react-native : communicate between react-native JS and WebView component

APIs:

window.postMessage in WebView, post a message to react-native JS.
onMessage callback in react-native JS, receive a message from WebView.
injectjavascript, Function that accepts a string that will be passed to the WebView and executed immediately as JavaScript.
injectedjavascript, Set this to provide JavaScript that will be injected into the web page when the view loads.
onMessage
A function that is invoked when the webview calls window.postMessage. Setting this property will inject a postMessage global into your webview, but will still call pre-existing values of postMessage.
window.postMessage accepts one argument, data, which will be available on the event object, event.nativeEvent.data.

data must be a string.

Sample code

import React, { Component } from 'react';
import {
  Button,
  Platform,
  StyleSheet,
  Text,
  View,
  WebView,
} from 'react-native';

var WEBVIEW_REF = 'webview';

export default class App extends Component<{}> {
  constructor(props) {
    super(props);
    this.onWebViewMessage = this.onWebViewMessage.bind(this);
    this.onShare = this.onShare.bind(this);
  }

  onWebViewMessage(event) {
    console.warn(event.nativeEvent.data);
    let msg;
    try {
      msg = JSON.parse(event.nativeEvent.data);
    } catch (err) {
      console.warn(err);
      return;
    }
    console.log(msg);
  }

  onShare() {
    var fetchAbstractJS = "(" + this.fetchAbstract.toString() + "());";
    console.log(fetchAbstractJS);
    this.refs[WEBVIEW_REF].injectJavaScript(fetchAbstractJS);
  }

  // function called in WebView via injectJavaScript
  fetchAbstract() {
    try {
      var title = document.querySelector('head title').innerText;
      var desc = document.querySelector('p').innerText;
      var imgurl = document.querySelector('p img').src;
      // post Message to react-native JS
      window.postMessage(JSON.stringify({'id' : 'ABSTRACT_FETCHED', 'url' : window.location.href, 'title' : title, 'desc' : desc, 'imgurl' : imgurl}), "*");
    } catch (err) {
      console.warn(err);
      return;
    }
  }

  render() {
    return (
    <View style={{flex:1}}>
      <WebView
        ref={WEBVIEW_REF}
        style={{flex:1}}
        onMessage={this.onWebViewMessage}
        source={{uri: 'https://manna.errong.win/let-s-growing-up-in-jesus/'}}
      />
      <Button
        onPress={this.onShare}
        title="Share"
        color="#841584"
        accessibilityLabel="Social Share"
      />
    </View>
    );
  }
}

react-native log-android

log-android

Refer

https://facebook.github.io/react-native/docs/webview.html#onmessage
https://facebook.github.io/react-native/docs/webview.html#injectjavascript
https://facebook.github.io/react-native/docs/webview.html#injectedjavascript

Let's Growing up in Jesus

看你们学习的工夫,本该作师傅,谁知还得有人将 神圣言小学的开端另教导你们,并且成了那必须吃奶、不能吃干粮的人。 (希伯来书 5:12 和合本)
In fact, though by this time you ought to be teachers, you need someone to teach you the elementary truths of God's word all over again. You need milk, not solid food! (Hebrews 5:12 NIV)
凡只能吃奶的都不熟练仁义的道理,因为他是婴孩; (希伯来书 5:13 和合本)
Anyone who lives on milk, being still an infant, is not acquainted with the teaching about righteousness. (Hebrews 5:13 NIV)
惟独长大成人的才能吃干粮;他们的心窍习练得通达,就能分辨好歹了。 (希伯来书 5:14 和合本)
But solid food is for the mature, who by constant use have trained themselves to distinguish good from evil. (Hebrews 5:14 NIV)


Photo by Milos Prelevic / Unsplash

react-native run-android : Command `run-android` unrecognized

F:\webrowser>react-native run-android
Command run-android unrecognized. Make sure that you have run npm install an
d that you are inside a react-native project.

F:\webrowser>npm install
added 781 packages in 338.768s

npm ERR! code UNABLE_TO_VERIFY_LEAF_SIGNATURE

F:\webrowser>npm install -g react-native-cli
npm ERR! code UNABLE_TO_VERIFY_LEAF_SIGNATURE
npm ERR! errno UNABLE_TO_VERIFY_LEAF_SIGNATURE
npm ERR! request to https://registry.npmjs.org/react-native-cli failed, reason:
unable to verify the first certificate

npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\Administrator\AppData\Roaming\npm-cache_logs\2018-01-11T1
6_55_54_266Z-debug.log

solution

npm config set strict-ssl false

F:\webrowser>npm install -g react-native-cli
C:\Users\Administrator\AppData\Roaming\npm\react-native -> C:\Users\Administrato
r\AppData\Roaming\npm\node_modules\react-native-cli\index.js

  • react-native-cli@2.0.1
    added 41 packages in 23.687s

git clone : SSL cert ificate problem: unable to get local issuer certificate

F:>git clone https://github.com/lengerrong/webrowser.git
Cloning into 'webrowser'...
fatal: unable to access 'https://github.com/lengerrong/webrowser.git/': SSL cert
ificate problem: unable to get local issuer certificate

F:>git config --global http.sslVerify false

F:>git clone https://github.com/lengerrong/webrowser.git
Cloning into 'webrowser'...
remote: Counting objects: 134, done.
remote: Compressing objects: 100% (90/90), done.
Receiving objects: 33% (45/134), 492.00 KiB | 17.00 KiB/s

Generate Signed android APK for react-native app

Refer:
https://facebook.github.io/react-native/docs/signed-apk-android.html

create your own key store file

https://errong.win/generate-keystore/

modifications

signed-apk

error INSTALL_FAILED_UPDATE_INCOMPATIBLE

https://errong.win/react-native-run-android-variant-release/

java.lang.NullPointerException (no error message)

When I set below values to true, I encountered NullPointerException.
so my reset them to false again.

+ def enableSeparateBuildPerCPUArchitecture = true + universalApk true  // If true, also generate a universal APK + def enableProguardInReleaseBuilds = true 

error can't delete/read lint-results-release-fatal.html

kill all java.exe via task manager

set up proxy for android emulator

c:\Users\lenger\AppData\Local\Android\Sdk\tools>emulator.exe -http-proxy ip:port -avd Nexus_5X_API_23

c:\Users\lenger\AppData\Local\Android\Sdk\tools>bin\avdmanager.bat list avd

    Name: Nexus_5X_API_23   Device: Nexus 5X (Google)     Path: C:\Users\lenger\.android\avd\Nexus_5X_API_23.avd   Target: Google APIs (Google Inc.)           Based on: Android 6.0 (Marshmallow) Tag/ABI: google_apis/x86_64     Skin: nexus_5x   Sdcard: 100M ---------     Name: Nexus_5X_API_23_2   Device: Nexus 5X (Google)     Path: C:\Users\lenger\.android\avd\Nexus_5X_API_23_2.avd   Target: Google APIs (Google Inc.)           Based on: Android 6.0 (Marshmallow) Tag/ABI: google_apis/armeabi-v7a     Skin: nexus_5x   Sdcard: 100M ---------     Name: Nexus_5X_API_27_x86   Device: Nexus 5X (Google)     Path: C:\Users\lenger\.android\avd\Nexus_5X_API_27_x86.avd   Target: Google APIs (Google Inc.)           Based on: Android API 27 Tag/ABI: google_apis/x86     Skin: nexus_5x   Sdcard: 800M Snapshot: no 

fixed: embedded-redis: Unable to run on macOS Sonoma

Issue you might see below error while trying to run embedded-redis for your testing on your macOS after you upgrade to Sonoma. java.la...