WebViewJavascriptBridge

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 { // 註冊橋接 self.bridge = [SWHybridManager setJavaScriptBridgeWithWebView:self.webView controller:self]; } [WKWebViewJavascriptBridge enableLogging]; WKWebViewJavascriptBridge *bridge = [WKWebViewJavascriptBridge bridgeForWebView:webView]; [bridge setWebViewDelegate:controller]; 
  • 註冊方法供JavaScript調用
__weak typeof(controller)wController = controller; /****************************公共方法註冊-Start*********************/ //MARK:打開窗體 [bridge registerHandler:HandlerFunctionNameOpenWindow handler:^(id data, WVJBResponseCallback responseCallback) { __strong typeof(wController)sController = wController; NSLog(@"\n調用了openWindow: %@", data); NSDictionary *dict = (NSDictionary *)data; SWOpenWindowModel *model = [SWOpenWindowModel yy_modelWithDictionary:dict]; [self pushViewController:sController data:model responseCallback:responseCallback]; }]; 
  • 調用JavaScript方法
[self.bridge callHandler:callFunctionNameGetSearchKeyWord data:json]; 

3、方法名定義

  • 由於方法名的定義是字符串,因此建議採用常量字符串,防止拼寫錯誤
  • 其次不建議採用宏定義
  • 我採用如下方法
  • 橋接管理類的.h
/**打開窗體 */ FOUNDATION_EXPORT NSString *const HandlerFunctionNameOpenWindow; /** 關閉窗口*/ FOUNDATION_EXPORT NSString *const HandlerFunctionNameCloseWindow; 
  • 橋接管理類的.m
/**打開窗體 */ NSString *const HandlerFunctionNameOpenWindow = @"openWindow"; /** 關閉窗口*/ NSString *const HandlerFunctionNameCloseWindow = @"closeWindow"; 
  • 使用時直接使用常量字符串便可
  • 注意點:如相似我使用在基類傳入控制器和webview到管理類中,在類中使用controller要注意循環引用,不然會致使控制器沒法釋放
+ (WKWebViewJavascriptBridge *)setJavaScriptBridgeWithWebView:(WKWebView *)webView controller:(__kindof SWBaseWebViewController *)controller; __weak typeof(controller)wController = controller; // 弱引用傳入控制器 __strong typeof(wController)sController = wController; // 在block內部強引用 

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) { /* Initialize your app here */ bridge.registerHandler('JS Echo', function(data, responseCallback) { console.log("JS Echo called with:", data) responseCallback(data) }) bridge.callHandler('ObjC Echo', {'key':'value'}, function responseCallback(responseData) { console.log("JS received response:", responseData) }) }) 

6、注意事項

  • 若是產生調用不通的問題,多爲JavaScript調用時機問題
  • 注意橋接的代理
做者:Pnyg_回眸 連接:https://www.jianshu.com/p/58d6f2f4c5db 來源:簡書 簡書著做權歸做者全部,任何形式的轉載都請聯繫做者得到受權並註明出處。
相關文章
相關標籤/搜索