---
# System prepended metadata

title: The Mobile Modernization Strategy PoC
tags: [CircusStreet]

---

---
tags: CircusStreet
---
# The Mobile Modernization Strategy PoC

[toc]

## Project structure

In this PoC the `react-native` application is initialized (and located) inside the `mobile.circusstreet.com` repository on the top level as below:

```
mobile.circusstreet.com
- ...
- cordova
- htdocs
- react-native <- here
  - mycs
- ...
```

### Assets

#### iOS

Files that will be used inside react-native app as the inner application must be "dragged and dropped" via xCode into the `cordova` directory. That's way the xCode will link that files in the `react-native/mycs/ios/mycs.xcodeproj/project.pbxproj` file as something like this:
```
  846EB90A239536FE00172915 /* cordova */ = {
    isa = PBXGroup;
	children = (
	  84C33A1B2397C14000047EB3 /* index2.html */,
	  84C33A192397C13A00047EB3 /* css */,
	  84C33A172397C13200047EB3 /* js */,
	);
	path = cordova;
	sourceTree = "<group>";
  };
```
Therefore, used files don't need to be copied or moved.

#### Android

On the other hand, for the Android, files must be copied into the specific assets directory: `react-native/mycs/android/app/src/main/assets`.

## Wrapper

We use the `WebView` component from the `react-native-webview` library (https://github.com/react-native-community/react-native-webview) as the `WebView` from `react-native` is currently deprecated.

The uri of the inner App depends on platform:

```
const uri = (Platform.OS === 'android' ? 'file:///android_asset/' : '') + 'index2.html';
```

That is used in the `WebView` component:
```javascript
<WebView
  ...
  source={{uri}}
  javaScriptEnabled={true}
  allowFileAccess={true}
  originWhitelist={['*']}
/>
```

## Comunication

We use `PostMessage` API for the comunication between the react-native and inner app (current mycs).

### React Native -> MYCS

React Native: ```App.js```:

```javascript
<Button
  title="Increase"
  onPress={() => {
    this.webview.postMessage(
      JSON.stringify({
        message: 'MSG_FROM_REACT_NATIVE',
        data: {
          counter: this.state.counter + 1,
        },
      }),
    );
    this.increase(); // Update local state
  }}
/>
```

Inner App: ```app.js```:
```javascript
function messageHandler(rawData) {
  var data = JSON.parse(rawData.data);
  if (data.message === "MSG_FROM_REACT_NATIVE") {
    ...
  }
}

document.addEventListener("message", messageHandler);
...
```

### MYCS -> React Native

Inner App: ```app.js```:
```javascript
window.ReactNativeWebView.postMessage(
  JSON.stringify({
    message: "MSG_FROM_WEBVIEW",
    data: {
      counter: counter
    }
  })
);
```

Important! Use `window.ReactNativeWebView.postMessage` instead of standard `window.postMessage` API.

React Native: ```App.js```:

```javascript
const msgHandler = e => {
  const data = JSON.parse(e.nativeEvent.data);
  if (data.message === 'MSG_FROM_WEBVIEW') {
    this.setState({
      counter: data.data.counter,
    });
  }
};
...
<WebView
  ...
  onMessage={msgHandler}
/>
```

### Initial values

We can also send initial values to the inner app using the `injectedJavaScript` property of `WebView`:

```javascript
<WebView
  ...
  injectedJavaScript={`
    counter = ${this.state.counter}; 
    init();
  `}
/>
```

## Debugging

The React Native application can be debugged in easy way, using for example React Native Debugger (https://github.com/jhen0409/react-native-debugger). Debugging the inner application can be done as described below.

### iOS

You can debug the inner application via Safari Dev Tools, in the `Develop` menu. If you can't see that menu, you need to enable it first, see https://support.apple.com/en-gb/guide/safari/sfri20948/mac.


### Android

To be able to debug the inner application you should modify the`MyApplication.java` file as below:

```java
...
import android.webkit.WebView;
...
  public void onCreate() {
    ...
    WebView.setWebContentsDebuggingEnabled(true);
  }
```

Then you will be able to run the inspector via Google Chrome Dev Tools (remote devices section)