小知识,大挑战!本文正在参与“程序员必备小知识”创作活动
本文同时参与「掘力星计划」,赢取创作大礼包,挑战创作激励金
通过问题看本质!!!
WebViewJavascriptBridge
通过代码,我们可以发现,其实WebViewJavascriptBridge是通过url拦截的方式去通信,封装了一套自己的代码。让调用和解析更加具有面向对象特征。源码
//html代码
//把消息从JS发送到客户端
function _doSend(message, responseCallback) {
if (responseCallback) {
var callbackId = 'cb_' + (uniqueId++) + '_' + new Date().getTime();
responseCallbacks[callbackId] = responseCallback;
message['callbackId'] = callbackId;
}
sendMessageQueue.push(message);
//JS对OC的调用
messagingIframe.src = CUSTOM_PROTOCOL_SCHEME + '://' + QUEUE_HAS_MESSAGE;
}
//客户端代码
//让webview执行跳转操作,在👇方法中拦截到JS发给客户端的消息
-(void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
graph TD
客户端注册handler--> JS执行src代码 --> webview接收数据
--> webview执行JS函数代码获取数据
--> webview处理业务逻辑回调数据到html
- 客户端注册handler:vc初始化时,注册handler,这个handler是提供给JS调用的
- JS执行src代码:JS执行代码前,会先把要处理到数据保存到map中
- webview接收数据:
-(void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler - 原生wkwebview通过该方法拦截到url后,处理业务。
- webview执行JS函数代码获取数据:根据不同URL类型,执行对应的JS函数,获取在map预先存储的数据。
- webview处理业务逻辑回调数据到html:根据消息对象的回调id和数据,通过注册的handler回调给前端,前端通过回调id,查找对应的方法,执行代码。
WKScriptMessageHandler
WKWebView是Apple在iOS8推出的Webkit框架中的负责网页的渲染与展示的类,相比UIWebView速度更快,占用内存更少,支持更多的HTML特性。 WKScriptMessageHandler是WebKit提供的一种在WKWebView上进行JS消息控制的协议。
使用
- JS与iOS客户端约定好
TCXJSbridge协议名称; - JS通过window.webkit.messageHandlers.TCXJSbridge.postMessage()的方式发送消息;
- iOS客户端在
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message方法中读取name为TCXJSbridge的消息数据message.body,通过body解析对应的业务数据。 - wkwebview中addScriptMessageHandler会引起循环引用问题,要注意释放
//添加handler
[self.webView.configuration.userContentController addScriptMessageHandler:self name:@"TCXJSbridge"];
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
if ([message.name isEqualToString:@"TCXJSbridge"]) {
//解析数据,执行相应的代码
}
}
//JS代码
window.webkit.messageHandlers.TCXJSbridge.postMessage();
总结
| 标题 | UIWebView | WKWebView | 是否是第三方库 | UIWebView |
|---|---|---|---|---|
| url拦截 | 支持 | 支持 | 否 | 短时间内连续执行多次,只能拦截到最后一次。 |
| JavaScriptCore(iOS7+) | 支持 | 不支持 | 是 | UIWebView退出历史舞台 |
| WebViewJavascriptBridge | 支持 | 支持 | 是 | 1、开发维护成本大;2、需要H5端配合改动;3、 不兼容安卓 |
| WKScriptMessageHandler(iOS8+) | 不支持 | 支持 | 是 | 1、系统自带;2、学习成本低;3、易用易维护 |
- 综上所述,我们在开发中使用WKScriptMessageHandler方案最合适。
- 因为目前几乎所有APP支持的版本都是在iOS8以上的。
- 而且WebKit引入了javascript引擎,WKWebView初始化的时候,添加脚本信息处理器WKScriptMessageHandler,让一个对象具有脚本信息处理能力,只要我们遵循协议方法,就能上手开发了。
- 高效、易用、维护成本低。