iOS和html交互-WKWebView

本文最后更新于:2 年前

html5的标准确立后,随着手机性能的提升和对h5标准的推广支持,原生开发容器,h5开发内容的方式成为了新的开发方式,这种混合开发带来了更高的开发效率,更高的代码复用率,更好的体验方式。而自iOS 2就开始使用的UIWebView也逐渐显示出不足,例如加载速度慢、内存消耗多等问题。

iOS 8之后,苹果推出了新的web框架WebKit,新框架中的WKWebView可以用来替换UIWebView,苹果对WKWebView进行了很大的优化,全面提升了对web页面的支持。

首先我们看下WKWebView的属性,WKWebView中提供了一个WKWebViewConfiguration的属性,该属性有许多设置,可以达到不同的效果,除此还提供了两个代理WKNavigationDelegateWKUIDelegate,分别对应不同的代理,感兴趣的可以自己查阅下官方文档。

web调用原生的方法

在使用WKWebViewweb页面进行交互时,我们最常使用到的应该就是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
//iOS代码
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
//创建wkwebview
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>

通过userContentControlleraddScriptMessageHandler方法,将当前controller以名称GHWebViewJavascriptBridge绑定到WKWebView中,在userContentController通过addScriptMessageHandler方法绑定的类中实现userContentController:didReceiveScriptMessage:的方法,通过此方法可以和web页面进行通信,当然如果需要传参的话,htmlpostMessage里面的字符串可以按照约定好的格式进行拼接参数

原生调用web的方法

1
2
3
4
5
//iOS代码
NSString *jsStr = [NSString stringWithFormat:@"getCodeString('%@')", @"二维码"];
[self.webView evaluateJavaScript:jsStr completionHandler:^(id _Nullable result, NSError * _Nullable error) {

}];
1
2
3
4
5
//js代码
window.getCodeString = function(codeStr) {
alert('二维码字符串' + codeStr);
}

WKWebView提供了和UIWebView类似的方法evaluateJavaScript:completionHandler:的方法,通过此方法直接调用web页面中的window层的方法,此方法还能有回调,通过回调我们能够判断js方法有没有调用成功