在html5
的标准确立后,随着手机性能的提升和对h5
标准的推广支持,原生开发容器,h5
开发内容的方式成为了新的开发方式,这种混合开发带来了更高的开发效率,更高的代码复用率,更好的体验方式。而自iOS 2
就开始使用的UIWebView
也逐渐显示出不足,例如加载速度慢、内存消耗多等问题。
在iOS 8
之后,苹果推出了新的web
框架WebKit
,新框架中的WKWebView
可以用来替换UIWebView
,苹果对WKWebView
进行了很大的优化,全面提升了对web
页面的支持。
首先我们看下WKWebView
的属性,WKWebView
中提供了一个WKWebViewConfiguration
的属性,该属性有许多设置,可以达到不同的效果,除此还提供了两个代理WKNavigationDelegate
和WKUIDelegate
,分别对应不同的代理,感兴趣的可以自己查阅下官方文档。
web
调用原生的方法
在使用WKWebView
与web
页面进行交互时,我们最常使用到的应该就是WKWebViewConfiguration
中的userContentController
属性,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| - (void)viewDidLoad { [super viewDidLoad]; WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init]; configuration.userContentController = [[WKUserContentController alloc] init]; [configuration.userContentController addScriptMessageHandler:self name:@"GHWebViewJavascriptBridge"]; WKWebView *webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height) configuration:configuration]; webView.backgroundColor = [UIColor whiteColor]; [self.view addSubview:webView]; _webView = webView; NSString *urlStr = @"http://xxxxxxxxxxxxx"; urlStr = [urlStr stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlStr]]; [webView loadRequest:request]; }
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message { if ([message.name isEqualToString:@"GHWebViewJavascriptBridge"]) { NSString *body = message.body; if (body && [body isEqualToString:@"closePage"]) { [self.navigationController popToRootViewControllerAnimated:YES]; } } }
- (void)dealloc { [self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"GHWebViewJavascriptBridge"]; [self.webView.configuration.userContentController removeAllUserScripts]; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| //html页面 <!DOCTYPE html> <html>
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no"> <title></title> </head>
<body> <div> <button type="button" class="mui-btn" onclick="closePage()">点击关闭页面</button> </div> <script> function closePage() { window.webkit.messageHandlers.GHWebViewJavascriptBridge.postMessage('closePage'); } </script> </body> </html>
|
通过userContentController
的addScriptMessageHandler
方法,将当前controller
以名称GHWebViewJavascriptBridge
绑定到WKWebView
中,在userContentController
通过addScriptMessageHandler
方法绑定的类中实现userContentController:didReceiveScriptMessage:
的方法,通过此方法可以和web
页面进行通信,当然如果需要传参的话,html
中postMessage
里面的字符串可以按照约定好的格式进行拼接参数
原生调用web
的方法
1 2 3 4 5
| NSString *jsStr = [NSString stringWithFormat:@"getCodeString('%@')", @"二维码"]; [self.webView evaluateJavaScript:jsStr completionHandler:^(id _Nullable result, NSError * _Nullable error) { }];
|
1 2 3 4 5
| window.getCodeString = function(codeStr) { alert('二维码字符串' + codeStr); }
|
WKWebView
提供了和UIWebView
类似的方法evaluateJavaScript:completionHandler:
的方法,通过此方法直接调用web
页面中的window
层的方法,此方法还能有回调,通过回调我们能够判断js
方法有没有调用成功