1、選擇
- 項目自己webview使用的是WKWebview,其實WKWebview自帶的messageHandle也能夠知足此需求
- JSContext,源自於JavaScriptCore框架中的東西,最後不使用此方案源於一下幾點
- 可是其中繁雜的字符串使用,讓我覺的可能會因爲粗心出現不可預知的錯誤
- 加載時機的問題,當你從新loadrequest的時候,會致使js注入失敗
- 回調方法略複雜
- JavaScriptBridge,最後選擇此庫源於如下幾點
- 使用簡單,註冊完畢以後設置完代理,只須要負責註冊方法和調用方法
- 回調簡單,兩端回調responsecallback包含在註冊的方法中。使用block
- 三端通用,JavaScript和iOS、Android均可以(Android版本庫)
- Ps :關於Android版本庫,其中不少是按照iOS版的JavaScriptBridge改寫的。可是其中有不少問題,尤爲是各類調用時機問題,上面的連接是通過我旁邊的Android小哥試了四五個版本以後發現的,修復了各類改寫版的問題
2、使用
- 首先須要引入WebViewJavascriptBridge庫
#import "WebViewJavascriptBridge.h"
- 初始化,此處爲了方便子類使用,因此在基類中註冊bridge,並return bridge對象,方便子類調用
#pragma mark - 橋接 - (void)InitializeWebViewJavascriptBridge {
__weak typeof(controller)wController = controller;
[self.bridge callHandler:callFunctionNameGetSearchKeyWord data:json];
3、方法名定義
- 由於方法名的定義是字符串,因此建議採用常量字符串,防止拼寫錯誤
- 其次不建議採用宏定義
- 我採用如下方法
- 橋接管理類的.h
- 使用時直接使用常量字符串便可
- 注意點:如相似我使用在基類傳入控制器和webview到管理類中,在類中使用controller要注意循環引用,不然會致使控制器沒法釋放
+ (WKWebViewJavascriptBridge *)setJavaScriptBridgeWithWebView:(WKWebView *)webView controller:(__kindof SWBaseWebViewController *)controller; __weak typeof(controller)wController = controller;
4、數據傳輸
- iOS端直接返回字典便可
- 我代碼中是返回json字符串,爲了與Android統一,方便H5解析數據
5、JavaScript代碼
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) }
setupWebViewJavascriptBridge(function(bridge) {
6、注意事項
- 若是產生調用不通的問題,多爲JavaScript調用時機問題
- 注意橋接的代理