WebViewJavascriptBridge-Obj-C和JavaScript互通消息的桥梁

移动开发 后端
WebViewJavascriptBridge 要求 WebViewJavascriptBridge.js.txt 文件嵌入到web view来创建一个在JS这边的桥梁.标准的实现是用 mainBundle 找到这个文件.如果你建立一个 静态库并且你把这个文件放在其他地方,你可以用下面的方法找 WebViewJavascriptBridge.js.txt 文件:

[[138163]]

WebViewJavascriptBridge是Obj-C和JavaScript通过UIWebViews/WebViews互通消息的一个iOS/OSX的桥梁. 如果你喜欢WebViewJavascriptBridge,你可能也想check outWebViewProxy.

Obj-C和JavaScript原理简单说一下,Obj-C调用JavaScript很简单,可以通过webview的stringByEvaluatingJavaScriptFromString:方法调用JavaScript代码;JavaScript调用Obj-C,则是通过web view的代理方法shouldStartLoadWithRequest:来接收JavaScript的网络请求从而实现调用。

正在使用WebViewJavascriptBridge的项目

有很多的公司和项目在使用WebViewJavascriptBridge.这个列表不完整,你可以随意添加.

Facebook Messenger

Facebook Paper

Yardsale

EverTrue

Game Insight

Altralogica

Sush.io

Flutterby Labs

JD Media’s 鼎盛中华

Dojo4’s Imbed

CareZone

Hemlig

安装& 例子 (iOS & OSX)

首先打开Example Apps文件夹.打开iOS或者OSX的工程然后点击运行.

在你自己的工程中用WebViewJavascriptBridge:

1) 拖动 WebViewJavascriptBridge 文件夹到你的工程中.

在出现的对话框中, 取消 (我觉得应该是选中)”Copy items into destination group’s folder” 并且 选择 “Create groups for any folders”

2) 引入头文件并且申明一个属性:

  1. #import "WebViewJavascriptBridge.h" 
  2. ... 
  3. @property WebViewJavascriptBridge* bridge; 

3) 实例化WebViewJavascriptBridge并且带上一个UIWebView (iOS)或者WebView (OSX):

  1. self.bridge = [WebViewJavascriptBridge bridgeForWebView:webView handler:^(id data, WVJBResponseCallback responseCallback) { 
  2. NSLog(@"Received message from javascript: %@", data); 
  3. responseCallback(@"Right back atcha"); 
  4. }]; 

4) 首先从ObjC到javascript发送一些消息:

  1. [self.bridge send:@"Well hello there"]; 
  2. [self.bridge send:[NSDictionary dictionaryWithObject:@"Foo" forKey:@"Bar"]]; 
  3. [self.bridge send:@"Give me a response, will you?" responseCallback:^(id responseData) { 
  4. NSLog(@"ObjC got its response! %@", responseData); 
  5. }]; 

