javascript和安卓iOS之间约定的相互调用彼此接口的桥梁 参考
WebViewJavascriptBridge
原理
OC环境和Javascript环境各自保存一个相互调用的bridge对象,每一个调用之间都有id和callbackid来找到两个环境对应的处理。
核心类
WebViewJavascriptBridge_JS:Javascript环境的Bridge初始化和处理。负责接收OC发给Javascript的消息,并且把Javascript环境的消息发送给OC。
WKWebViewJavascriptBridge / WebViewJavascriptBridge : 主要负责OC环境的消息处理 并且吧OC 环境的消息发送给javascript环境
WebViewJavascriptBridgeBase:主要实现了OC环境的Bridge初始化和处理。
1.1 原生环境初始化
1.2 原生环境注册方法
1.3 javascript 初始化和注册方法
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
| function setWebViewJavascriptBridge(callback) { // 第一次调用这个方法的时候 为false if (window.WebViewJavascriptBridge) { return callback(WebJavascriptBridge) }
// 第一次调用的时候 为false if(window.WVJBCallback) { return window.WVJBCallback.push(callback) }
// 将callback赋值给对象 window.WVJBCallback = [callback]
// 创建iframe 追加在body之后 初始化之后 在将其移除
var WVJBIframe = document.createElement('iframe') WVJBIframe.style.display = none WVJBIframe.src = 'https://__bridge_loaded__' document.documentElement.appendChild(WVJBIframe); setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0) }
setupWebViewJavascriptBridge(function(bridge) { // 把WEB中注册的方法注册到bridge里面 bridge.registerHandler('testJavascriptHandler', function(data,responseCallback){
// OC 传递过来的数据 log('ocjC call testJavascript with', data);
// js返回数据 var responseData = {'Javascript Says':'Right back atcha'} responseCallback(responseData)
}) })
|
1.4
1.5 javascript发送消息给OC
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
| // testObjcHandler 类似于接口 {'foo' : 'bar'} 类似于数据 response 类似于响应消息 bridge.callHandler('testObjcHandler', {'foo': 'bar'}, function(response) { log('JS got response', response)--> })
//web端调用一个OC注册的消息 function callHandler(handlerName, data, responseCallback) { if (arguments.length == 2 && typeof data == 'function') { responseCallback = data; data = null; } _doSend({ handlerName: handlerName, data: data }, responseCallback); }
//JS调用OC方法,执行具体的发送操作 function _doSend(message, responseCallback) { if (responseCallback) { var callbackId = 'cb_'+(uniqueId++)+'_'+new Date().getTime(); //存储消息的回调ID responseCallbacks[callbackId] = responseCallback; //把消息对应的回调ID和消息一起发送,以供消息返回以后使用 message['callbackId'] = callbackId; } //把消息放入消息列表 sendMessageQueue.push(message); //下面这句话会发起JS对OC的调用,让webview执行跳转操作,从而可以在 //webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler //中拦截到JS发给OC的消息 messagingIframe.src = CUSTOM_PROTOCOL_SCHEME + '://' + QUEUE_HAS_MESSAGE; }
|
总结
- 分别在OC环境和Javascript环境都保存bridge对象, 在bridge对象中都保存的resquestID 和对应的callbackID函数 以及对应ID具体的实现方法
- OC通过Javascript环境的window.WebViewJavascriptBridge对象来调用JS方法
- javascript 通过改变iframe的Src来唤起web view的代理方法从而实现把javascript消息发送给OC的功能
// webstorm 注册码见注释