自iOS8 以后,苹果推出了新框架 WebKit,提供了替换 UIWebView 的组件 WKWebView。各种 UIWebView 的性能问题没有了,速度更快了,占用内存少了,体验更好了,下面列举一些其它的优势:
- 在性能、稳定性、功能方面有很大提升(加载速度,内存的提升谁用谁知道)
- 更多的支持 HTML5 的特性
- 官方宣称的高达60fps的滚动刷新率以及内置手势
- Safari 相同的 JavaScript 引擎
- 将 UIWebViewDelegate 与 UIWebView 拆分成了14类与3个协议,包含该更细节功能的实现。
在OC中添加监听的接口清单:以JS脚本的接口showMobile
为例:
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
WKUserContentController *userCC = config.userContentController;
//MARK:在OC中添加监听的接口清单:JS脚本的接口名
[userCC addScriptMessageHandler:self name:@"showMobile"];
- 设置代理类遵守
WKScriptMessageHandler
协议
@interface ViewController () <WKScriptMessageHandler>
- 注册对JS接口监听,注入代理类
[userCC addScriptMessageHandler:self name:@"showMobile"];
- 实现
WKUserContentController
代理的回调方法,响应JS接口事件
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
NSLog(@"%@",message.body);
}
js接口声明格式:
window.webkit.messageHandlers.接口名.postMessage('参数')
接口名: 在WKWebView中,当JS执行该接口时,OC会拦截预先监听的接口,并处理相关事件。
参数:object类型,多个参数时需要封装为集合类型来实现多参传递。
当OC拦截到该接口时,可以在WKScriptMessageHandler
回调方法中的WKScriptMessage
参数实例中获取该参数值: message.body
。
三个例子:
- JS无参调用OC
当无参调用OC时,参数必须为null
window.webkit.messageHandlers.showMobile.postMessage(null)
- JS传参调用OC
传递单个参数时,直接写入即可,例如:xiao黄
window.webkit.messageHandlers.showName.postMessage('xiao黄')
传递多个参数时,需要封装为集合类型实现多参传递。
例如:当传递一个电话,一条信息,需要封装为['13300001111','Go Climbing This Weekend !!!']
window.webkit.messageHandlers.showSendMsg.postMessage(['13300001111', 'Go Climbing This Weekend !!!'])
在网页加载完成之后调用JS代码才会执行,因为这个时候html页面已经注入到webView中并且可以响应到对应方法。
例如调用JS函数alertMobile()
:
[self.wkWebView evaluateJavaScript:@"alertMobile()" completionHandler:^(id _Nullable response, NSError * _Nullable error) {
//TODO
NSLog(@"%@ %@",response,error);
}];
- 当注入的类型字符串类型时,必须用
''
括起来。 - OC注入的参数为全局属性,在html中的JS脚本可以直接调用属性名来获取值。
通过NSString形式,编写JS脚本,通过以下两种方式注入网页
方式一:在初始化WKWebView
时,通过配置WKWebViewConfiguration>userContentController
注入JS脚本 。
//MARK:向网页中注入JS脚本例如,参数/函数等
WKUserScript *script = [[WKUserScript alloc] initWithSource:@"var number=0;"
injectionTime:WKUserScriptInjectionTimeAtDocumentStart
forMainFrameOnly:YES];
WKUserContentController *userCC = config.userContentController;
[userCC addUserScript:script];
方式二:使用WKWebView实例方法evaluateJavaScript
动态注入JS脚本
[self.wkWebView evaluateJavaScript:@"var number=0;" completionHandler:nil];
使用WKWebView实例方法evaluateJavaScript
动态调用JS函数
[self.wkWebView evaluateJavaScript:@"alertSendMsg('18870707070','下午好!')" completionHandler:nil];