5) 然后,看看javascript这边:

  1. function connectWebViewJavascriptBridge(callback) { 
  2. if (window.WebViewJavascriptBridge) { 
  3. callback(WebViewJavascriptBridge) 
  4. } else { 
  5. document.addEventListener('WebViewJavascriptBridgeReady', function() { 
  6. callback(WebViewJavascriptBridge) 
  7. }, false) 
  8. connectWebViewJavascriptBridge(function(bridge) { 
  9. /* Init your app here */ 
  10. bridge.init(function(message, responseCallback) { 
  11. alert('Received message: ' + message) 
  12. if (responseCallback) { 
  13. responseCallback("Right back atcha") 
  14. }) 
  15. bridge.send('Hello from the javascript') 
  16. bridge.send('Please respond to this', function responseCallback(responseData) { 
  17. console.log("Javascript got its response", responseData) 
  18. }) 
  19. }) 

Contributors & Forks

Contributors: https://github.com/marcuswestin/WebViewJavascriptBridge/graphs/contributors

Forks: https://github.com/marcuswestin/WebViewJavascriptBridge/network/members

API 参考

ObjC API

  1. [WebViewJavascriptBridge bridgeForWebView: (UIWebView/WebView*)webview handler:(WVJBHandler)handler] 
  2.  
  3. [WebViewJavascriptBridge bridgeForWebView: 
  4.  
  5. (UIWebView/WebView*)webview webViewDelegate: 
  6.  
  7. (UIWebViewDelegate*)webViewDelegate handler:(WVJBHandler)handler] 

给web view创建一个javascript的桥梁.

假如javascript需要一个反馈,那么 WVJBResponseCallback 不能为 nil .

当然,通过 webViewDelegate:(UIWebViewDelegate*)webViewDelegate 你可以得到web view的生命周期事件.

例子:

  1. WebViewJavascriptBridge bridgeForWebView:webView handler:^(id data, WVJBResponseCallback responseCallback) { 
  2. NSLog(@"Received message from javascript: %@", data); 
  3. if (responseCallback) { 
  4. responseCallback(@"Right back atcha"); 
  5. }] 
  6. [WebViewJavascriptBridge bridgeForWebView:webView webViewDelegate:self handler:^(id data, WVJBResponseCallback responseCallback) { /* ... */ }]; 
  7.  
  8. [bridge send:(id)data] 
  9.  
  10. [bridge send:(id)data responseCallback:(WVJBResponseCallback)responseCallback] 

发送一个消息给javascript. 并且在发送消息成功后可以通过 responseCallback block做出一 些反应.

例子:

  1. [self.bridge send:@"Hi"]; 
  2. [self.bridge send:[NSDictionary dictionaryWithObject:@"Foo" forKey:@"Bar"]]; 
  3. [self.bridge send:@"I expect a response!" responseCallback:^(id responseData) { 
  4. NSLog(@"Got response! %@", responseData); 
  5. }]; 
  6.  
  7. [bridge registerHandler:(NSString*)handlerName handler: (WVJBHandler)handler] 

注册一个叫做 handlerName 的handler. javascript能够通过 WebViewJavascriptBridge.callHandler(“handlerName”) 调起这个handler.

例子:

  1. [self.bridge registerHandler:@"getScreenHeight" handler:^(id data, WVJBResponseCallback responseCallback) { 
  2. responseCallback([NSNumber numberWithInt:[UIScreen mainScreen].bounds.size.height]); 
  3. }]; 
  4.  
  5. [bridge callHandler:(NSString*)handlerName data:(id)data] 
  6.  
  7. [bridge callHandler:(NSString*)handlerName data:(id)data responseCallback:(WVJBResponseCallback)callback] 

调起javascript叫做 handlerName的handler. 在调用 handler成功后可以通过responseCallback block做出反应.

例子:

  1. [self.bridge callHandler:@"showAlert" data:@"Hi from ObjC to JS!"]; 
  2. [self.bridge callHandler:@"getCurrentPageUrl" data:nil responseCallback:^(id responseData) { 
  3. NSLog(@"Current UIWebView page URL is: %@", responseData); 
  4. }]; 

定义 bundle

WebViewJavascriptBridge 要求 WebViewJavascriptBridge.js.txt 文件嵌入到web view来创建一个在JS这边的桥梁.标准的实现是用 mainBundle 找到这个文件.如果你建立一个 静态库并且你把这个文件放在其他地方,你可以用下面的方法找 WebViewJavascriptBridge.js.txt 文件:

[WebViewJavascriptBridge bridgeForWebView:

(UIWebView/WebView*)webView webViewDelegate:

(UIWebViewDelegate*)webViewDelegate handler:(WVJBHandler)handler

resourceBundle:(NSBundle*)bundle

例子:

  1. [WebViewJavascriptBridge bridgeForWebView:_webView 
  2. webViewDelegate:self 
  3. handler:^(id data, WVJBResponseCallback responseCallback) { 
  4. NSLog(@"Received message from javascript: %@", data); 
  5. resourceBundle:[NSBundle bundleWithURL:[[NSBundle mainBundle] URLForResource:@"ResourcesBundle" withExtension:@"bundle"]] 
  6. ]; 

Javascript API

document.addEventListener(‘WebViewJavascriptBridgeReady’,

function onBridgeReady(event) { … }, false)

一直等待 WebViewJavascriptBridgeReady DOM 事件.

例子:

  1. document.addEventListener('WebViewJavascriptBridgeReady', function(event) { 
  2. var bridge = event.bridge 
  3. // Start using the bridge 
  4. }, false) 

bridge.init(function messageHandler(data, response) { … })

初始化这个桥. 这会调起 ‘WebViewJavascriptBridgeReady’ 的事件handler.

这个 messageHandler 函数会接收通过ObjC的 [bridge send:(id)data] 和 [bridge send:(id)data responseCallback:(WVJBResponseCallback)responseCallback] 方法 发送的所有消息.

如果ObjC发送消息时有WVJBResponseCallback block,那么可以通过response对象发送消息.

例子:

  1. bridge.init(function(data, responseCallback) { 
  2. alert("Got data " + JSON.stringify(data)) 
  3. if (responseCallback) { 
  4. responseCallback("Right back atcha!"
  5. }) 

bridge.send(“Hi there!”)

bridge.send({ Foo:”Bar” })

bridge.send(data, function responseCallback(responseData) { …

})

给ObjC发送消息. 在发送成功后可以通过 responseCallback 函数做出反应.

例子:

  1. bridge.send("Hi there!"
  2. bridge.send("Hi there!", function(responseData) { 
  3. alert("I got a response! "+JSON.stringify(responseData)) 
  4. }) 

bridge.registerHandler(“handlerName”, function(responseData) { … })

注册一个叫做 handlerName 的handler. ObjC能够通过 [bridge callHandler:”handlerName” data:@”Foo”] 和 [bridge callHandler:”handlerName” data:@”Foo” responseCallback:^(id responseData) { … }] 两个方法调起这个handler.

例子:

  1. bridge.registerHandler("showAlert", function(data) { alert(data) }) 
  2. bridge.registerHandler("getCurrentPageUrl", function(data, responseCallback) { 
  3. responseCallback(document.location.toString()) 
  4. }) 

iOS4 支持 (包括 JSONKit)

注:iOS4支持尚未在V2 +测试.

WebViewJavascriptBridge 默认使用 NSJSONSerialization .如果你需要iOS 4的支持,你可以用JSONKit,并且增加 USE_JSONKIT 的预处理宏到你的工程中.

责任编辑:chenqingxiang 来源: CocoaChina
相关推荐

2009-10-30 10:15:00

双线接入技术

2021-02-05 18:22:51

GoC剖析

2009-10-14 13:57:51

RESTFul Bri

2012-09-20 09:17:18

LinuxWindows

2012-09-20 15:54:46

LinuxWindows服务器

2011-04-11 10:09:20

委托反馈C++

2016-06-29 10:42:42

云计算混合云

2021-01-28 21:40:25

webRTC音视频Web

2019-07-19 07:56:13

消息队列消息代理消息中间件

2009-08-19 15:54:33

处理C#消息

2023-07-28 08:13:30

2013-04-03 10:22:00

iOS开发Objective-C

2023-03-19 17:21:31

CLIP架构人工智能

2021-05-14 11:02:33

PythonShell命令

2013-03-26 10:08:38

LLVM 4.0语法变LLVM 4.0新特性

2021-06-16 11:06:55

微信QQLinux

2011-10-11 09:46:28

2013-04-28 10:36:00

Obj-C数组Obj-C字符串拼接与

2011-07-08 14:23:39

云计算英特尔基础架构

2024-05-20 08:21:36

Activity内部类接口
点赞
收藏

51CTO技术栈公众号