Skip to content
This repository has been archived by the owner on Jul 2, 2019. It is now read-only.

shayne/react-native-webview-js-context

Repository files navigation

react-native-webview-js-context npm version

Interactive JavaScript between a UIWebView and React Native.

Example: Google Charts used to render a chart (base64 encoded image) in a <Image /> component

const GC_HTML = `
  <html>
    <head>
      <script type="text/javascript" src="https://www.google.com/jsapi"></script>
      <script type="text/javascript">
        google.load('visualization', '1.0', {'packages':['corechart']});
        google.setOnLoadCallback(resolve); /* <--- resolve() is called by RNWebViewJSContext */
      </script>
    </head>
    <body><div id="chart_div"></div></body>
  </html>`;

const CHART_JS = `
  var data = new google.visualization.DataTable();
  data.addColumn('date', 'Day');
  data.addColumn('number', 'Weight');
  data.addColumn({ type: 'string', role: 'annotation' });
  data.addRows([
      [new Date(2015, 2, 1), 150, '150'],
      [new Date(2015, 2, 2), 152, null],
      [new Date(2015, 2, 3), 146, '146'],
      [new Date(2015, 2, 4), 150, null],
      [new Date(2015, 2, 5), 157, '157'],
      [new Date(2015, 2, 06), 147, null],
      [new Date(2015, 2, 07), 147.5, '147'],
  ]);

  var options = { enableInteractivity: false,
                  legend: {position: 'none'},
                  lineWidth: 3, width:750, height:420,
                  pointShape: 'circle', pointSize: 8,
                  chartArea: { left: 30, width: 690 }, areaOpacity: 0.07,
                  colors: ['#e14c4d'], backgroundColor: { 'fill': '#34343f' },
                  annotations: {
                    textStyle: { fontSize: 26, bold: true, color: '#bbbbbd', auroColor: '#3f3f3f' },
                  },
                  hAxis: {
                    format: 'MMM d',
                    textStyle: {color: '#bbbbbd', fontSize: 16,}, gridlines: { color: 'transparent' },
                  },
                  vAxis: { gridlines: { count: 3, color: '#3f414f' } },
                };

  var chart = new google.visualization.AreaChart(document.getElementById('chart_div'));
  chart.draw(data, options);

  resolve(chart.getImageURI()); /* <--- resolve() is called by RNWebViewJSContext */`;

import WebViewJSContext from 'react-native-webview-js-context';

class RNCharts {
  state: { imageUri: null };

  componentWillMount() {
    WebViewJSContext.createWithHTML(GC_HTML)
      .then(context => {
        this.ctx = context;
        this.loadChart();
      });
  }

  componentWillUnmount() {
    this.ctx && this.ctx.destroy();
  },

  render() {
    return this.state.imageUri ?
      <Image style={{ width: 375, height: 300 }} source={{ uri: this.state.imageUri }} />
      : <View />;
  }

  async loadChart() {
    var imageUri = await this.ctx.evaluateScript(CHART_JS);
    this.setState({ imageUri });
  }
}

Usage

First you need to install react-native-webview-js-context:

npm install react-native-webview-js-context --save

iOS

  1. In XCode, in the project navigator, right click LibrariesAdd Files to [your project's name]
  2. Go to node_modulesreact-native-webview-js-contextios and add RNWebViewJSContext.xcodeproj
  3. In XCode, in the project navigator, select your project. Add libRNWebViewJSContext.a to your project's Build PhasesLink Binary With Libraries
  4. Run your project (Cmd+R)

Android

  • android/settings.gradle
...
include ':react-native-webview-js-context'
project(':react-native-webview-js-context').projectDir = new File(settingsDir, '../node_modules/react-native-webview-js-context/android')
  • android/app/build.gradle
dependencies {
	...
	compile project(':react-native-webview-js-context')
}
  • register module (in MainActivity.java)
...

import com.shaynesweeney.react_native_webview_js_context.RNWebViewJSContextPackage; // <--- IMPORT

public class MainActivity extends Activity implements DefaultHardwareBackBtnHandler {
	...

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mReactRootView = new ReactRootView(this);

        mReactInstanceManager = ReactInstanceManager.builder()
                .setApplication(getApplication())
                .setBundleAssetName("index.android.bundle")
                .setJSMainModuleName("index.android")
                .addPackage(new MainReactPackage())
                .addPackage(new RNWebViewJSContextPackage()) // <- ADD HERE
                .setUseDeveloperSupport(BuildConfig.DEBUG)
                .setInitialLifecycleState(LifecycleState.RESUMED)
                .build();

        mReactRootView.startReactApplication(mReactInstanceManager, "YourProject", null);

        setContentView(mReactRootView);
    }
}

About

Utilize the JavaScript VM running inside an iOS UIWebView to exploit libraries targeting the DOM (e.g. Google Charts)

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published