美文网首页
iOS 使用 WKWebview 替换 UIWebview 踩过

iOS 使用 WKWebview 替换 UIWebview 踩过

作者: JX_Chanho | 来源:发表于2020-05-07 13:42 被阅读0次

    由于苹果规定自2020年4月起 App Store 将不再接受使用 UIWebView 的新 app,2020年12月起将不再接受使用 UIWebView 的 app 更新,近期在着手将项目中使用 UIWebView 加载本地 HTML 替换成使用 WKWebview 加载。WKWebview 的基本使用笔者在这里就不过多赘述了,网上一搜一大把;在这里就记录下笔者在替换使用 WKWebview 过程中踩过的坑(ps:并不全面,只是笔者替换过程中遇到的问题)。

    1.WKWebview localstorage 存取信息不一致

    例如项目中存在两个使用 WKWebview 加载的页面 A 和 B; 在 B 页面使用 localstorage 保存信息,回到 A 页面取不到在 B 页面使用 localstorage 所保存的数据。

    原因:

    <a href="https://developer.apple.com/reference/webkit/wkwebviewconfiguration"> wkwebviewconfiguration </a> 中有个属性 processPool,描述是:The process pool from which to obtain the view’s Web Content process.

    解决方法:

    将 config 中的 processPool 使用单例

    
    WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
    
    //使用单例解决 locastorge 储存问题
    
    config.processPool = [YT_WKProcessPool shareInstance];
    
    

    2.WKWebview 跨域问题

    在 WWDC 2014发布会上发布 iOS8.0 中,apple 公布了 WebKit 框架,这意味着 OSX 和 iOS 开发者将共用同样的开发库,新改变可以提高开发者编写的代码的重复使用性。WebKit 框架使用 WKWebView 来代替 iOS 的 UIWebView 和 OSX 的WebView,并且使用Nitro JavaScript引擎,这意味着所有第三方浏览器运行 JavaScript 将会跟 safari 一样快。

    原因:

    WebKit 对跨域进行了安全检查限制,不允许跨域。

    解决方法:

    创建 WKWebView 的时候设置 WKWebViewConfiguration 的属性 _allowUniversalAccessFromFileURLs

    WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
    [config.preferences setValue:@YES forKey:@"allowFileAccessFromFileURLs"];
    if (@available(iOS 10.0, *)) {
        [config setValue:@YES forKey:@"allowUniversalAccessFromFileURLs"];
     }
    

    但是 allowUniversalAccessFromFileURLs 属性只有 iOS10.0 及以上系统才支持,要兼容 iOS10.0 以下系统那就只能让服务器兼容支持了,服务器请求 Headers 中配置 Access-Control-Allow-Origin: * ,当然这里也可以指定域。

    3.WKWebView 加载自签名证书的 https 链接

    当加载的本地 HTML 发送 https 链接的请求时,如果使用的证书是自建证书(自签名证书),链接是无法正常加载的,必须要做一个权限认证。

    原因

    在使用 UIWebView 的时候就需要把请求存储下来然后使用 NSURLConnection 去重新发起请求,然后走 NSURLConnection 的权限认证通道忽略 https 的证书验证,当然 WKWebView 更不能例外,不过 WKWebView 更便捷。

    解决方法

    实现 WKWebView 的代理方法 (- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler)

    - (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler {
        if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
            NSURLCredential *card = [[NSURLCredential alloc] initWithTrust:challenge.protectionSpace.serverTrust];
            completionHandler(NSURLSessionAuthChallengeUseCredential,card);
        }
    }
    

    但是在 iOS8.0 系统下,自建证书的 https 链接权限认证,不会调用此代理方法。查来查去,原来是一个 bug,在 iOS9.0 中已经修复,这明显就是不管 iOS8.0 的情况了,而且此方法也没有标记在 iOS9.0 中使用,然后查找了下目前市场上的主流 app,一般都是最低支持 iOS9.0 甚至 iOS10.0,而笔者目前经手的项目最低支持还是 iOS7.0 ,没办法了只能去跟项目经理一顿扯皮之后改成最低支持 iOS9.0。

    以上就是目前笔者使用 WKWebview 替换 UIWebview 所遇到的问题,后续遇到新的问题将会补充更新!

    相关文章

      网友评论

          本文标题:iOS 使用 WKWebview 替换 UIWebview 踩过

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