自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];