由于蘋果規(guī)定自2020年4月起 App Store 將不再接受使用 UIWebView 的新 app,2020年12月起將不再接受使用 UIWebView 的 app 更新,近期在著手將項目中使用 UIWebView 加載本地 HTML 替換成使用 WKWebview 加載。WKWebview 的基本使用筆者在這里就不過多贅述了,網(wǎng)上一搜一大把;在這里就記錄下筆者在替換使用 WKWebview 過程中踩過的坑(ps:并不全面,只是筆者替換過程中遇到的問題)。
1.WKWebview localstorage 存取信息不一致
例如項目中存在兩個使用 WKWebview 加載的頁面 A 和 B; 在 B 頁面使用 localstorage 保存信息,回到 A 頁面取不到在 B 頁面使用 localstorage 所保存的數(shù)據(jù)。
原因:
<a > 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發(fā)布會上發(fā)布 iOS8.0 中,apple 公布了 WebKit 框架,這意味著 OSX 和 iOS 開發(fā)者將共用同樣的開發(fā)庫,新改變可以提高開發(fā)者編寫的代碼的重復使用性。WebKit 框架使用 WKWebView 來代替 iOS 的 UIWebView 和 OSX 的WebView,并且使用Nitro JavaScript引擎,這意味著所有第三方瀏覽器運行 JavaScript 將會跟 safari 一樣快。
原因:
WebKit 對跨域進行了安全檢查限制,不允許跨域。
解決方法:
創(chuàng)建 WKWebView 的時候設(shè)置 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 及以上系統(tǒng)才支持,要兼容 iOS10.0 以下系統(tǒng)那就只能讓服務器兼容支持了,服務器請求 Headers 中配置 Access-Control-Allow-Origin: * ,當然這里也可以指定域。
3.WKWebView 加載自簽名證書的 https 鏈接
當加載的本地 HTML 發(fā)送 https 鏈接的請求時,如果使用的證書是自建證書(自簽名證書),鏈接是無法正常加載的,必須要做一個權(quán)限認證。
原因
在使用 UIWebView 的時候就需要把請求存儲下來然后使用 NSURLConnection 去重新發(fā)起請求,然后走 NSURLConnection 的權(quán)限認證通道忽略 https 的證書驗證,當然 WKWebView 更不能例外,不過 WKWebView 更便捷。
解決方法
實現(xiàn) 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 系統(tǒng)下,自建證書的 https 鏈接權(quán)限認證,不會調(diào)用此代理方法。查來查去,原來是一個 bug,在 iOS9.0 中已經(jīng)修復,這明顯就是不管 iOS8.0 的情況了,而且此方法也沒有標記在 iOS9.0 中使用,然后查找了下目前市場上的主流 app,一般都是最低支持 iOS9.0 甚至 iOS10.0,而筆者目前經(jīng)手的項目最低支持還是 iOS7.0 ,沒辦法了只能去跟項目經(jīng)理一頓扯皮之后改成最低支持 iOS9.0。
以上就是目前筆者使用 WKWebview 替換 UIWebview 所遇到的問題,后續(xù)遇到新的問題將會補充更新!