# WebViewJavascriptBridge
把 OC 的方法注册到桥梁中,让 JS 去调用。 把 JS 的方法注册在桥梁中,让 OC 去调用。
# WebViewJavaScriptBridge 使用的基本步骤
1.首先在项目中导入 WebViewJavaScriptBridge 框架。
pod ‘WebViewJavascriptBridge’
2.导入头文件 #import <WebViewJavascriptBridge.h>。 3.建立 WebViewJavaScriptBridge 和 WebView 之间的关系。
_jsBridge = [WebViewJavascriptBridge bridgeForWebView:_webView];
4.在 HTML 文件中,复制粘贴这两段 JS 函数。
function setupWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) {
return callback(WebViewJavascriptBridge);
}
if (window.WVJBCallbacks) {
return window.WVJBCallbacks.push(callback);
}
window.WVJBCallbacks = [callback]; // 创建一个 WVJBCallbacks 全局属性数组,并将 callback 插入到数组中。
var WVJBIframe = document.createElement("iframe"); // 创建一个 iframe 元素
WVJBIframe.style.display = "none"; // 不显示
WVJBIframe.src = "wvjbscheme://__BRIDGE_LOADED__"; // 设置 iframe 的 src 属性
document.documentElement.appendChild(WVJBIframe); // 把 iframe 添加到当前文导航上。
setTimeout(function() {
document.documentElement.removeChild(WVJBIframe);
}, 0);
}
// 这里主要是注册 OC 将要调用的 JS 方法。
setupWebViewJavascriptBridge(function(bridge) {});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
到此为止,基本的准备工作就做完了。现在需要往桥梁中注入 OC 方法 和 JS 函数了。
# 往桥梁中注入 OC 方法 和 JS 函数
往桥梁中注入 OC 方法。
[_jsBridge registerHandler:@"scanClick" handler:^(id data, WVJBResponseCallback responseCallback) {
NSLog(@"dataFrom JS : %@",data[@"data"]);
responseCallback(@"扫描结果 : www.baidu.com");
}];
2
3
4
5
6
这段代码的意思: 1.scanClick 是 OC block 的一个别名。 2.block 本身,是 JS 通过某种方式调用到 scanClick 的时候,执行的代码块。 3.data ,由于 OC 这端由 JS 调用,所以 data 是 JS 端传递过来的数据。 4.responseCallback OC 端的 block 执行完毕之后,往 JS 端传递的数据。
往桥梁中注入 JS 函数.
OC 方法,在 OC 中注入。JS 的方法所以必然就需要在 JS 中注入的。(好像是废话) 在 JS 的方法如何注入到桥梁呢?
之前,在准备工作的时候,有两段 JS 代码。 需要在第二段 JS 代码中,注入 JS 的函数。
// 这里主要是注册 OC 将要调用的 JS 方法。
setupWebViewJavascriptBridge(function(bridge) {
// 声明 OC 需要调用的 JS 方法。
bridge.registerHanlder("testJavaScriptFunction", function(
data,
responseCallback,
) {
// data 是 OC 传递过来的数据.
// responseCallback 是 JS 调用完毕之后传递给 OC 的数据
alert("JS 被 OC 调用了.");
responseCallback({ data: "js 的数据", from: "JS" });
});
});
2
3
4
5
6
7
8
9
10
11
12
13
这段代码的意思: 1.testJavaScriptFunction 是注入到桥梁中 JS 函数的别名。以供 OC 端调用。 2.回调函数的 data。 既然 JS 函数由 OC 调用,所以 data 是 OC 端传递过来的数据。 3.responseCallback 。 JS 调用在被 OC 调用完毕之后,向 OC 端传递的数据。
基本就是: OC 端注册 OC 的方法,OC 端调用 JS 的函数。 JS 端注册 JS 的函数,JS 端调用 OC 的方法。
# WebViewJavascriptBridge 实现原理
从setupWebViewJavascriptBridge函数来看感觉 WebViewJavascriptBridge 是通过 URL Scheme 的方式来实现的。
但是在 JSBridge 中我们提到,这种方式是有意缺点的。
TIP
🤔 那么 WebViewJavascriptBridge 是怎么实现的呢?
# 通信流程

# 代码实现方式

# 总结
- 分别在 OC 环境和 javascript 环境都保存一个 bridge 对象,里面维持着 requestId,callbackId,以及每个 id 对应的具体实现。
- OC 通过 javascript 环境的 window.WebViewJavascriptBridge 对象来找到具体的方法,然后执行。
- javascript 通过改变 iframe 的 src 来出发 webview 的代理方法 webView:(WKWebView _)webView decidePolicyForNavigationAction:(WKNavigationAction _)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler 从而实现把 javascript 消息发送给 OC 这个功能。
TIP
简单来说 URL Scheme 拦截有参数长度限制的缺点,代码注入有不安全的缺点 WebViewJavascriptBridge 两者结合 通过 URL Scheme 拦截获取到一个 id,然后去 h5 的全局对象上 根据 id 拿到实际的参数,之后根据参数处理好业务之后,再执行和 id 相关的一个回调函数,把结果传给这个函数
