WKWebView使用遇到的坑--加载本地html及JS交互
1. ios9以前版本读取本地HTML的问题
当使用loadRequest来读取本地的HTML时,WKWebView是无法读取成功的,后台会出现如下的提示:
Could not create a sandbox extension for /
原因是WKWebView是不允许通过loadRequest的方法来加载本地根目录的HTML文件。
而在iOS9的SDK中加入了以下方法来加载本地的HTML文件:[WKWebView loadFileURL:allowingReadAccessToURL:]
但是在iOS9以下的版本是没提供这个便利的方法的。以下为解决方案的思路,就是在iOS9以下版本时,先将本地HTML文件的数据copy到tmp目录中,然后再使用loadRequest来加载。但是如果在HTML中加入了其他资源文件,例如js,css,image等必须一同copy到temp中。这个是最蛋疼的事情了。
解决方法如下
1.Objective-C:
//将文件copy到tmp目录
- (NSURL *)fileURLForBuggyWKWebView8:(NSURL *)fileURL {
NSError *error = nil;
if (!fileURL.fileURL || ![fileURL checkResourceIsReachableAndReturnError:&error]) {
return nil;
}
// Create "/temp/www" directory
NSFileManager *fileManager= [NSFileManager defaultManager];
NSURL *temDirURL = [[NSURL fileURLWithPath:NSTemporaryDirectory()] URLByAppendingPathComponent:@"www"];
[fileManager createDirectoryAtURL:temDirURL withIntermediateDirectories:YES attributes:nil error:&error];
NSURL *dstURL = [temDirURL URLByAppendingPathComponent:fileURL.lastPathComponent];
// Now copy given file to the temp directory
[fileManager removeItemAtURL:dstURL error:&error];
[fileManager copyItemAtURL:fileURL toURL:dstURL error:&error];
// Files in "/temp/www" load flawlesly :)
return dstURL;
}
//调用逻辑
NSString *path = [[NSBundle mainBundle] pathForResource:@"indexoff" ofType:@"html"];
if(path){
if ([[UIDevice currentDevice].systemVersion floatValue] >= 9.0) {
// iOS9. One year later things are OK.
NSURL *fileURL = [NSURL fileURLWithPath:path];
[self.webView loadFileURL:fileURL allowingReadAccessToURL:fileURL];
} else {
// iOS8. Things can be workaround-ed
// Brave people can do just this
// fileURL = try! pathForBuggyWKWebView8(fileURL)
// webView.loadRequest(NSURLRequest(URL: fileURL))
NSURL *fileURL = [self.fileHelper fileURLForBuggyWKWebView8:[NSURL fileURLWithPath:path]];
NSURLRequest *request = [NSURLRequest requestWithURL:fileURL];
[self.webView loadRequest:request];
}
}
2.Swift
//将文件copy到tmp目录
func fileURLForBuggyWKWebView8(fileURL: NSURL) throws -> NSURL {
// Some safety checks
var error:NSError? = nil;
if (!fileURL.fileURL || !fileURL.checkResourceIsReachableAndReturnError(&error)) {
throw error ?? NSError(
domain: "BuggyWKWebViewDomain",
code: 1001,
userInfo: [NSLocalizedDescriptionKey: NSLocalizedString("URL must be a file URL.", comment:"")])
}
// Create "/temp/www" directory
let fm = NSFileManager.defaultManager()
let tmpDirURL = NSURL.fileURLWithPath(NSTemporaryDirectory()).URLByAppendingPathComponent("www")
try! fm.createDirectoryAtURL(tmpDirURL, withIntermediateDirectories: true, attributes: nil)
// Now copy given file to the temp directory
let dstURL = tmpDirURL.URLByAppendingPathComponent(fileURL.lastPathComponent!)
let _ = try? fileMgr.removeItemAtURL(dstURL)
try! fm.copyItemAtURL(fileURL, toURL: dstURL)
// Files in "/temp/www" load flawlesly :)
return dstURL
}
//方法调用
var filePath = NSBundle.mainBundle().pathForResource("file", ofType: "pdf")
if #available(iOS 9.0, *) {
// iOS9. One year later things are OK.
webView.loadFileURL(fileURL, allowingReadAccessToURL: fileURL)
} else {
// iOS8. Things can be workaround-ed
// Brave people can do just this
// fileURL = try! pathForBuggyWKWebView8(fileURL)
// webView.loadRequest(NSURLRequest(URL: fileURL))
do {
fileURL = try fileURLForBuggyWKWebView8(fileURL)
webView.loadRequest(NSURLRequest(URL: fileURL))
} catch let error as NSError {
print("Error: " + error.debugDescription)
}
}
2. WKWebView - WKNavigationDelegate使用
特别提醒一点,在使用以下delegate的方法时
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler需执行decisionHandler的block。
例如:
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
NSURLRequest *request = navigationAction.request;
WMPageActionType actionType = ActionTypeNone;
WKNavigationActionPolicy actionPolicy = WKNavigationActionPolicyAllow;
if([request.URL.absoluteString hasPrefix:OC_CLOSE_REQUEST]){
actionType = ActionTypeClose;
actionPolicy = WKNavigationActionPolicyCancel;
}
if(self.actionDelegate && [self.actionDelegate respondsToSelector:@selector(webView:action:type:)]) {
[self.actionDelegate webView:webView action:navigationAction type:actionType];
}
//这句是必须加上的,不然会异常
decisionHandler(actionPolicy);
}
3.WKWebView-JS执行方法
WKWebView JS执行方法与UIWebView不一样了。
- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^)(id, NSError *))completionHandler;completionHandler 拥有两个参数,一个是返回错误,一个可以返回执行脚本后的返回值
WKWebView使用遇到的坑--加载本地html及JS交互的更多相关文章
- #iOS问题记录#动态Html加载本地CSS和JS文件
所谓动态Html,指代码中组合生成的html字符串: 若需要加载本地CSS,图片,JS文件,则, 1,需要文件的全路径: 2,需要"file:///"标志: 例如: //获取文件全 ...
- WebView加载本地html、js文件常见问题及解决办法
声明:基于android studio平台,php语言搭建服务器 目录: 一.JavaScript脚本语言没有反应 二.alert无法弹出 三.html页面之间不能跳转 四.屏幕缩放没有达到预期效果 ...
- 填补Resources和WWW加载本地资源的坑
总的来说Resources和WWW加载本地资源坑比较多,大多与路径有关. 下面代码构成了一个路径的预读模块: 此模块主要解决的坑是:Resources或WWW加载本地的文件夹中的多个文件时,无法获取文 ...
- WKWebView 加载本地HTML显示不出网页问题,这点你注意了吗?-------完美显示
1.首先,WKWebView的引入和创建,我这里就不做阐述,我要说的,就是解决别人不能给您解决的问题 2.WKWebView 加载本地HTML,也就是两三句代码 是吧?作为读者的您肯定也知道,也实现 ...
- swift 加载 本地html 和 网络路径
先上代码: xcode 9.4 ios 11.4 import UIKit import WebKit class RootViewController: UIViewController, WKN ...
- 重新想象 Windows 8.1 Store Apps (81) - 控件增强: WebView 之加载本地 html, 智能替换 html 中的 url 引用, 通过 Share Contract 分享 WebView 中的内容, 为 WebView 截图
[源码下载] 重新想象 Windows 8.1 Store Apps (81) - 控件增强: WebView 之加载本地 html, 智能替换 html 中的 url 引用, 通过 Share Co ...
- iOS --- UIWebView的加载本地数据的三种方式
UIWebView是IOS内置的浏览器,可以浏览网页,打开文档 html/htm pdf docx txt等格式的文件. safari浏览器就是通过UIWebView做的. 服务器将MIM ...
- UIWebView加载本地html文件
UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(, , KScreenWidth, KScreenHeight-)]; ...
- viewpage listview gridview加载本地大图多图OOM处理办法
很少上博客园写东西了. 最近在写公司项目,由于需要加载本地相册通过viewpager方式来加载, 最后发现直接进入界面就OOM了. 经过几天的整理最终搞定. 现在将加载本地和加载网络图片的缓存工具类贴 ...
随机推荐
- 50行Python代码实现视频中物体颜色识别和跟踪
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 机器学习与统计学 PS:如有需要Python学习资料的小伙伴可以加 ...
- SpringCloud(七):springcloud-config统一管理配置中心
前言: Spring Cloud Config组件是独立的,不需要注册到eureka.config工作原理是把读取目标到配置拉取到本地缓存一份然后供给其他客户端使用,所以一旦config启动成功,可以 ...
- Dojo.declare使用方法详解
ArcGIS API for JavaScript是基于dojo开发的一套API,在实际生产中,我们需要再根据自己的需求实现自定义的功能,最后抽象成接口给前端调用. 我们使用dojo的declare来 ...
- Hacking/Penetrating tester bookmark collection
Blogs http://carnal0wnage.blogspot.com/ http://www.mcgrewsecurity.com/ http://www.gnucitizen.org/blo ...
- iOS关于制作动画运动轨迹(UIBezierPath介绍)
参考链接: https://www.jianshu.com/p/6c9aa9c5dd68
- MySQL基础之数据管理【5】
子查询的使用 select 字段名称 from tbl_name where col_name=(select col_name from tbl_name); --内层语句查询的结果可以作为外层语句 ...
- Python完全平方数
python解题源代码如下: import math """ 简述:一个整数,它加上100和加上268后都是一个完全平方数 提问:请问该数是多少? Python解题思路分 ...
- WPF-自定义控件引用外部样式+转换器
引用单个外部样式 <UserControl.Resources> <ResourceDictionary Source="pack://application:,,,/XM ...
- linux 命令之touch
转自:http://www.maomao365.com/?p=2037 一.touch命令简介touch的命令功能说明: 1 可以通过touch新建一个文件; 2 可以修改文件的时间戳; 3 可以批量 ...
- s3c2440裸机-时钟编程(一、2440时钟体系介绍)
1.总线框架 下图是2440的总线框架,其中有AHB(Advanced High performance Bus)高速总线,APB(Advanced Peripheral Bus)外围总线. 不同总线 ...