Convert Figma logo to code with AI

marcuswestin logoWebViewJavascriptBridge

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

14,285
2,979
14,285
102

Top Related Projects

android java and javascript bridge, inspired by wechat webview jsbridge

11,811

VasSonic is a lightweight and high-performance Hybrid framework developed by tencent VAS team, which is intended to speed up the first screen of websites working on Android and iOS platform.

Apache Cordova InAppBrowser Plugin

Official Sentry SDK for React Native

17,266

Mars is a cross-platform network component developed by WeChat.

Quick Overview

WebViewJavascriptBridge is a library that provides a seamless way to establish two-way communication between native iOS/Android code and JavaScript code running in a WebView. It allows developers to easily call native functions from JavaScript and vice versa, enabling rich interactions between web content and native app functionality.

Pros

  • Easy integration with existing iOS and Android projects
  • Supports both synchronous and asynchronous communication
  • Well-documented API with clear examples
  • Actively maintained with regular updates

Cons

  • Limited to WebView-based applications
  • May introduce a slight performance overhead compared to native-only solutions
  • Requires careful handling of security concerns when exposing native functionality to web content
  • Learning curve for developers new to hybrid app development

Code Examples

  1. Setting up the bridge in iOS (Swift):
import WebKit
import WebViewJavascriptBridge

class ViewController: UIViewController {
    var bridge: WKWebViewJavascriptBridge!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        let webView = WKWebView(frame: view.bounds)
        view.addSubview(webView)
        
        bridge = WKWebViewJavascriptBridge(webView: webView)
        
        bridge.register(handlerName: "nativeFunction") { data, responseCallback in
            print("Native function called with data: \(data ?? "")")
            responseCallback("Response from native")
        }
    }
}
  1. Calling a native function from JavaScript:
window.WebViewJavascriptBridge.callHandler(
    'nativeFunction',
    {'key': 'value'},
    function(response) {
        console.log('Response from native:', response);
    }
);
  1. Registering a JavaScript handler:
window.WebViewJavascriptBridge.registerHandler('jsFunction', function(data, responseCallback) {
    console.log('JS function called with data:', data);
    responseCallback('Response from JavaScript');
});

Getting Started

  1. Install the library:

    • For iOS: Use CocoaPods and add pod 'WebViewJavascriptBridge' to your Podfile
    • For Android: Add implementation 'com.github.lzyzsd:jsbridge:1.0.4' to your app's build.gradle
  2. Set up the bridge in your native code (iOS example):

import WebViewJavascriptBridge

let webView = WKWebView(frame: view.bounds)
let bridge = WKWebViewJavascriptBridge(webView: webView)

bridge.register(handlerName: "nativeFunction") { data, responseCallback in
    // Handle native function call
    responseCallback("Response from native")
}
  1. Use the bridge in your web content:
<script>
    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 = 'https://__bridge_loaded__';
        document.documentElement.appendChild(WVJBIframe);
        setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)
    }

    setupWebViewJavascriptBridge(function(bridge) {
        bridge.callHandler('nativeFunction', {'key': 'value'}, function(response) {
            console.log('Response from native:', response);
        });
    });
</script>

Competitor Comparisons

android java and javascript bridge, inspired by wechat webview jsbridge

Pros of JsBridge

  • Simpler implementation, potentially easier to integrate for basic use cases
  • Lightweight with fewer dependencies
  • More recent updates and active maintenance

Cons of JsBridge

  • Less comprehensive documentation compared to WebViewJavascriptBridge
  • Fewer features and customization options
  • Smaller community and less widespread adoption

Code Comparison

WebViewJavascriptBridge:

bridge.callHandler('testObjcCallback', {'foo': 'bar'}, function(response) {
    console.log('JS got response', response)
})

JsBridge:

window.JsBridge.call('testObjcCallback', {'foo': 'bar'}, function(response) {
    console.log('JS got response', response)
})

Both libraries provide similar functionality for calling native methods from JavaScript, with slight differences in syntax. WebViewJavascriptBridge uses a bridge object, while JsBridge uses window.JsBridge.

WebViewJavascriptBridge offers more extensive features and has been widely adopted in various projects. It provides robust documentation and examples, making it easier for developers to implement complex interactions between web and native components.

