---
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)