在iOS8.0, 蘋(píng)果推出了WebKit框架, 但時(shí)至今日, 仍然有很多公司需要支持iOS8以下的系統(tǒng), 所以可能還沒(méi)有將
UIWebView
完全更換成WKWebView
,WKWebView
的性能上的表現(xiàn)確實(shí)比UIWebView
好很多, 但是坑也很多, 要用WKWebView
就要接受它的坑.
前面的一些列文章著重講述了UIWebView和JS的交互, 下面是參考鏈接
OC和JS交互(UIWebView)入門(mén)篇
OC和JS交互(UIWebView)中級(jí)篇1
OC和JS交互(UIWebView)中級(jí)篇2
OC和JS交互(UIWebView)中級(jí)篇3
WKWebView和UIWebView一樣, 在和JS交互的時(shí)候也可以通過(guò)JS注入的方式, 而且在WebViewJavaScriptBridge框架中也提供了對(duì)WKWebView
的支持. 這里只對(duì)和UIWebView
不同的地方進(jìn)行說(shuō)明.
- (void)webView:(WKWebView *)webView
decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction
decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
if (webView != _webView) { return; }
NSURL *url = navigationAction.request.URL;
__strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate;
if ([_base isCorrectProcotocolScheme:url]) {
if ([_base isBridgeLoadedURL:url]) {
[_base injectJavascriptFile];
} else if ([_base isQueueMessageURL:url]) {
[self WKFlushMessageQueue];
} else {
[_base logUnkownMessage:url];
}
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:decidePolicyForNavigationAction:decisionHandler:)]) {
[_webViewDelegate webView:webView decidePolicyForNavigationAction:navigationAction decisionHandler:decisionHandler];
} else {
decisionHandler(WKNavigationActionPolicyAllow);
}
}
上面的代碼是WKWebView
的代理方法, 當(dāng)改變網(wǎng)頁(yè)的src
屬性, 就會(huì)觸發(fā)這個(gè)代理被調(diào)用, 和UIWebView
的- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
類(lèi)似, 這里需要注意一點(diǎn), 要確保- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
代理一定調(diào)用到decisionHandler
否則會(huì)崩潰, 而且不能重復(fù)調(diào)用, 這里原著應(yīng)該是有個(gè)bug的.
if ([_base isCorrectProcotocolScheme:url]) {
if ([_base isBridgeLoadedURL:url]) {
[_base injectJavascriptFile];
} else if ([_base isQueueMessageURL:url]) {
[self WKFlushMessageQueue];
} else {
[_base logUnkownMessage:url];
}
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
上面的if分支一定要return, 否則會(huì)崩潰
'NSInternalInconsistencyException', reason: 'Completion handler passed to -[WKWebViewJavascriptBridge webView:decidePolicyForNavigationAction:decisionHandler:] was called more than once'
信息已經(jīng)說(shuō)的很明白了, 多次調(diào)用decisionHandler
.
這里對(duì)于OC和JS交互(UIWebView)中級(jí)篇3
中最后遺留的3個(gè)問(wèn)題的第二個(gè)實(shí)際已經(jīng)有了答案, 對(duì)于WKWebView
依然可以進(jìn)行攔截. 至于其它2個(gè)問(wèn)題, 我們將會(huì)在后面的文章陸續(xù)給出答案.