Skip to content

Commit 49dd503

Browse files
committed
Merge branch 'release/v0.19.0'
2 parents d89f1da + 5847b8b commit 49dd503

File tree

16 files changed

+661
-130
lines changed

16 files changed

+661
-130
lines changed

README.md

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,73 @@
11
# React Native WebView Javascript Bridge
2-
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.16 and above**, the bridge is fully functional.
2+
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.19 and above**, the bridge is fully functional.
33

44

55

66
## Installation
77

88
In order to use this extension, you have to do the following steps:
99

10-
1. in your react-native project, run `npm install react-native-webview-bridge`
11-
2. go to xcode's `Project Navigator` tab
10+
in your react-native project, run `npm install react-native-webview-bridge`
11+
12+
### iOS
13+
14+
1. go to xcode's `Project Navigator` tab
1215
<p align="center">
1316
<img src ="https://raw.githubusercontent.com/alinz/react-native-webview-bridge/master/doc/assets/01.png" />
1417
</p>
15-
3. right click on `Libraries`
16-
4. select `Add Files to ...` option
18+
2. right click on `Libraries`
19+
3. select `Add Files to ...` option
1720
<p align="center">
1821
<img src ="https://raw.githubusercontent.com/alinz/react-native-webview-bridge/master/doc/assets/02.png" />
1922
</p>
20-
5. navigate to `node_modules/react-native-webview-bridge/ios` and add `React-Native-Webview-Bridge.xcodeproj` folder
23+
4. navigate to `node_modules/react-native-webview-bridge/ios` and add `React-Native-Webview-Bridge.xcodeproj` folder
2124
<p align="center">
2225
<img src ="https://raw.githubusercontent.com/alinz/react-native-webview-bridge/master/doc/assets/03.png" />
2326
</p>
24-
6. on project `Project Navigator` tab, click on your project's name and select Target's name and from there click on `Build Phases`
27+
5. on project `Project Navigator` tab, click on your project's name and select Target's name and from there click on `Build Phases`
2528
<p align="center">
2629
<img src ="https://raw.githubusercontent.com/alinz/react-native-webview-bridge/master/doc/assets/04.png" />
2730
</p>
28-
7. expand `Link Binary With Libraries` and click `+` sign to add a new one.
29-
8. select `libReact-Native-Webviwe-Bridge.a` and click `Add` button.
31+
6. expand `Link Binary With Libraries` and click `+` sign to add a new one.
32+
7. select `libReact-Native-Webviwe-Bridge.a` and click `Add` button.
3033
<p align="center">
3134
<img src ="https://raw.githubusercontent.com/alinz/react-native-webview-bridge/master/doc/assets/05.png" />
3235
</p>
33-
9. clean compile to make sure your project can compile and build.
36+
8. clean compile to make sure your project can compile and build.
37+
38+
### Android (Beta)
39+
40+
1. add the following import to `MainActivity.java` of your application
41+
42+
```java
43+
import com.github.alinz.reactnativewebviewbridge.WebViewBridgePackage;
44+
```
45+
46+
2. add the following code to add the package to `MainActivity.java`
47+
48+
```java
49+
mReactInstanceManager = ReactInstanceManager.builder()
50+
...
51+
.addPackage(new WebViewBridgePackage())
52+
...
53+
```
54+
55+
3. add the following codes to your `android/setting.gradle`
56+
57+
> you might have multiple 3rd party libraries, make sure that you don't create multiple include.
58+
59+
```
60+
include ':app', ':react-native-webview-bridge'
61+
project(':react-native-webview-bridge').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webview-bridge/android')
62+
```
63+
64+
4. edit `android/app/build.gradle` and add the following line inside `dependencies`
65+
66+
```
67+
compile project(':react-native-webview-bridge')
68+
```
69+
70+
5. run `react-native run-android` to see if everything is compilable.
3471

3572
## Usage
3673

@@ -70,7 +107,7 @@ this method sends a message to native side. the message must be in string type o
70107

71108
this method needs to be implemented. it will be called once a message arrives from native side. The type of message is in string.
72109

73-
#### onError
110+
#### onError (iOS only)
74111

75112
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.
76113

