Skip to content

An iOS/OSX bridge for sending messages between Obj-C and JavaScript in UIWebViews/WebViews

License

Notifications You must be signed in to change notification settings

r2ys/WebViewJavascriptBridge

Repository files navigation

WebViewJavascriptBridge

Build Status

An iOS/OSX bridge for sending messages between Obj-C and JavaScript in UIWebViews/WebViews.

Who uses WebViewJavascriptBridge?

WebViewJavascriptBridge is used by a range of companies and projects. This is a small and incomplete sample list:

Facebook Messenger, Facebook Paper, Yardsale, EverTrue, Game Insight, Sush.io, Flutterby Labs, Dojo4's Imbed, CareZone, Hemlig, Altralogica, 鼎盛中华, FRIL, 留白·WHITE

Installation (iOS & OSX)

Installation with CocoaPods

Add this to your podfile and run pod install to install:

`pod 'WebViewJavascriptBridge', '~> 4.1.4'`

Manual installation

Drag the WebViewJavascriptBridge folder into your project.

In the dialog that appears, uncheck "Copy items into destination group's folder" and select "Create groups for any folders".

Examples

See the Example Apps/ folder. Open either the iOS or OSX project and hit run to see it in action.

To use a WebViewJavascriptBridge in your own project:

Usage

  1. Import the header file and declare an ivar property:
#import "WebViewJavascriptBridge.h"

...

@property WebViewJavascriptBridge* bridge;
  1. Instantiate WebViewJavascriptBridge with a UIWebView (iOS) or WebView (OSX):
self.bridge = [WebViewJavascriptBridge bridgeForWebView:webView handler:^(id data, WVJBResponseCallback responseCallback) {
	NSLog(@"Received message from javascript: %@", data);
	responseCallback(@"Right back atcha");
}];
  1. Go ahead and send some messages from ObjC to javascript:
[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);
}];
  1. Finally, set up the javascript side:
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 */

	bridge.registerHandler('JS Echo', function(data, responseCallback) {
		console.log("JS Echo called with:", data)
		responseCallback(data)
	})
	bridge.callHandler('ObjC Echo', function responseCallback(responseData) {
		console.log("JS received response:", responseData)
	})
})

WKWebView Support (iOS 8+ & OS 10.10+)

WARNING: WKWebView still has many bugs and missing network APIs. It may not be a simple drop-in replacement.

WebViewJavascriptBridge supports WKWebView for iOS 8 and OSX Yosemite. In order to use WKWebView you need to instantiate the WKWebViewJavascriptBridge. The rest of the WKWebViewJavascriptBridge API is the same as WebViewJavascriptBridge.

  1. Import the header file:
#import "WKWebViewJavascriptBridge.h"
  1. Instantiate WKWebViewJavascriptBridge and with a WKWebView object
WKWebViewJavascriptBridge* bridge = [WKWebViewJavascriptBridge bridgeForWebView:webView];

Contributors & Forks

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

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

API Reference

ObjC API

[WebViewJavascriptBridge bridgeForWebView:(UIWebView/WebView*)webview

Create a javascript bridge for the given web view.

Example:

[WebViewJavascriptBridge bridgeForWebView:webView];
[bridge registerHandler:(NSString*)handlerName handler:(WVJBHandler)handler]

Register a handler called handlerName. The javascript can then call this handler with WebViewJavascriptBridge.callHandler("handlerName").

Example:

[self.bridge registerHandler:@"getScreenHeight" handler:^(id data, WVJBResponseCallback responseCallback) {
	responseCallback([NSNumber numberWithInt:[UIScreen mainScreen].bounds.size.height]);
}];
[self.bridge registerHandler:@"log" handler:^(id data, WVJBResponseCallback responseCallback) {
	NSLog(@"Log: %@", data);
}];
[bridge callHandler:(NSString*)handlerName data:(id)data]
[bridge callHandler:(NSString*)handlerName data:(id)data responseCallback:(WVJBResponseCallback)callback]

Call the javascript handler called handlerName. Optionally expect a response by giving a responseCallback block.

Example:

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

[bridge setWebViewDelegate:UIWebViewDelegate*)webViewDelegate]

Optionally, set a UIWebViewDelegate if you need to respond to the web view's lifecycle events.

Javascript API

bridge.registerHandler("handlerName", function(responseData) { ... })

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

Example:

bridge.registerHandler("showAlert", function(data) { alert(data) })
bridge.registerHandler("getCurrentPageUrl", function(data, responseCallback) {
	responseCallback(document.location.toString())
})
bridge.callHander("handlerName", data, function responseCallback(responseData) { ... })

Call an ObjC handler called handlerName. If responseCallback is defined, the ObjC handler can respond.

Example:

bridge.callHandler("Log", "Foo")
bridge.callHandler("getScreenHeight", null, function(response) {
	alert('Screen height:' + response)
})

iOS4 support (with JSONKit)

Note: iOS4 support has not yet been tested in v2+.

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

About

An iOS/OSX bridge for sending messages between Obj-C and JavaScript in UIWebViews/WebViews

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Objective-C 91.2%
  • HTML 6.5%
  • Ruby 1.7%
  • Makefile 0.6%