JsBridge, being lighter and simpler, may be suitable for projects with basic requirements or those prioritizing a minimalistic approach. However, it may lack some advanced features and community support compared to WebViewJavascriptBridge.

Ultimately, the choice between these libraries depends on the specific needs of your project, the level of complexity required, and the importance of community support and documentation.

11,811

VasSonic is a lightweight and high-performance Hybrid framework developed by tencent VAS team, which is intended to speed up the first screen of websites working on Android and iOS platform.

Pros of VasSonic

  • Focuses on optimizing web page loading speed, especially for slow networks
  • Supports both Android and iOS platforms
  • Provides a complete solution for hybrid app development, including pre-loading and parallel loading

Cons of VasSonic

  • More complex implementation compared to WebViewJavascriptBridge
  • Requires modifications to both client and server-side code
  • May have a steeper learning curve for developers new to hybrid app development

Code Comparison

WebViewJavascriptBridge (iOS):

[self.bridge callHandler:@"testJavascriptHandler" data:@{ @"foo": @"bar" }
  responseCallback:^(id responseData) {
    NSLog(@"testJavascriptHandler responded: %@", responseData);
}];

VasSonic (Android):

SonicSession session = SonicEngine.getInstance().createSession(url, new SonicSessionConfig.Builder().build());
if (null != session) {
    session.bindClient(new SonicSessionClientImpl());
}

The code snippets demonstrate the different approaches of the two libraries. WebViewJavascriptBridge focuses on bridging JavaScript and native code communication, while VasSonic emphasizes optimizing web page loading and provides a more comprehensive solution for hybrid app development.

Apache Cordova InAppBrowser Plugin

Pros of InAppBrowser

  • Designed specifically for Cordova/PhoneGap applications, offering seamless integration
  • Provides a full-featured in-app browser with more control over the browsing experience
  • Supports a wider range of platforms, including iOS, Android, and Windows

Cons of InAppBrowser

  • Limited to Cordova/PhoneGap ecosystem, not suitable for native iOS/Android development
  • May have a larger footprint and impact on app performance compared to WebViewJavascriptBridge

Code Comparison

WebViewJavascriptBridge (iOS):

[_bridge registerHandler:@"testObjcCallback" handler:^(id data, WVJBResponseCallback responseCallback) {
    NSLog(@"testObjcCallback called: %@", data);
    responseCallback(@"Response from testObjcCallback");
}];

InAppBrowser (Cordova):

var ref = cordova.InAppBrowser.open('https://example.com', '_blank', 'location=yes');
ref.addEventListener('loadstop', function(event) {
    ref.executeScript({code: "alert('hello world');"});
});

The code snippets demonstrate the different approaches:

  • WebViewJavascriptBridge focuses on bidirectional communication between native code and JavaScript
  • InAppBrowser emphasizes controlling a full browser instance within the app

Both libraries serve different purposes:

  • WebViewJavascriptBridge is ideal for native apps requiring JavaScript integration
  • InAppBrowser is better suited for Cordova apps needing a customizable in-app browser

Choose based on your project requirements and development ecosystem.

Official Sentry SDK for React Native

Pros of sentry-react-native

  • Specifically designed for React Native error tracking and performance monitoring
  • Provides comprehensive crash reporting and error logging for React Native apps
  • Integrates seamlessly with Sentry's powerful backend services for analytics and issue management

Cons of sentry-react-native

  • More complex setup and configuration compared to WebViewJavascriptBridge
  • Limited to React Native applications, while WebViewJavascriptBridge is more versatile for general WebView communication
  • Requires a Sentry account and potentially paid plans for advanced features

Code Comparison

WebViewJavascriptBridge (iOS):

[WebViewJavascriptBridge enableLogging];
bridge = [WebViewJavascriptBridge bridgeForWebView:webView];
[bridge registerHandler:@"testObjcCallback" handler:^(id data, WVJBResponseCallback responseCallback) {
    responseCallback(@"Response from testObjcCallback");
}];

sentry-react-native:

import * as Sentry from "@sentry/react-native";

Sentry.init({
  dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
});

Sentry.captureException(new Error("Something went wrong"));

