OC和JS交互的三種方法


  看簡書上說一共有六種OC和JS交互的方法,但是前三種原理都一致,都是通過檢測、攔截Url地址實現互相調用的。剩下的react native等第三方框架原理不一樣,也沒有去研究,下邊記錄我使用的三種方法(原理都是攔截Url地址)。

  (一)、使用系統自帶JavaScriptCore庫進行交互,支持iOS7以后系統。(備注:我這個項目在交互MBProgress的時候控制隱藏,js代碼會發生奔潰,安卓是好的,原因始終找不到)

oc調用js方法

[homeWebView stringByEvaluatingJavaScriptFromString:jsFunction];

-------------------------------------------------------------------

js調用oc方法導入

  1、JavaScriptCore庫

  #import <JavaScriptCore/JavaScriptCore.h>

  2、獲得上下文

- (void)webViewDidFinishLoad:(UIWebView *)webView{

    //降低webview帶來的內存泄露

    [[NSUserDefaultsstandardUserDefaults] setInteger:0forKey:@"WebKitCacheModelPreferenceKey"];

    //----------------------JS回掉方法----------------------------------------

  JSContext *context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];

//沒有返回值的寫法

    context[@"showProgressDialogPhone"] = ^() { // 顯示

        [self showProgressDialog];

    };

  // 有返回值的寫法,

  context[@"getTabInfoIOS"] = [self getTabInfoIOS];//獲得權限

}

3、js端綁定方法oc方法,綁定的這個方法名稱必須要和oc里注冊的方法名稱保持一致

   function showProgressDialog(){

      showProgressDialogPhone();

    }

(二)、實現了JSExport協議的協議,這樣調用到vc里的方法

1、聲明協議,實現協議方法

在.h文件中聲明

@protocol TestJSObjectProtocol <JSExport>

-(void)closeProgressDialog;

@end

.m文件中實現協議方法

@interface ViewController ()<TestJSObjectProtocol>

@end

1、同上先獲得上下文,oc這里綁定方法、實現closeProgressDialog方法

        ViewController *viewCtlOBJ = [ViewController new];

        context[@"viewCtlOBJ"] = viewCtlOBJ;

        NSString *jsStr1=[NSString stringWithFormat:@"viewCtlOBJ.closeProgressDialog()"];

        [context evaluateScript:jsStr1];

2、js這邊調用oc方法

function closeProgressDialog(){

 viewCtlOBJ.closeProgressDialog();

}

(三)、使用WebViewJavascriptBridge進行oc和js的交互

備注:兼容iOS7以下版本,我最終使用的這個方法,解決掉js代碼崩潰的問題。這個類庫是異步執行的,優點:調用oc和js代碼優雅,傳值和回調方便

 

1、先導入WebViewJavascriptBridge包,可參考上一篇文章導入。

  #import "WebViewJavascriptBridge.h"

  @propertyWebViewJavascriptBridge* bridge;

  2、OC原生注冊方法,實現方法

   [WebViewJavascriptBridgeenableLogging];

    _bridge = [WebViewJavascriptBridgebridgeForWebView:homeWebView];

    [_bridgesetWebViewDelegate:self];

    /***

     /js調用oc

     /@param registerHandler 要注冊的事件名稱(這里我們為showProgressDialogPhone)

     /@param handel 回調block函數 當后台觸發這個事件的時候會執行block里面的代碼

     ***/

    [_bridgeregisterHandler:@"showProgressDialogPhone"handler:^(id data, WVJBResponseCallback responseCallback) {

        NSLog(@"顯示加載");

        [self showProgressDialog];

        responseCallback(@"Response 顯示加載");

    }];

  3、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)

}

    setupWebViewJavascriptBridge(function(bridge) {

                                 bridge.callHandler('showProgressDialogPhone', function(response) {

                                                  alert(response);

                                                    })

                                 });

 

 -----------------------------------------------------------------------------------------

   //oc調用js代碼

     bridge.registerHandler('testJavascriptHandler', function(data, responseCallback) {

   log('ObjC called testJavascriptHandler with', data)

       var responseData = { 'Javascript Says':'Right back atcha!' }

                                                  responseCallback(responseData)

                                                  })

    //需要傳參數,不需要從后台返回執行結果

    /***

     @param callHandler 商定的事件名稱,用來調用網頁里面相應的事件實現

     @param data id類型,相當於我們函數中的參數,向網頁傳遞函數執行需要的參數

     ***/

//    [_bridge callHandler:@"testJavascriptHandler" data:@{ @"foo":@"before ready" }];

--------------------------------------------------------------------------------------

 

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM