WebViewJavascriptBridge-Bridge between Obj-C and JavaScript

WebViewJavascriptBridge-Bridge between Obj-C and JavaScript

[[138163]]

WebViewJavascriptBridge is an iOS/OSX bridge for Obj-C and JavaScript to communicate via UIWebViews/WebViews. If you like WebViewJavascriptBridge, you might also want to check out WebViewProxy.

Let me briefly explain the principles of Obj-C and JavaScript. It is very simple for Obj-C to call JavaScript. You can call JavaScript code through the stringByEvaluatingJavaScriptFromString: method of webview; JavaScript calls Obj-C by receiving JavaScript network requests through the web view's proxy method shouldStartLoadWithRequest: to implement the call.

Projects using WebViewJavascriptBridge

There are many companies and projects using WebViewJavascriptBridge. This list is not complete, feel free to add to it.

Facebook Messenger

Facebook Paper

Yardsale

EverTrue

Game Insight

Altralogica

Sush.io

Flutterby Labs

JD Media's China

Dojo4's Imbed

CareZone

Hemlig

Installation & Examples (iOS & OSX)

First open the Example Apps folder. Open the iOS or OSX project and click Run.

To use WebViewJavascriptBridge in your own project:

1) Drag the WebViewJavascriptBridge folder into your project.

In the dialog box that appears, uncheck (I think it should be checked) "Copy items into destination group's folder" and select "Create groups for any folders"

2) Import the header file and declare a property:

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

3) Instantiate WebViewJavascriptBridge and bring a UIWebView (iOS) or 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) First send some messages from ObjC to 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) Then, look at the javascript side:

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

Contributors & Forks

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

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

API Reference

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]

Create a javascript bridge to the web view.

If the javascript needs a response, then WVJBResponseCallback cannot be nil.

Of course, you can get the life cycle events of the web view through webViewDelegate:(UIWebViewDelegate*)webViewDelegate.

example:

  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. }]
  7. [WebViewJavascriptBridge bridgeForWebView:webView webViewDelegate:self handler:^(id data, WVJBResponseCallback responseCallback) { /* ... */ }];
  8.  
  9. [bridge send:(id)data]
  10.  
  11. [bridge send:(id)data responseCallback:(WVJBResponseCallback)responseCallback]

Send a message to javascript. And after the message is sent successfully, you can make some response through the responseCallback block.

example:

  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]

Register a handler called handlerName. JavaScript can call this handler via WebViewJavascriptBridge.callHandler("handlerName").

example:

  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]

Calls the handler named handlerName in javascript. After the handler is successfully called, a response can be made through the responseCallback block.

example:

  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. }];

Defining a bundle

WebViewJavascriptBridge requires the WebViewJavascriptBridge.js.txt file to be embedded in the web view to create a bridge on the JS side. The standard implementation uses mainBundle to find this file. If you build a static library and you put this file somewhere else, you can find the WebViewJavascriptBridge.js.txt file as follows:

[WebViewJavascriptBridge bridgeForWebView:

(UIWebView/WebView*)webView webViewDelegate:

(UIWebViewDelegate*)webViewDelegate handler:(WVJBHandler)handler

resourceBundle:(NSBundle*)bundle

example:

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

Javascript API

document.addEventListener('WebViewJavascriptBridgeReady',

function onBridgeReady(event) { … }, false)

Waiting for the WebViewJavascriptBridgeReady DOM event.

example:

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

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

Initialize the bridge. This will invoke the 'WebViewJavascriptBridgeReady' event handler.

This messageHandler function will receive all messages sent through the ObjC [bridge send:(id)data] and [bridge send:(id)data responseCallback:(WVJBResponseCallback)responseCallback] methods.

If there is a WVJBResponseCallback block when ObjC sends a message, the message can be sent through the response object.

example:

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

bridge.send("Hi there!")

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

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

})

Send a message to ObjC. After the message is sent successfully, you can react through the responseCallback function.

example:

  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) { … })

Register a handler called handlerName. ObjC can call this handler via [bridge callHandler:"handlerName" data:@"Foo"] and [bridge callHandler:"handlerName" data:@"Foo" responseCallback:^(id responseData) { … }]

example:

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

iOS4 support (including JSONKit)

NOTE: iOS4 support has not been tested in V2+.

WebViewJavascriptBridge uses NSJSONSerialization by default. If you need iOS 4 support, you can use JSONKit and add the USE_JSONKIT preprocessor macro to your project.

<<:  Cocos Developer Salon Chengdu Station will be grandly opened to serve entrepreneurs

>>:  Subversive design - Apple cancels the Home button

Recommend

Android decompilation - smali syntax

Preface We have talked about the tools for androi...

How difficult is it to produce the blue fireworks in the TV series "Nothing But Thirty"?

In the TV series “Nothing But Thirty”, “blue fire...

Resource satellites: the "eyes" in space

Resource satellites are China's earliest tran...

New discovery! This cell can repair liver damage!

my country has the highest prevalence of liver di...

Methodology in the Internet Age: Business Rules for Online Communities

Since the development of the Internet, people hav...

iPhone 7 Plus/Pro dual-camera may be delayed due to technical issues

According to foreign media reports, if you have s...

How to achieve a breakthrough from 0 to 1 in information flow advertising

If you don’t want to be blamed for “ineffective m...

Why did Xiaomi make a 3,000 yuan router?

On the afternoon of June 10, Xiaomi held a press ...

Here’s what you need to know about food shelf life

One minute with the doctor, the postures are cons...

How to conduct data analysis for operational promotion?

Talking about data analysis theory alone is too d...