我们公司目前进行的项目开发大多是Hybrid开发,也就是app里嵌入H5页面,所以Native端和H5端在有时候需要进行交互。比如H5界面有录制视频的需求,需要调起原生的摄像头功能,这在H5端肯定是无法实现的。因为H5实质上只是一个嵌入的webView,所需的api需要原生端进行提供。
这时候,我们就需要JSBridge
作为Native端和H5端进行交互的工具,这个项目采用的是WebViewJavascriptBridge,具体API和介绍在这个官方文档里都有,不做详细说明了。
阅读了JSBridge
之后,我们还需要一份由Native原生端提供的接口文档,上面详细的说明了我们应当调用他们的方法、回调参数以及需要我们提供给他们调用的方法。
接口文档示例如下图所示:
下面来说说可能遇到的坑:
- 原生端接口文档不准确。事实上和与后端对接是一样的,接口文档不正确带来的问题就是无法交互成功,而且对于与原生端交互,最大的问题在于前端无法在本地调试,出了问题只有找原生端,解决问题效率非常低。本次项目我安装了
vconsole
,但是不知道为什么在原生端打开时无效,推测可能是原生端对于webView做了什么限制。这次项目,花费时间最多的就是接口文档这一块儿了,所以下次开发前一定要确认接口文档是否准确。 -
registerHandler
需要声明回调的参数,不然等于未注册这个方法。
bridge.registerHandler('svideoCallBackStatus', function(data) {
callback(data);
});
3.registerHandler
方法也就是Native调用H5的js,需要提前调用。我在项目里处理是在页面的created
生命周期里调用的。确保和原生端交互的时候已经注册。
4.项目中出现比如两次进入同一页面,调起JSBridge的时候,registerHandler
方法会调用两次的问题。牛邦的林宇大神修改了初始化JSBridge的代码,加了对于回调函数的判重操作。避免了直接入队,导致反复调用的问题。修改后的代码如下:
/**
* 原生端js桥
*/
export function setupWebViewJavascriptBridge(callback) {
// 回调是否存在了
let callbackExisted = false;
if ((<any>window).WebViewJavascriptBridge) {
return callback((<any>window).WebViewJavascriptBridge);
}
if ((<any>window).WVJBCallbacks) {
(<any>window).WVJBCallbacks.forEach(cb => {
if (JSON.stringify(cb) == JSON.stringify(callback)) {
callbackExisted = true;
}
});
if (!callbackExisted) {
return (<any>window).WVJBCallbacks.push(callback);
}
return;
}
(<any>window).WVJBCallbacks = [callback];
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);
}