美文网首页
Objective-C 与 Javascript 交互之 Web

Objective-C 与 Javascript 交互之 Web

作者: 4f080ccfcf32 | 来源:发表于2017-08-09 19:00 被阅读7次

    大多数的 App 都会有嵌入网页的做法,因此可能就会遇到原生与网页里的交互的场景。交互无非就两种情况,要么是 Objective-C (以下简称 objc ) 调用 Javascript (以下简称 js) 的方法,要么 js 调用原生的方法。

    考虑到效率和拓展维护,在开发过程中我选择了一个被开发者广泛使用的一个优秀的开源库 WebViewJavascriptBridge 。使用起来也比较简单,但是需要前端工程师的配合,在 js 里添加代码。


    iOS 端:

    1、初始化

    self.webViewBridge = [WebViewJavascriptBridge bridgeForWebView:self.webView];
        [self.webViewBridge setWebViewDelegate:self];
        
    

    这里需要注意的是,初始化方法要写到 UIWebView 的初始化之后。

    2、js 调用 objc

    既然 js 需要调用我们,我们要提前准备好方法。下面在我们的代码中先注册一个方法供 js 调用。

    [self.webViewBridge registerHandler:@"shareClick" handler:^(id data, WVJBResponseCallback responseCallback) {
        // Do Share
        responseCallback();//可选 :分享完成后,可以选择通知 js 端。
    }];
    

    这里的 “shareClick” 可以认为是一个 key, js 通过这个 key 回调我们的方法。

    你可以对每个方法设置一个不同的 key ,在每个方法的回调里单独执行某个行为。比如上面的是分享,你可以再次注册一个 “openPhotoLibraryClick”

    [self.webViewBridge registerHandler:@"openPhotoLibraryClick" handler:^(id data, WVJBResponseCallback responseCallback) {
        // Open You PhotoLibraryClick
        responseCallback();//可选 :分享完成后,可以通知 js 端。
    }];
    

    当然你也可以只注册一个方法,通过 js 传过来的 data 来区分不同的方法。比如:

    [self.webViewBridge registerHandler:@"jsBridgeCall" handler:^(id data, WVJBResponseCallback responseCallback) {
         if ([data isKindOfClass:[NSDictionary class]]) {
                NSDictionary *dataDict = (NSDictionary *)data;
                if([dataDict[@"type"] isEqualToString:SHARE_TYPE]){
                    // Do Share
                }else if([dataDict[@"type"] isEqualToString:SHARE_OPEN_PHTOTLIBRARY]){
                    // Open You PhotoLibraryClick
                }
        }
        responseCallback();//可选 :分享完成后,可以通知 js 端。
    }];
    

    具体方案,要综合项目需求考虑,和前端工程师协商好就行。

    3、objc 调用js

    我们调用 js ,那 js 中自然也已经注册了一个方法供我们调用,我们同样只需要知道该方法的 key 即可,这里你可以根据具体情况选择是否需要传值,是需要 js的通知 回调:

    //无值 无回调
     [self.webViewBridge callHandler:@"finishedShare"];
    
    //无回调
     [self.webViewBridge callHandler:@"finishedShare" data:@{@"key":@"value"}];
    
    //有传值 有回调
     [self.webViewBridge callHandler:@"finishedShare" data:@{@"key":@"value"} responseCallback:^(id responseData) {
        // js 完成调用后,如果有回调,可以在这里监听。        
    }];
    

    至于选择写多个 callHandler 来区分不同的方法,还是一个通用的 callHandler ,通过我们传递给 js 的 type 来区分,同上所述。


    js 端

    1、定义对接函数(拷贝该方法到 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)
    }
    

    2、js 调用 objc

    上文中,objc 已经 registerHandler 了 key 为 "shareClick" 的方法。因此 js 按照 key 值,就可以调用了:

    var params = {'key':'value'};
    
    window.WebViewJavascriptBridge.callHandler('shareClick', params);
    
    window.WebViewJavascriptBridge.callHandler('shareClick',params,function(response) {
        //如果 objc 端添加了回调,那么,回执行这里面的代码块
         alert(response);
    });
    

    3、objc 调用 js

    objc 调用 js 需要 js 先注册方法,objc 通过key去调用。

     setupWebViewJavascriptBridge(function(bridge) {
                     bridge.registerHandler('finishedShare', function(data, responseCallback) {
                        //可选,可在执行完js的动作后,通知 objc
                        responseCallback('js执行过了');
                     })
                })
    

    总结:Objctive-C 与 Javascript 的相互调用,在 WebViewJavascriptBridge 的包装下,变得非常简单。总结下来就是:如果是 objc 调用 js ,那么 js注册方法(registerHandler),objc 调用方法(callHandler)。反之,objc 注册方法(registerHandler),js 调用方法(callHandler)。

    相关文章

      网友评论

          本文标题:Objective-C 与 Javascript 交互之 Web

          本文链接:https://www.haomeiwen.com/subject/dpcjkxtx.html