使用 WebViewJavascriptBridge 处理 OC 与 JS 间的交互

项目中遇到需要在 UIVWebView 中添加几个按钮、点击事件以及改变一些文字,在 GitHub 上看到 WebViewJavascriptBridge 可以用于处理 OC 与 JS 间的交互,就尝试使用它做了一些简单的操作。

按照官方说明,需要做以下几步操作进行初始化配置:
1.导入头文件并声明一个 WebViewJavascriptBridge 的实例属性:

#import "WebViewJavascriptBridge.h"

@property WebViewJavascriptBridge* bridge;

2.使用 UIWebView 对 bridge 进行初始化:

self.bridge = [WebViewJavascriptBridge bridgeForWebView:webView];

3.在 OC 中注册一个 Handler 供 JS 调用,或调用 JS 中的一个 Handler:

[self.bridge registerHandler:@"ObjC Echo" handler:^(id data, WVJBResponseCallback responseCallback) {
    NSLog(@"ObjC Echo called with: %@", data);
    responseCallback(data);
}];
[self.bridge callHandler:@"JS Echo" responseCallback:^(id responseData) {
    NSLog(@"ObjC received response: %@", responseData);
}];

4.然后在 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 = 'wvjbscheme://__BRIDGE_LOADED__';
    document.documentElement.appendChild(WVJBIframe);
    setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)
} 
setupWebViewJavascriptBridge(function(bridge) {

    /* Initialize your app here */
    // JS 注册 handler 供 OC 调用,以及调用 OC handler 的例子,注意调用方法和被调用方法必须同名。
    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)
    })
})

因为需求比较简单,所以需要做的步骤不多,只需要在 JS 中动态添加按钮,然后为按钮的 onclick 添加 handler,在 OC 中实现对应的方法即可。

toolbar 中添加一个按钮及handler,实现如下:

    var likeButton = document.getElementById('toolbar').appendChild(document.createElement('input'))
    likeButton.id = 'like'
    likeButton.type = 'image'
    likeButton.src='heart.png'
    likeButton.onclick = function(e) {
        e.preventDefault()
        // handler
        bridge.callHandler('likeNews', {'foo': 'bar'}, function(response) {
            likecount.innerHTML = response
            likeButton.src='heart_selected.png'
        })
    }

在 OC 中添加对应方法:

- (void)likeNews
{
    [self.bridge registerHandler:@"likeNews" handler:^(id data, WVJBResponseCallback responseCallback) {
        [Comment topicWithContentId:self.contentID result:^(SSResponseState state, id<ISSCTopic> topic, NSError *error) {
            if (![topic liked]) {
                [Comment likeWithContentId:self.contentID title:self.contentDict[@"title"]   comment:nil user:nil result:^(SSResponseState state, NSError *error) {
                    if (state == 1) {
                        responseCallback([NSString stringWithFormat:@"%ld", (long)[topic likeCount]]);
                    }
                }];
            } else {
                responseCallback([NSString stringWithFormat:@"%ld", (long)[topic likeCount]]);
            }
        }];
    }];
}

这里使用了 ShareSDK 来进行分享,即 Comment,获取对应的评论并进行点赞操作。

其实这个项目中对 HTML 的处理有更方便的方法,不过之前由于使用 Json 来传递 HTML 数据,然后本地处理、添加 CSS 等,处理的比较麻烦,不过最后的效果都差不多。

最后感谢一下富士233。

推荐阅读更多精彩内容