Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically compiling and running a react-native app inside another

I need to create a mobile app that contains other apps and can run them. It is basically like an "app center" which have a list of apps (that we publish on our server) and the user can open one of them which lead to the app being opened.

Think about Expo's app, the user can scan the QR code of his app and it will be automatically compiled and opened, this is close to the feature I want.

The apps that can be opened are created using react-native and stored inside GIT repositories in Gitlab.

Consider the following example:

Sketch image of the desired app

By launching the app, which we call App Center, a list of apps will be shown. When the user click on one of them, it will be opened internally.


Here's a "more technical" example:

  1. The App Center is launched
  2. The app will get the list of apps to show from the server, for example by calling https://myappcenterserver.com/all-apps
  3. They will be displayed and it will listens to press events
  4. Let's say the user pressed an app called 1st App (it's a very bad name I know) which have AP123 as an ID
  5. Our app will send a request to the server by calling https://myappcenterserver.com/app/AP123, this will either returns the react-native source code of the app from the Git repository
  6. Our app center will compile the code from step 5 and run it

So according to you which is the best approach I should consider.

Should I use a remote code solution such as CodePush or react-native-dynamic-bundle ? Do they fit in this context ?

like image 451
Atef Avatar asked Jul 29 '19 10:07

Atef


1 Answers

This is possible partially via CodePush:

  • Create multiple CodePush environments for different apps. (APP1 APP2 etc)
  • When you boot up your app, make an API call to fetch app list and corresponding code push deployment key.
  • on button click codepush.sync(deployment_key) → restart app and then jump directly to your app (maybe store the app name in AsyncStorage and jump directly to it via navigation)

However, the caveat might be a dealbreaker:

  • your app will be reloaded after selecting the app
  • major react version upgrade(native java/oc changes) would require store release as it can't be handled over JS (might not be dealbreaker)

There is also a better way:

  • create one single container app and one CodePush environment
  • have a central configuration like [{app:"A1", version: 2.0.0}, {app: "A2", version: 1.2.0}]
  • all other apps A1, A2, A3 expose objects which can be exposed as plugin to container app.
  • Your CI handles building the app dynamically form the multiple repository (or better - multiple npm packages generated by different repos) and pushes the JS to CodePush server.
  • it adds all apps from the configuration (bash script to yarn add A1, yarn add a2, yarn add a3) to the container,
  • your app reads the configuration and loads the A1 A2 etc.
  • CD creates new CodePush releases.

This is repeated whenever the central configuration changes (say after A1 publishes npm package they update the central configuration).

It solves the problem of restart as you've all bundles build in to one.

CodePush: https://docs.microsoft.com/en-us/appcenter/distribution/codepush/react-native#dynamic-deployment-assignment

Or go you might want to through expo's code https://github.com/expo/expo/blob/d56076241cef55b0a93a5c0bb8dc690270e42dcb/home/screens/QRCodeScreen.android.js#L89

like image 61
Sengupta Amit Avatar answered Oct 17 '22 08:10

Sengupta Amit