OC和JS交互(WKWebView)入门篇
在iOS8.0, 苹果推出了WebKit框架, 但时至今日, 仍然有很多公司需要支持iOS8以下的系统, 所以可能还没有将
UIWebView
完全更换成WKWebView
,WKWebView
的性能上的表现确实比UIWebView
好很多, 但是坑也很多, 要用WKWebView
就要接受它的坑.
前面的一些列文章着重讲述了UIWebView和JS的交互, 下面是参考链接
OC和JS交互(UIWebView)入门篇
OC和JS交互(UIWebView)中级篇1
OC和JS交互(UIWebView)中级篇2
OC和JS交互(UIWebView)中级篇3
WKWebView和UIWebView一样, 在和JS交互的时候也可以通过JS注入的方式, 而且在WebViewJavaScriptBridge框架中也提供了对WKWebView
的支持. 这里只对和UIWebView
不同的地方进行说明.
- (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
的代理方法, 当改变网页的src
属性, 就会触发这个代理被调用, 和UIWebView
的- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
类似, 这里需要注意一点, 要确保- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
代理一定调用到decisionHandler
否则会崩溃, 而且不能重复调用, 这里原著应该是有个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, 否则会崩溃
'NSInternalInconsistencyException', reason: 'Completion handler passed to -[WKWebViewJavascriptBridge webView:decidePolicyForNavigationAction:decisionHandler:] was called more than once'
信息已经说的很明白了, 多次调用decisionHandler
.
这里对于OC和JS交互(UIWebView)中级篇3
中最后遗留的3个问题的第二个实际已经有了答案, 对于WKWebView
依然可以进行拦截. 至于其它2个问题, 我们将会在后面的文章陆续给出答案.