美文网首页
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