H5嵌入APP后,原生APP与H5之间交互

原生APP跳转到H5页面时,往往需要携带一些用户信息,之前做法是在跳转的地址中拼接H5页面需要的参数,现在通过window.WebViewJavascriptBridge悄悄的进行数据交互。

本文主要从H5的角度记录交互思路:

1:安卓环境和ios环境稍微有点不同,需要根据navigator.userAgent判断一下当前环境

2:仍然是APP环境不同,安卓需要进行兼容性判断,如果不存在window.WebViewJavascriptBridge变量,需要手动添加Dom的WebViewJavascriptBridgeReady事件监听;ios同样需要判断是否存在window.WebViewJavascriptBridge变量,如果不存在继续判断window.WVJBCallbacks变量,如果仍然不存在,则手动赋值为H5回调,然后document.createElement('iframe')插入document中,随即移除。

3:以上处理完成后,通过WebViewJavascriptBridge变量来注册【事件】以便APP能监听到并执行相应操作

4:3中需要对安卓系统进行init处理,如果是安卓系统,注册事件之前需要先调用WebViewJavascriptBridge.init()

方法(注意: 一个页面整个生命周期过程中,只能进行一次init()否则会报错,我的做法是通过一个全局变量来判断是否初始化过)

以下是具体代码:

//针对安卓和ios系统,对window.WebViewJavascriptBridge进行兼容性处理
function setupWebViewJavascriptBridge(callback) {
	var u = navigator.userAgent;
	var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android终端
	var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
	if (isAndroid) {
		if (window.WebViewJavascriptBridge) {
			callback(WebViewJavascriptBridge)
		} else {
            //添加dom事件
			document.addEventListener(
				'WebViewJavascriptBridgeReady',
				function () {
					callback(WebViewJavascriptBridge)
				},
				false
			);
		}
			
	}
	if (isiOS) {
		console.log('isiOS')
		if (window.WebViewJavascriptBridge) {
			return callback(WebViewJavascriptBridge);
		}
		if (window.WVJBCallbacks) {
			return window.WVJBCallbacks.push(callback);
		}
		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)
	}
}
//封装方法,key:跟原生定义好的要捕获的名称, callback:原生捕获后执行的回调,此处可以写H5的后续执行方法,params:对象,要传给原生的参数
var setupWebViewBridge = function (key, callback, params) {
	setupWebViewJavascriptBridge(function (bridge) {
		var u = navigator.userAgent;
		var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android终端
		var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
        //自己定义的全局变量,用来判断当前页面中安卓系统是否进行过一次初始化,页面卸载时取消赋值
		if (!window.hadCalledWindow_WebViewJavascriptBridge ) {
			if (isAndroid) {
				window.hadCalledWindow_WebViewJavascriptBridge = true 
				bridge.init(function (message, responseCallback) {
					console.log('JS got a message', message);
					var data = {
						'Javascript Responds': '测试中文!'
					};
 
					if (responseCallback) {
						console.log('JS responding with', data);
						responseCallback(data);
					}
				});
			}
		}
		bridge.callHandler(
			key,
            //安卓系统必须传一个参数,否则捕获不到,因此,默认传入一个_x_变量 
			JSON.stringify({
				...params,
				_x_: 1,
			}),
			callback
		);
 
	})
}

原生APP里,注册要捕获的方法:

bridge.registerHandler('jsbridge_showMessage', function (data, responseCallback) {
             showResponse(data);
         });

转载来源于 https://blog.csdn.net/haoyanyu_/article/details/89237819

移动端混合开发,需要原生与h5交互。
目前接触过的两种方法:

  1. 大多数是直接通过webview代理,理解的是通过拦截调用与原生进行交互。任意版本都支持。
  2. 使用第三方库WebViewJavaScriptBridge。
    这里主要整理下WebViewJavaScriptBridge在前端部分的使用:
    【用于 WKWebView & UIWebView 中 OC 和 JS 交互(ios)】

注册监听事件(固定代码):

/*这段代码是固定的,必须要放到js中*/
function setupWebViewJavascriptBridge(callback) {
	if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); }
	if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); }
	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)

js与原生方法调用部分

//添加原生调起js方法
setupWebViewJavascriptBridge(function(bridge) {
     /* Initialize your app here */
     //所有与iOS交互的JS代码放这里!

    //js注册方法让原生调起(原生调用js)
    
    //name: 和原生约定的调用方法名
    //function(data,callback):调用方法的具体内容,data为原生传过来的参数,callback为js给原生的回调函数             
    bridge.registerHandler("jsFunction",function(data,responseCallback){
        alert("do sth with"+data)
        responseCallback("js calls back to oc");
    });
    
    
    //js唤起原生注册的方法(js调用原生)
    
    //name: 和原生约定的调用方法名
    //data: 向原生传递的参数
    //function: 原生调用后的回调函数(回调结果处理)
    bridge.callHandler('ocFunction',data,function(res){
         alert("js has received the result:"+res);
    });
}

备注:

posted @ 2020-10-17 13:10  打个大大西瓜  阅读(4913)  评论(0编辑  收藏  举报