原生和H5 的交互方式
在 原生开发 Hybrid App 的时候,前端和原生通信,需要jsBridge进行交互,在此总结下和原生一些交互的方式
需要说明App内嵌的H5都是基于原生WebView来实现的,为h5展示提供了容器
JS && OC
ios的WebView有两种,分别 是UIWebView 、WKWebView
- UIWebView 比较老,但是银行页面必须使用这个
- WKWebView 轻量级的新
UIWebView原生的交互原理
- 通过一个 JSContext 获取 UIWebView 的 JS 执行上下文,然后通过这个上下文,进行 OC & JS 的双端交互。
- 使用WebViewJavascriptBridge插件与JS交互
- 拦截http 请求截取参数进行交互(OC无法主动触发JS)
WebViewJavascriptBridge(IOS)原理与使用
原理
初始化时,创建一个iframe标签,src为https://__bridge_loaded__,OC截取这个url后,删除本地iframe并给html再次生成一个iframe,src是OC赋予的,并以这个url进行交互
使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| // 初始化函数 function setupWebViewJavascriptBridge(callback) { if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); } if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); } window.WVJBCallbacks = [callback]; const WVJBIframe = document.createElement('iframe'); WVJBIframe.style.display = 'none'; WVJBIframe.src = 'https://__bridge_loaded__'; document.documentElement.appendChild(WVJBIframe); setTimeout(() => { document.documentElement.removeChild(WVJBIframe); }, 0); } // 触发函数 setupWebViewJavascriptBridge(() => { });
// 使用方法 window.WebViewJavascriptBridge.callHandler( 'userInfo', // 方法名 { param: '中文测试' }, // 参数 (responseData) => { // 回调 alert(responseData); }, );
|
WKWebView原生的交互原理
通过 userContentController 把需要观察的 JS 执行函数注册起来。
然后通过一个协议方法,将所有注册过的 JS 函数执行的参数传递到此协议方法中。
JS To OC
这个方式是最通用方式
1 2 3 4
| window.webkit.messageHandlers.userInfo.postMessage({name : "李四",age : 22});
userInfo // 方法名 {name : "李四",age : 22} // 参数
|
OC To JS
1 2
| // js 在window下注册一个回调 // OC 触发 window下的这个回调 来进行交互
|
JS && Android
Android 4.0-4.4 没有jsBridge,可以使用url拦截传参
!!! 安卓传参只能接收字符串 需要进行转换
通信方式有两种:原生交互和插件WebViewJavascriptBridge
原生交互
1 2 3
| window.AndroidWebView.userInfo({name : "李四",age : 22}); userInfo // 方法名 {name : "李四",age : 22} // 参数
|
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 37
| // 初始化函数 function connectWebViewJavascriptBridge(callback) { if (window.WebViewJavascriptBridge) { callback(WebViewJavascriptBridge); } else { document.addEventListener( 'WebViewJavascriptBridgeReady', () => { callback(WebViewJavascriptBridge); }, false, ); } } // 触发 connectWebViewJavascriptBridge((bridge) => { bridge.init((message, responseCallback) => { console.log('JS got a message', message); const data = { 'Javascript Responds': '测试中文!', }; if (responseCallback) { console.log('JS responding with', data); responseCallback(data); } }); }); // 使用方法 window.WebViewJavascriptBridge.callHandler( 'userInfo', // 方法名 { param: '中文测试' }, // 参数 (responseData) => { // 回调 alert(responseData); }, );
|