The code snippets demonstrate the basic setup and usage of each library. WebViewJavascriptBridge focuses on bridging communication between native code and JavaScript in WebViews, while sentry-react-native is tailored for error tracking and reporting in React Native applications.

17,266

Mars is a cross-platform network component developed by WeChat.

Pros of Mars

  • Comprehensive cross-platform communication solution for mobile apps
  • Robust network optimization and reliability features
  • Supports multiple protocols (HTTP, UDP, etc.) and provides advanced networking capabilities

Cons of Mars

  • More complex and heavyweight compared to WebViewJavascriptBridge
  • Steeper learning curve due to its extensive feature set
  • May be overkill for simple WebView-to-native communication needs

Code Comparison

WebViewJavascriptBridge (JavaScript):

bridge.callHandler('nativeFunction', {'key': 'value'}, function(response) {
    console.log("JS received response:", response);
});

Mars (C++):

mars::stn::Task task;
task.cmdid_ = CMDID_SEND_MESSAGE;
task.channel_select_ = ChannelType_All;
task.send_only_ = false;
mars::stn::StartTask(task);

While WebViewJavascriptBridge focuses on simple JavaScript-to-native communication, Mars provides a more comprehensive networking solution with advanced features for mobile app development. WebViewJavascriptBridge is easier to implement for basic WebView interactions, while Mars offers robust cross-platform communication capabilities but requires more setup and understanding of its architecture.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

WebViewJavascriptBridge

Circle CI

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

Migration Guide

When upgrading from v5.0.x to 6.0.x you will have to update the setupWebViewJavascriptBridge javascript snippet. See https://github.com/marcuswestin/WebViewJavascriptBridge#usage part 4).

Who uses WebViewJavascriptBridge?

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

Installation (iOS & OSX)

Installation with CocoaPods

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

pod 'WebViewJavascriptBridge', '~> 6.0'

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 WKWebView, UIWebView (iOS) or WebView (OSX):
self.bridge = [WebViewJavascriptBridge bridgeForWebView:webView];
  1. Register a handler in ObjC, and call a 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" data:nil responseCallback:^(id responseData) {
	NSLog(@"ObjC received response: %@", responseData);
}];
  1. Copy and paste setupWebViewJavascriptBridge into your 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 = 'https://__bridge_loaded__';
	document.documentElement.appendChild(WVJBIframe);
	setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)
}
  1. Finally, call setupWebViewJavascriptBridge and then use the bridge to register handlers and call ObjC handlers:
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', {'key':'value'}, function responseCallback(responseData) {
		console.log("JS received response:", responseData)
	})
})

Automatic reference counting (ARC)

This library relies on ARC, so if you use ARC in you project, all works fine. But if your project have no ARC support, be sure to do next steps:

  1. In your Xcode project open project settings -> 'Build Phases'

  2. Expand 'Compile Sources' header and find all *.m files which are belongs to this library. Make attention on the 'Compiler Flags' in front of each source file in this list

  3. For each file add '-fobjc-arc' flag

Now all WVJB files will be compiled with ARC support.

Contributors & Forks

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

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

API Reference

ObjC API

[WebViewJavascriptBridge bridgeForWebView:(WKWebVIew/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. If a responseCallback block is given the javascript handler can respond.

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:(id)webViewDelegate]

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

[bridge disableJavscriptAlertBoxSafetyTimeout]

UNSAFE. Speed up bridge message passing by disabling the setTimeout safety check. It is only safe to disable this safety check if you do not call any of the javascript popup box functions (alert, confirm, and prompt). If you call any of these functions from the bridged javascript code, the app will hang.

Example:

[self.bridge disableJavscriptAlertBoxSafetyTimeout];

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.callHandler("handlerName", data)
bridge.callHandler("handlerName", data, function responseCallback(responseData) { ... })

Call an ObjC handler called handlerName. If a responseCallback function is given the ObjC handler can respond.

Example:

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

Calling bridge.disableJavscriptAlertBoxSafetyTimeout() has the same effect as calling [bridge disableJavscriptAlertBoxSafetyTimeout]; in ObjC.

Example:

bridge.disableJavscriptAlertBoxSafetyTimeout()