Webview和H5页面的交互方式(二)

1,533 阅读3分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动

本文同时参与「掘力星计划」,赢取创作大礼包,挑战创作激励金

通过问题看本质!!!

前文回顾

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

  1. 客户端注册handler:vc初始化时,注册handler,这个handler是提供给JS调用的
  2. JS执行src代码:JS执行代码前,会先把要处理到数据保存到map中
  3. webview接收数据:-(void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
  4. 原生wkwebview通过该方法拦截到url后,处理业务。
  5. webview执行JS函数代码获取数据:根据不同URL类型,执行对应的JS函数,获取在map预先存储的数据。
  6. 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();

总结

标题UIWebViewWKWebView是否是第三方库UIWebView
url拦截支持支持短时间内连续执行多次,只能拦截到最后一次。
JavaScriptCore(iOS7+)支持不支持UIWebView退出历史舞台
WebViewJavascriptBridge支持支持1、开发维护成本大;2、需要H5端配合改动;3、 不兼容安卓
WKScriptMessageHandler(iOS8+)不支持支持1、系统自带;2、学习成本低;3、易用易维护
  • 综上所述,我们在开发中使用WKScriptMessageHandler方案最合适。
  • 因为目前几乎所有APP支持的版本都是在iOS8以上的。
  • 而且WebKit引入了javascript引擎,WKWebView初始化的时候,添加脚本信息处理器WKScriptMessageHandler,让一个对象具有脚本信息处理能力,只要我们遵循协议方法,就能上手开发了。
  • 高效、易用、维护成本低。