在iOS原生应用程序加载网页来实现部分界面或功能已不是什么稀奇的事了。很多应用都使用了HTML+CSS+Javascript+Native APP的方式来开发,如Fackbook、微信和支付宝等。采用这种开发模式具有明显的好处:
当然,这也面临着一个问题,那就是怎么实现原生程序和Web页面交互,也即Objective-C(Swift)与JavaScript交互。iOS SDK中的 UIWebView
和 WKWebView
都可以方便的实现Objective-C(Swift)与JavaScript交互。同时,GitHub上的 WebViewJavascriptBridge 使得交互变得更为轻松。本文将介绍WebViewJavascriptBridge的使用方法。
在GitHub上下载 WebViewJavascriptBridge ,里面包含WebViewJavascriptBridge源代码和使用例子。使用前把文件夹WebViewJavascriptBridge拖入项目即可。
WebViewJavascriptBridge可应用于 UIWebView
和 WKWebView
。 WKWebView 是iOS 8引入的一个新的框架——WebKit.
使用WebViewJavascriptBridge一般会有以下流程:
当然,还必须加载一个网页。
初始化的时候需要提供一个函数/Block,当发送消息给另一个语言时(如Objective-C调用[bridge send:(id)data]向JavaScript发送消息),会执行这个函数/Block。
同时,只有注册的函数才能供另一个语言调用。
导入头文件#import "WebViewJavascriptBridge.h"
申明属性 @property WebViewJavascriptBridge* bridge;
如果使用 WKWebView
,则使用如下方式:
导入头文件#import "WKWebViewJavascriptBridge.h"
申明属性 @property WKWebViewJavascriptBridge* bridge;
//webView可以是UIWebView或WKWebView self.bridge = [WebViewJavascriptBridge bridgeForWebView:webView handler:^(id data, WVJBResponseCallback responseCallback) { NSLog(@"Received message from javascript: %@", data); responseCallback(@"Right back atcha"); }];
在JavaScript中的bridge调用send方法后,会执行handler的block。
[self.bridge registerHandler:@"testObjcCallback" handler:^(id data, WVJBResponseCallback responseCallback) { NSLog(@"testObjcCallback called: %@", data); responseCallback(@"Response from testObjcCallback"); }];
在JavaScript中的bridge调用 testObjcCallback
方法后,会执行该handler的block。
//无回调直接调用 [self.bridge callHandler:@"testJavascriptHandler" data:@{ @"foo":@"before ready" }]; //有回调调用 id data = @{ @"greetingFromObjC": @"Hi there, JS!" }; [self.bridge callHandler:@"testJavascriptHandler" data:data responseCallback:^(id response) { NSLog(@"testJavascriptHandler responded: %@", response); }];
当使用有回调调用方法时,会把 block
传入JavalockScript方法,JavaScript代码可执行该 block
(JavaScript的调用方法见下方)。
[self.bridge send:@"A string sent from ObjC to JS" responseCallback:^(id response) { NSLog(@"sendMessage got response: %@", response); }];
发送消息与调用方法类似,相当调用一个特殊函数(该函数在JavaScript代码中初始化时设置,见下方)。
//加载本地网页 NSString* htmlPath = [[NSBundle mainBundle] pathForResource:@"web" ofType:@"html"]; NSString* appHtml = [NSString stringWithContentsOfFile:htmlPath encoding:NSUTF8StringEncoding error:nil]; NSURL *baseURL = [NSURL fileURLWithPath:htmlPath]; [self.webview loadHTMLString:appHtml baseURL:baseURL]; //加载远程网页 NSURL *url = [NSURL URLWithString:urlStr]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; [self.webview loadRequest:request];
function connectWebViewJavascriptBridge(callback) { if (window.WebViewJavascriptBridge) { callback(WebViewJavascriptBridge) } else { document.addEventListener('WebViewJavascriptBridgeReady', function(event) { callback(WebViewJavascriptBridge) }, false) } } connectWebViewJavascriptBridge(init);
初始化要在添加监听之后进行。初始化时需要传入一个函数,当Objective-C代码发送消息调用 [bridge send:(id)data]
或 [bridge send:(id)data responseCallback:(WVJBResponseCallback)responseCallback]
时会执行此函数。
function recieved(message, responseCallback) { log('JS got a message', message) var data = { 'Javascript Responds': 'Wee!' } log('JS responding with', data) responseCallback(data) } function init(bridge) { bridge.init(recieved); }
function testJavascript(data, responseCallback) { log('ObjC called testJavascriptHandler with', data) var responseData = { 'Javascript Says': 'Right back atcha!' } log('JS responding with', responseData) responseCallback(responseData) } bridge.registerHandler('testJavascriptHandler', testJavascript);
注册后在Objective-C代码中就可调用该函数(调用方法见上述)。
function callObjC() { gbridge.callHandler('testObjcCallback', { 'foo': 'bar' }, function(response) { log('JS got response', response) }); }
Objective-C会执行以名称 testObjcCallback
注册的block。
发送消息
与调用函数类似,会调用Objective-C中初始化时传入的block。
function sendMessage() { var data = 'Hello from JS button' gbridge.send(data, function(responseData) { log('JS got response', responseData) }) }
可以说WebViewJavascriptBridge的使用是如此简单,以至不需要太多的笔墨。当然WebViewJavascriptBridge也是很强大的,它能结合WebApp和Native APP并充分发挥各自的优势。
原文链接: http://zh.5long.me/2015/ios-objective-c-javascript-bridge/
版权声明:自由转载-非商用-保持署名 | Creative Commons BY-NC 4.0