2015-06-09 10:30:13 -04:00
# React Native WebView Javascript Bridge
2016-03-05 10:52:04 -05:00
I have been testing and reading a lot of way to safely create a bridge between react-native and webview. I'm happy to announced that the wait is over and from **React-Native 0.20 and above** , the bridge is fully functional.
2015-12-09 13:31:58 -05:00
2015-06-09 10:30:13 -04:00
## Installation
2015-07-14 15:08:02 -04:00
In order to use this extension, you have to do the following steps:
2015-06-09 10:30:13 -04:00
2016-02-11 16:25:25 -05:00
in your react-native project, run `npm install react-native-webview-bridge`
### iOS
1. go to xcode's `Project Navigator` tab
2015-12-09 13:31:58 -05:00
<p align="center">
<img src ="https://raw.githubusercontent.com/alinz/react-native-webview-bridge/master/doc/assets/01.png" />
</p>
2016-02-11 16:25:25 -05:00
2. right click on `Libraries`
3. select `Add Files to ...` option
2015-12-09 13:31:58 -05:00
<p align="center">
<img src ="https://raw.githubusercontent.com/alinz/react-native-webview-bridge/master/doc/assets/02.png" />
</p>
2016-02-11 16:25:25 -05:00
4. navigate to `node_modules/react-native-webview-bridge/ios` and add `React-Native-Webview-Bridge.xcodeproj` folder
2015-12-09 13:31:58 -05:00
<p align="center">
<img src ="https://raw.githubusercontent.com/alinz/react-native-webview-bridge/master/doc/assets/03.png" />
</p>
2016-02-11 16:25:25 -05:00
5. on project `Project Navigator` tab, click on your project's name and select Target's name and from there click on `Build Phases`
2015-12-09 13:31:58 -05:00
<p align="center">
<img src ="https://raw.githubusercontent.com/alinz/react-native-webview-bridge/master/doc/assets/04.png" />
</p>
2016-02-11 16:25:25 -05:00
6. expand `Link Binary With Libraries` and click `+` sign to add a new one.
7. select `libReact-Native-Webviwe-Bridge.a` and click `Add` button.
2015-12-09 13:31:58 -05:00
<p align="center">
<img src ="https://raw.githubusercontent.com/alinz/react-native-webview-bridge/master/doc/assets/05.png" />
</p>
2016-02-11 16:25:25 -05:00
8. clean compile to make sure your project can compile and build.
### Android (Beta)
1. add the following import to `MainActivity.java` of your application
```java
import com.github.alinz.reactnativewebviewbridge.WebViewBridgePackage ;
```
2. add the following code to add the package to `MainActivity.java`
```java
mReactInstanceManager = ReactInstanceManager . builder ()
...
. addPackage ( new WebViewBridgePackage ())
...
```
3. add the following codes to your `android/setting.gradle`
> you might have multiple 3rd party libraries, make sure that you don't create multiple include.
```
include ':app', ':react-native-webview-bridge'
project(':react-native-webview-bridge').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webview-bridge/android')
```
4. edit `android/app/build.gradle` and add the following line inside `dependencies`
```
compile project(':react-native-webview-bridge')
```
5. run `react-native run-android` to see if everything is compilable.
2015-06-09 10:30:13 -04:00
## Usage
2015-12-09 13:31:58 -05:00
just import the module with one of your choices way:
** CommonJS style **
2015-06-09 10:30:13 -04:00
2015-07-14 15:08:02 -04:00
```js
var WebViewBridge = require ( 'react-native-webview-bridge' );
```
2015-12-09 13:31:58 -05:00
** ES6/ES2015 style **
2015-06-09 10:30:13 -04:00
```js
2015-12-09 13:31:58 -05:00
import WebViewBridge from 'react-native-webview-bridge' ;
```
2015-06-09 10:30:13 -04:00
2015-12-09 13:31:58 -05:00
`WebViewBridge` is an extension of `WebView` . It injects special script into any pages once it loads. Also it extends the functionality of `WebView` by adding 1 new method and 1 new props.
2015-06-09 10:30:13 -04:00
2015-12-09 13:31:58 -05:00
#### sendToBridge(message)
the message must be in string. because this is the only way to send data back and forth between native and webview.
2015-06-09 10:30:13 -04:00
2015-12-09 13:31:58 -05:00
#### onBridgeMessage
this is a prop that needs to be a function. it will be called once a message is received from webview. The type of received message is also in string.
## Bridge Script
bridge script is a special script which injects into all the webview. It automatically register a global variable called `WebViewBridge` . It has 2 optional methods to implement and one method to send message to native side.
#### send(message)
this method sends a message to native side. the message must be in string type or `onError` method will be called.
#### onMessage
this method needs to be implemented. it will be called once a message arrives from native side. The type of message is in string.
2016-02-11 16:25:25 -05:00
#### onError (iOS only)
2015-12-09 13:31:58 -05:00
this is an error reporting method. It will be called if there is an error happens during sending a message. It receives a error message in string type.
## Notes
> a special bridge script will be injected once the page is going to different URL. So you don't have to manage when it needs to be injected.
> You can still pass your own javascript to be injected into webview. However, Bridge script will be injected first and then your custom script.
## Simple Example
This example can be found in `examples` folder.
```js
const injectScript = `
2015-12-14 10:51:33 -05:00
function webViewBridgeReady(cb) {
//checks whether WebViewBirdge exists in global scope.
if (window.WebViewBridge) {
cb(window.WebViewBridge);
return;
2015-12-09 13:31:58 -05:00
}
2015-12-14 10:51:33 -05:00
function handler() {
//remove the handler from listener since we don't need it anymore
document.removeEventListener('WebViewBridge', handler, false);
//pass the WebViewBridge object to the callback
cb(window.WebViewBridge);
}
//if WebViewBridge doesn't exist in global scope attach itself to document
//event system. Once the code is being injected by extension, the handler will
//be called.
document.addEventListener('WebViewBridge', handler, false);
}
webViewBridgeReady(function (webViewBridge) {
2016-01-31 21:33:17 +01:00
webViewBridge.onMessage = function (message) {
2015-12-14 10:51:33 -05:00
alert('got a message from Native: ' + message);
2016-01-31 21:33:17 +01:00
webViewBridge.send("message from webview");
2015-12-14 10:51:33 -05:00
};
});
2015-12-09 13:31:58 -05:00
` ;
var Sample2 = React . createClass ({
2015-06-09 10:30:13 -04:00
componentDidMount () {
2015-12-09 13:31:58 -05:00
setTimeout (() => {
this . refs . webviewbridge . sendToBridge ( "hahaha" );
}, 5000 );
},
onBridgeMessage : function ( message ) {
console . log ( message );
},
render : function () {
2015-06-09 10:30:13 -04:00
return (
< WebViewBridge
2015-12-09 13:31:58 -05:00
ref = "webviewbridge"
onBridgeMessage = { this . onBridgeMessage }
injectedJavaScript = { injectScript }
2016-03-05 10:52:04 -05:00
source = {{ uri : "http://google.com" }} />
2015-06-09 10:30:13 -04:00
);
}
2015-12-09 13:31:58 -05:00
});
```