WKWebView使用遇到的坑

作者: Jay神 | 来源:发表于2016-01-19 11:06 被阅读48297次

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 拥有两个参数,一个是返回错误,一个可以返回执行脚本后的返回值

相关文章

网友评论

  • IT播客:设置 navigationDelegate 会黑屏 咋回事啊?
  • 有理想有暴富的小青年:[self.wkwebView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:urlStr]]];
    用这个加载本地的html试试
  • Beyond无状态:博主 我wkwebview访问网络HTML地址 就第一次能加载出来 重跑一遍项目就不行了 换个HTML地址 也是这样 咋回事啊
  • 宇玄丶:楼主,你那个fielHeper是什么啊?
  • 5a8c365da0b7:请问WKWebView苹果审核时说ipv6网络不能加载,有没有人遇到过?
  • 069eea124da3:博主,请问self.fileHelper指的是什么?
  • 2bb5ebfd832c:博主我想问下,如果是ios8系统中使用wkwebview,为什么接收不到WKScriptMessageHandler回调中的-(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message 而在ios9之后的系统就可以正常的接收到
  • ce70df11c8e3:朋友,我在iOS10.2系统上可以使用[webView loadRequest:[NSURLRequest requestWithURL:fileURL]];
    你说的 WKWebView是不允许通过loadRequest的方法来加载本地根目录的HTML文件这个有问题?
    麻烦你再验证一下
  • 潘烨:我这个wKwebView 跟js 交互,轻点一下不触发js的方法,在模拟器上必须摁下去才能触发,真机上也是,怎么能轻点一下就能触发,是不是有什么属性,获取js 设置啊,JSContext *content 这个轻点是可以的,求大神帮忙啊。
  • 748281001c95:怎么更改wkWebview页面字体大小,还有无图模式呢?
  • 小伙eryayayayaya:楼主:可以问你一个问题么,我有这么一个需求:有一个界面使用H5做的,这个h5界面有一个倒计时,当倒计时时间还有10秒的时候,就让他有提示声音。控制这个声音开关是要用原声的switch来控制。这种要怎么做?
  • f48ab9e63152:请问我是用远程下载html页面 然后用loadhtmlstring()的方式加在的html页面, 也碰到楼主的问题, 请问如何解决? js, css都是远程路径.
  • 太空蛙:大神们, wkwebview出现白屏怎么破?
  • 9a996ce6ed8d:关于wkWebview和js交互的问题, evaluateJavaScript:comletionHandler 这个方法中,返回结果一个是NSError类型的error,另一个id类型的结果为什么是一个Boolean属性,是这个方法只能返回这两个类型的结果吗
  • ZhongXi:- (nullable WKNavigation *)loadFileURL:(NSURL *)URL allowingReadAccessToURL:(NSURL *)readAccessURL API_AVAILABLE(macosx(10.11), ios(9.0));
    可以加载本地HTML文件
  • 1b05ef2b4848:请教下楼主 咱们用wkwebview的这个代理方法 接受前端的调用
    “- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message”
    比如说前端想跟客户端获取用户信息的话 客户端接收到信息之后 该怎么返回相应的信息呢?
    之前uiwebview 我们可以直接retuan相应的信息
  • 米米露:博主你好,我用了您的方法,把文件拷贝到tmp目录下可以加载出来,但是tmp目录下的文件会被清除。然后就拷贝到document目录下,但是document目录下却打不开。请问您有什么解决办法吗?
    德坤柳:@哈尔_e451 你后来是怎么解决的啊
    Jay神:document没权限 简单界面用wk 复杂的还是回到webview比较合适
    98377d3f22ce:你好,请问你是怎么解决的?Tmp目录文件会被清空,放到这里显然不好
  • 始于__初见:使用WKWebview 控制台输出
    Could not signal service com.apple.WebKit.WebContent: 113: Could not find specified service
    Could not signal service com.apple.WebKit.Networking: 113: Could not find specified service
    有遇到么
    始于__初见:@Mossion 没有呢 ,正常使用没有问题
    Mossion:@始于__初见 请问你解决这个问题没有
    我不是掌柜:@始于__初见 +1,不知道什么情况
  • vicky_菲:我想问一下WKWebView加载的页面字体过大,如何调整?
    vicky_菲:@Jay神 谢谢 :+1:
    vicky_菲:设置了preferences.minimumFontSize = 30.0;注释掉就好了
    Jay神:字体问题 跟wk没关系 得看你加载的界面内容
  • 皮乐皮儿:楼主,我遇到了这样的问题:前天一切还是正常的,昨天开始测试的时候忽然发现WKWebView加载网页出现了问题,在模拟器上一切正常,在真机上就不能加载了,系统是iOS10.1.1的,换成uiwebview没什么问题,这个是什么原因呢?
    皮乐皮儿:@sculg 看下是不是html文件中调用css的路径不对,html和js,css文件最好放到同一个路径下 <link type="text/css" rel="stylesheet" href="css名称"> 我的这个里面是这样处理的。我遇到的问题不是你这样的,是由于webview高度获取,本来是js返回的,但是需要获取两次,第一次获取到后不会高度显示不完全,需要过一两秒重新获取一次才可以,这个问题目前用的笨方法,隔一秒再获取一次
    sculg:@顾语流年 你好,你的这个问题解决了吗?我也出现了这个问题,加载本地文件,模拟器上一切正常,真机上只能显示html文件,css样式无法显示出来。
  • FLNuo:还有 你最后这个completionHandler 方法 我的怎么 没有 势必自定义的???
  • FLNuo:WKWebView 加载html的时候 不走html中调用的js!是怎么回事啊?
    41219c59cd08:我的也是加载不了js,css,请问您是怎么解决的?
    FLNuo:@Jay神 对的 自己写的 js代码
    Jay神:加载本地js吗
  • GiantAxe77:WKWebView的哪个方法和UIWebView的shouldStartLoadWithRequest:方法一样啊?
    6ea8c6a1d65d:@GiantAxe decidePolicyForNavigationAction
  • 飞天遁地:我用wkwebView加载本地html,显示不全是什么问题?
  • z_hy:使用WKWebview在js中使用了zepto.js 的 load()方法,然后就报了一个跨域失败的错误 xmlhttprequest cannot load file cross origin requests are only,请问有什么解决办法么?
  • 6e8179322f95:如何在wkwebview加载完成后,获取网页的真实高度?
  • 7d4bb5d59ee5:我用wkwebview加载本地html文件loadrequest(loadHTML也试过,一样),之后要隔0.3-0.5秒左右才调用didFinishNavigation,求问是什么问题
    82295265a0fd:@Jay神 把html文件已经复制到tmp下了,还报Could not create a sandbox extension for '/'警告,但是会到加载完成的代理,然后发送向js发送evaluateJavaScript这个方法,报error错误, Error Domain=WKErrorDomain Code=4 "发生 JavaScript 异常" UserInfo=0x155a36c0 {NSLocalizedDescription=发生 JavaScript 异常},只有ios8下会这样,ios9以上没事
    7d4bb5d59ee5:@Jay神 应该不大啊,html文件才100多行,还有一些js,css,jquery文件
    Jay神:@Pandexxxxxxxxxx 本地的HTML很大吗?
  • 29b31617c222:博主,请问您一下,为什么我是用模态跳转的方式跳到wkWebView加载内容,因为系统有默认的返回方式,就好像UIModalPresentationCurrentContext这种方式,我点击WkWebView的上面就可以返回上层页面,但是这一返回就崩了,这种情况不知道你有没遇到过,但使用UIWebView是没有任何问题的
    82295265a0fd:@Jay神 把html文件已经复制到tmp下了,还报Could not create a sandbox extension for '/'警告,但是会到加载完成的代理,然后发送向js发送evaluateJavaScript这个方法,报error错误, Error Domain=WKErrorDomain Code=4 "发生 JavaScript 异常" UserInfo=0x155a36c0 {NSLocalizedDescription=发生 JavaScript 异常}
    29b31617c222:@Jay神 不像是其他地方引起的
    Jay神:@ISO_iOS_OSI 这个没遇到,但如何返回不应该回崩!有其他的业务在跑而引起的吗?
  • fc18f69e6ff0:之前webview拨打电话是可以实现的,现在换成wkwebview之后拨打电话怎么实现
    年轻人的心情_爱我所爱:@闭上眼睛 我也想问这个问题,楼上解决了吗
  • 4a8aeec7b5f2::fearful:求解一个坑,情景:wkwebview 加载服务器一个h5页面,h5页面里面有ajax请求 问题:这个页面经常会加载不出来,偶尔又可以加载出来,链接拷贝到浏览器可以加载出来
    29b31617c222:楼主,请问您一下,为什么我是用模态跳转的方式跳到wkWebView加载内容,因为系统有默认的返回方式,就好像UIModalPresentationCurrentContext这种方式,我点击WkWebView的上面就可以返回上层页面,但是这一返回就崩了,这种情况不知道你有没遇到过,但使用UIWebView是没有任何问题的
    Jay神:Ajax返回结果后有什么操作
  • 24110bb18262:博主,请问在执行JS的时候报错 Error Domain=WKErrorDomain Code=4 "A JavaScript exception occurred" UserInfo={NSLocalizedDescription=A JavaScript exception occurred} 怎么解决呢
    _skye:想咨询下 这个问问题目前解决了没有?
    AgoniNemo:你是不是在userContentController方法里,用evaluateJavaScript方法执行js?
  • Sky521:WKWebView通过loadHTMLString这个方法加载html字符串,改变字体大小,博主有方法吗
    卧龙小:@Sky521 解决了没?才用@天地不仁以万物为刍狗 的方案吗?
    798a37d82543:@Sky521
    if (self.note) {
    NSString *path = [[NSBundle mainBundle] bundlePath];
    NSURL *baseURL = [NSURL fileURLWithPath:path];
    NSString *css = @"<meta name='viewport' content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no'> <link rel='stylesheet' type='text/css' href='amazeui.min.css' > <link rel='stylesheet' type='text/css' href='app.css' >";
    NSString *subStr = [css stringByAppendingString:self.note];
    [webView loadHTMLString:subStr baseURL:baseURL];
    }
    self.note 是你需要加载的html字符串
    引入amazeui.min.css(自己下载)就差不多了,我这还引入了一个app.css,还是样式上的调整:body{padding:15px
    }//内边距
    img{
    width:100%
    }//图片适应屏幕
    Jay神:这个需求有多奇葩?这样做的目的是什么?我想如果要通过这种方式实现字体大小不合适
  • 0de50e9952cd:同样问题 但是我有个更简单方法诶
    [self loadHtml:@"File"];
    -(void)loadHtml:(NSString*)name{
    NSString *filePath = [[NSBundle mainBundle]pathForResource:name ofType:@"html"];
    NSString * str = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
    [self.webView loadHTMLString:str baseURL:nil];
    }
    zyg:@东方_未明 指定 baseURL 就行呀
    例如:[self.webView loadHTMLString:html baseURL:[NSBundle mainBundle].resourceURL];
    东方_未明:@贵妃醉酒 试了试你的方法, 果然加载不到js和css
    Jay神:@贵妃醉酒 HTML里面引用的其它文件怎么办?例如js或者image
  • 0141904cfe54:thanks for sharing
  • b01c913b01b1:我想知道如何监听网页跳转到的url地址?
    Jay神:@光影色 看WKNavigationDelegate
  • midmirror:感谢博主分享,帮了大忙了。。
  • 问问问你:那么如果都是一个个文件夹的内容,改如何copy到temp目录下呢?
    440bd488f596:@Jay神 :flushed: 请问楼主什么事hybird的框架
    Jay神:如果这样要批量的 你在APP启动时就要导入了 还有你有这么大量的页面的话 为何还用wk,应该选择hybird的框架去设计APP了
  • 9522b3aef89f:iOS8 wkwebview 加载远程html不显示图片,只显示内容,这是什么原因呢,求帮忙
    大爷你的伞:真的是这样啊,加载本地的HTML图片也显示不了,图片不是本地的
    Jay神:@良年追影 这个应该不会这样,加载本地图片,如果图片不在tmp路径才可能无法显示呢。
  • WenJim::action:

本文标题:WKWebView使用遇到的坑

本文链接:https://www.haomeiwen.com/subject/btukkttx.html