【注意】最后更新于 July 7, 2017,文中内容可能已过时,请谨慎使用。
WebKit简介
{% github it-boyer WKWebView-JS d03bc0e width = 30% %}
自iOS8 以后,苹果推出了新框架 WebKit,提供了替换 UIWebView 的组件 WKWebView。各种 UIWebView 的性能问题没有了,速度更快了,占用内存少了,体验更好了,下面列举一些其它的优势:
1、在性能、稳定性、功能方面有很大提升(加载速度,内存的提升谁用谁知道)
2、更多的支持 HTML5 的特性
3、官方宣称的高达60fps的滚动刷新率以及内置手势
4、Safari 相同的 JavaScript 引擎
5、将 UIWebViewDelegate 与 UIWebView 拆分成了14类与3个协议,包含该更细节功能的实现。
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
| title WKWebView和JS脚本
center header
了解传参原理和交互机制
endheader
'******* 类声明模块 *******'
'类型:class,abstract,interface,annotation,enum'
'访问域:(-)私有,(#)保护,(~)包私有,(+)公有'
'&&&&&& 类组合模块 类模块 &&&&&&&'
'六种组合样式:Node,Rectangle,Folder,Frame,Cloud,Database'
package "iOS原生API"<<Folder>>{
class WK<WKWebView>{
__ 方法组 __
+ (id)initWithFrame:configuration:
+ (void)evaluateJavaScript:completionHandler:
}
class config<WKWebViewConfiguration>{
-- 属性组 --
+ WKUserContentController *userContentController
__方法组__
+(id)init
}
class userCC<WKUserContentController>{
__方法组__
+(void)addScriptMessageHandler:name:
+(void)addUserScript:
}
class delegate<WKScriptMessageHandler>{
--代理方法--
+(void)userContentController:didReceiveScriptMessage:
}
class script<WKUserScript>{
--构造器--
+ (id)initWithSource:injectionTime:forMainFrameOnly:;
}
}
package JS脚本 <<Folder>> #red{
class js脚本{
--配置组--
messageHandlers:js接口名
postMessage参数
}
}
'###### 类备注模块 类声明末尾使用:note 位置: 备注#########'
note top of WK
浏览器主体
end note
note right of config #gray
用于在构造WK时,预加载js脚本,设置监听JS接口清单
end note
note bottom of userCC:1.提供预加载JS脚本操作\n2.在OC中添加监听的接口清单:JS脚本的接口名\n3.注入代理类
note top of js脚本: 调用原生\n window.webkit.messageHandlers.js接口名.postMessage(参数)\n 参数为id类型,当无参调用时,参数设置为null
note right of delegate:代理方法:拦截监听JS接口,获取JS传递的参数值\n在回调中获取该参数值:message.body
'>>>>>> 类关系图及连接备注模块 >>>>>>>>'
'关系节点符:(|>)继承,(*)合成 ,(o)聚合, 其他#,x,},+,^ 连线符:(--)实线 ,(..)虚线'
WK"1" *-[#red]- "1" config:构造参数 <
note right on link #white
构造WK时,配置webView的预设条件
end note
config *-[#green]- userCC:核心组件 <
script o-left[#red]- js脚本:浏览器预加载JS脚本 <
WK o-left[#red]- js脚本:浏览器调用JS脚本 <
userCC *-[#blue] delegate:处理监听到的JS脚本 <
delegate <|.left[#black]. WK: 代理类 <
userCC o-left[#gray]- script:注入脚本 <
center footer
boyer模型
endfooter
|
添加监听代理和JS接口
在OC中添加监听的接口清单:以JS脚本的接口showMobile
为例:
1
2
3
4
| WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
WKUserContentController *userCC = config.userContentController;
//MARK:在OC中添加监听的接口清单:JS脚本的接口名
[userCC addScriptMessageHandler:self name:@"showMobile"];
|
设置WKUserContentController的代理
- 设置代理类遵守
WKScriptMessageHandler
协议
1
| @interface ViewController () <WKScriptMessageHandler>
|
- 注册对JS接口监听,注入代理类
1
| [userCC addScriptMessageHandler:self name:@"showMobile"];
|
- 实现
WKUserContentController
代理的回调方法,响应JS接口事件
1
2
3
| - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
NSLog(@"%@",message.body);
}
|
JS脚本接口
js接口声明格式:
1
| window.webkit.messageHandlers.接口名.postMessage('参数')
|
接口名: 在WKWebView中,当JS执行该接口时,OC会拦截预先监听的接口,并处理相关事件。
参数:object类型,多个参数时需要封装为集合类型来实现多参传递。
当OC拦截到该接口时,可以在WKScriptMessageHandler
回调方法中的WKScriptMessage
参数实例中获取该参数值: message.body
。
三个例子:
- JS无参调用OC
当无参调用OC时,参数必须为null
1
| window.webkit.messageHandlers.showMobile.postMessage(null)
|
- JS传参调用OC
传递单个参数时,直接写入即可,例如:xiao黄
1
| window.webkit.messageHandlers.showName.postMessage('xiao黄')
|
传递多个参数时,需要封装为集合类型实现多参传递。
例如:当传递一个电话,一条信息,需要封装为['13300001111','Go Climbing This Weekend !!!']
1
| window.webkit.messageHandlers.showSendMsg.postMessage(['13300001111', 'Go Climbing This Weekend !!!'])
|
iOS原生API调用JS脚本
在网页加载完成之后调用JS代码才会执行,因为这个时候html页面已经注入到webView中并且可以响应到对应方法。
例如调用JS函数alertMobile()
:
1
2
3
4
| [self.wkWebView evaluateJavaScript:@"alertMobile()" completionHandler:^(id _Nullable response, NSError * _Nullable error) {
//TODO
NSLog(@"%@ %@",response,error);
}];
|
在OC中为JS定义属性/函数
- 当注入的类型字符串类型时,必须用
''
括起来。
- OC注入的参数为全局属性,在html中的JS脚本可以直接调用属性名来获取值。
通过NSString形式,编写JS脚本,通过以下两种方式注入网页
方式一:在初始化WKWebView
时,通过配置WKWebViewConfiguration>userContentController
注入JS脚本 。
1
2
3
4
5
6
| //MARK:向网页中注入JS脚本例如,参数/函数等
WKUserScript *script = [[WKUserScript alloc] initWithSource:@"var number=0;"
injectionTime:WKUserScriptInjectionTimeAtDocumentStart
forMainFrameOnly:YES];
WKUserContentController *userCC = config.userContentController;
[userCC addUserScript:script];
|
方式二:使用WKWebView实例方法evaluateJavaScript
动态注入JS脚本
1
| [self.wkWebView evaluateJavaScript:@"var number=0;" completionHandler:nil];
|
iOS原生API调用JS函数
使用WKWebView实例方法evaluateJavaScript
动态调用JS函数
1
| [self.wkWebView evaluateJavaScript:@"alertSendMsg('18870707070','下午好!')" completionHandler:nil];
|