android/build.gradle

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
buildscript {
2+
repositories {
3+
jcenter()
4+
}
5+
6+
dependencies {
7+
classpath 'com.android.tools.build:gradle:1.1.3'
8+
}
9+
}
10+
11+
apply plugin: 'com.android.library'
12+
13+
android {
14+
compileSdkVersion 23
15+
buildToolsVersion "23.0.1"
16+
17+
defaultConfig {
18+
minSdkVersion 16
19+
targetSdkVersion 23
20+
versionCode 1
21+
versionName "1.0"
22+
}
23+
lintOptions {
24+
abortOnError false
25+
}
26+
}
27+
28+
repositories {
29+
mavenCentral()
30+
}
31+
32+
dependencies {
33+
compile 'com.facebook.react:react-native:0.19.+'
34+
}

android/src/main/AndroidManifest.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2+
package="com.github.alinz.reactnativewebviewbridge">
3+
4+
</manifest>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.github.alinz.reactnativewebviewbridge;
2+
3+
import android.webkit.JavascriptInterface;
4+
5+
import com.facebook.react.bridge.Arguments;
6+
import com.facebook.react.bridge.ReactContext;
7+
import com.facebook.react.bridge.WritableMap;
8+
import com.facebook.react.modules.core.DeviceEventManagerModule;
9+
10+
class JavascriptBridge {
11+
private ReactContext context;
12+
13+
public JavascriptBridge(ReactContext context) {
14+
this.context = context;
15+
}
16+
17+
@JavascriptInterface
18+
public void send(String message) {
19+
WritableMap params = Arguments.createMap();
20+
params.putString("message", message);
21+
context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
22+
.emit("webViewBridgeMessage", params);
23+
}
24+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package com.github.alinz.reactnativewebviewbridge;
2+
3+
import javax.annotation.Nullable;
4+
import java.util.Map;
5+
6+
import android.webkit.WebView;
7+
8+
import com.facebook.react.views.webview.ReactWebViewManager;
9+
import com.facebook.react.views.webview.WebViewConfig;
10+
import com.facebook.react.bridge.ReadableArray;
11+
import com.facebook.react.bridge.ReactContext;
12+
import com.facebook.react.bridge.WritableMap;
13+
import com.facebook.react.common.MapBuilder;
14+
15+
public class WebViewBridgeManager extends ReactWebViewManager {
16+
private static final String REACT_CLASS = "RCTWebViewBridge";
17+
18+
public static final int COMMAND_INJECT_BRIDGE_SCRIPT = 100;
19+
public static final int COMMAND_SEND_TO_BRIDGE = 101;
20+
21+
private boolean initializedBridge;
22+
23+
public WebViewBridgeManager() {
24+
super();
25+
initializedBridge = false;
26+
}
27+
28+
public WebViewBridgeManager(WebViewConfig webViewConfig) {
29+
super(webViewConfig);
30+
initializedBridge = false;
31+
}
32+
33+
@Override
34+
public String getName() {
35+
return REACT_CLASS;
36+
}
37+
38+
@Override
39+
public @Nullable Map<String, Integer> getCommandsMap() {
40+
Map<String, Integer> commandsMap = super.getCommandsMap();
41+
42+
commandsMap.put("injectBridgeScript", COMMAND_INJECT_BRIDGE_SCRIPT);
43+
commandsMap.put("sendToBridge", COMMAND_SEND_TO_BRIDGE);
44+
45+
return commandsMap;
46+
}
47+
48+
@Override
49+
public void receiveCommand(WebView root, int commandId, @Nullable ReadableArray args) {
50+
super.receiveCommand(root, commandId, args);
51+
52+
switch (commandId) {
53+
case COMMAND_INJECT_BRIDGE_SCRIPT:
54+
injectBridgeScript(root);
55+
break;
56+
case COMMAND_SEND_TO_BRIDGE:
57+
sendToBridge(root, args.getString(0));
58+
break;
59+
default:
60+
//do nothing!!!!
61+
}
62+
}
63+
64+
private void sendToBridge(WebView root, String message) {
65+
//root.loadUrl("javascript:(function() {\n" + script + ";\n})();");
66+
String script = "WebViewBridge.onMessage('" + message + "');";
67+
root.evaluateJavascript(script, null);
68+
}
69+
70+
private void injectBridgeScript(WebView root) {
71+
//this code needs to be called once per context
72+
if (!initializedBridge) {
73+
root.addJavascriptInterface(new JavascriptBridge((ReactContext)root.getContext()), "WebViewBridgeAndroid");
74+
initializedBridge = true;
75+
}
76+
77+
//this code needs to be executed everytime a url changes.
78+
root.evaluateJavascript(""
79+
+ "(function() {"
80+
+ "if (window.WebViewBridge) return;"
81+
+ "var customEvent = document.createEvent('Event');"
82+
+ "WebViewBridge = {"
83+
+ "send: function(message) { WebViewBridgeAndroid.send(message); },"
84+
+ "onMessage: function() {}"
85+
+ "};"
86+
+ "window.WebViewBridge = WebViewBridge;"
87+
+ "customEvent.initEvent('WebViewBridge', true, true);"
88+
+ "document.dispatchEvent(customEvent);"
89+
+"}())", null);
90+
}
91+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.github.alinz.reactnativewebviewbridge;
2+
3+
import com.facebook.react.ReactPackage;
4+
import com.facebook.react.bridge.JavaScriptModule;
5+
import com.facebook.react.bridge.NativeModule;
6+
import com.facebook.react.bridge.ReactApplicationContext;
7+
import com.facebook.react.uimanager.ViewManager;
8+
9+
import java.util.ArrayList;
10+
import java.util.Arrays;
11+
import java.util.List;
12+
13+
public class WebViewBridgePackage implements ReactPackage {
14+
@Override
15+
public List<NativeModule> createNativeModules(ReactApplicationContext reactApplicationContext) {
16+
return new ArrayList<>();
17+
}
18+
19+
@Override
20+
public List<ViewManager> createViewManagers(ReactApplicationContext reactApplicationContext) {
21+
return Arrays.<ViewManager>asList(
22+
new WebViewBridgeManager()
23+
);
24+
}
25+
26+
@Override
27+
public List<Class<? extends JavaScriptModule>> createJSModules() {
28+
return Arrays.asList();
29+
}
30+
}

examples/Sample2/android/app/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,6 @@ dependencies {
7575
compile fileTree(dir: "libs", include: ["*.jar"])
7676
compile "com.android.support:appcompat-v7:23.0.1"
7777
compile "com.facebook.react:react-native:0.16.+"
78+
//compile "com.github.alinz.reactnativewebviewbridge"
79+
compile project(':react-native-webview-bridge')
7880
}

examples/Sample2/android/app/src/main/java/com/sample2/MainActivity.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
import com.facebook.react.shell.MainReactPackage;
1212
import com.facebook.soloader.SoLoader;
1313

14+
import com.github.alinz.reactnativewebviewbridge.WebViewBridgePackage;
15+
1416
public class MainActivity extends Activity implements DefaultHardwareBackBtnHandler {
1517

1618
private ReactInstanceManager mReactInstanceManager;
@@ -26,6 +28,7 @@ protected void onCreate(Bundle savedInstanceState) {
2628
.setBundleAssetName("index.android.bundle")
2729
.setJSMainModuleName("index.android")
2830
.addPackage(new MainReactPackage())
31+
.addPackage(new WebViewBridgePackage())
2932
.setUseDeveloperSupport(BuildConfig.DEBUG)
3033
.setInitialLifecycleState(LifecycleState.RESUMED)
3134
.build();
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
rootProject.name = 'Sample2'
22

3-
include ':app'
3+
include ':app', ':react-native-webview-bridge'
4+
project(':react-native-webview-bridge').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webview-bridge/android')

examples/Sample2/app.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/**
2+
* Sample React Native App
3+
* https://github.com/facebook/react-native
4+
*/
5+
'use strict';
6+
7+
var React = require('react-native');
8+
var {
9+
StyleSheet,
10+
Text,
11+
View,
12+
WebView
13+
} = React;
14+
15+
var WebViewBridge = require('react-native-webview-bridge');
16+
17+
const injectScript = `
18+
(function () {
19+
if (WebViewBridge) {
20+
21+
WebViewBridge.onMessage = function (message) {
22+
alert('got a message from Native: ' + message);
23+
24+
WebViewBridge.send("message from webview");
25+
};
26+
27+
} else {
28+
window.location.href = "yahoo.ca";
29+
}
30+
}());
31+
`;
32+
33+
var Sample2 = React.createClass({
34+
onBridgeMessage: function (message) {
35+
console.log(message);
36+
},
37+
render: function() {
38+
return (
39+
<WebViewBridge
40+
ref="webviewbridge"
41+
onBridgeMessage={this.onBridgeMessage}
42+
javaScriptEnabled={true}
43+
injectedJavaScript={injectScript}
44+
url={"https://google.com"}/>
45+
);
46+
}
47+
});
48+
49+
module.exports = Sample2;

0 commit comments

Comments
 (0)