I'm working on an enterprise React Native project that targets customers' backend installed on-premises. Some customers are slower than others to upgrade the backend and we still need to support them.
Instead of using feature flags, would it be possible to set up a workflow so that:
each release branch gets bundled as (e.g. release-v1, release-v2, release-v3,...)
we configure the compatible app version on the backend
the React Native opens up, fetches the compatible app version number, and loads up the appropriate bundle
With git you can group different branches that hold different versions of your app:
ANDROID:
path: yourProject/android/app/build.gradle
search and change: "versionCode" and "versionName"
iOS:
Open xCode
Select app project
Go to "General"
Change "version"
If you need get app version from Javascript use "react-native-version-info":
https://www.npmjs.com/package/react-native-version-info
You could organise your codebase so that it is flexible for all the different 'flavours' of the app.
For example:
Main code branch (all your base code goes in here, shared functionality, etc..)
Branch v1 - the differences on top of your 'main' branch for this version
Branch v2 - as v1 but with specific changes for v2 users
Branch N - ...and so on
Then each Branch 1,2,N version of the app can have it's own bundle Id and be released as a separate app.
You have 1 codebase to work on. Updates can be made on main and trickled down to Branch N apps if needed.
Specific "Branch" updates can be made and pushed to the relevant code branch.
Related
I am working on building a modular React Native App for Enterprises in which it requires adding or remove packages as features or plugins (without updating the app). The following shall be a process
An enterprise user shall download and install a base mobile Android/iOS app (build in React Native) in a mobile handset
From the back-end, multiple packages or features (may defer with other enterprises) shall be configured for an enterprise
The multiple pre-built packages/modules shall be kept at a store at the backend
The enterprise user shall automatically get the packages as features in the mobile app using step 1 above, post step 2
I don't have any issue handling and building the backend and react native app. I am struggling that how dynamically adding/removing a package is possible in the existing base mobile app based on backend configuration.
If those packages/features are javascript only you can try codepush. This will allow to change the js bundle runtime. Check out this section: Dynamic Deployment Assignment
However if those packages require native implementation the only solution would be to split your code. This way you would need to ship every package in the apk, but the main bundle will contain only the code of the "base" app and the other code with the additional features would be loaded runtime. This will also bring a huge performance boost.
You can easily control which user sees what by conditionally rendering the screens by a role or whatever.
For code splitting you can check out these repos:
react-native-bundle-splitter or repack
Before i continue, let me let you know that i know the code to deply to a targeted build for codepush
appcenter codepush release-react -a aountName/appName -d Production -m --description "CommentHere" -t versionName
I have tried to figure this out on my own and i have not been able to.
I have several versions of my app which i have deploy using CodePush and everything works well but I started having fears of crashes when i installed new packages on the latest build.
This implies the current code base would have new native differences as compaird to the old version.
The question is how can i deploy my new build with new native codes
and packages present to an old version of my app which does not have those
native packages without running into several crashes from all the users using the old version of the app...
I ask this cos i have a feeling if i push the new build with the new changes in UI and native chnages to the old version of my app, the app old app would crash.
If a bug comes in for an old version, how do I fix it and deploy it
for the old version only? Bugs may be critical and not everyone will
have the latest version of the app Or, the bug may only exist on a old
version of the app.
I await your response.
Code push will not affect any native code written within the Android or the iOS projects of a React-Native application. If you read the documentations carefully, it specifically says that it does not change / modify / update the native portion of the app.
Why?
This is because of the way the CodePush mechanism works. In essence, CodePush only stores and triggers the update of the JS bundle of the React-Native application.
This is why we wrap only the JS main app instance with CodePush HOC (Higher Order Component). This is what's happening when you do:
CodePush(MyApp); //wrapping the js bundle at app-root
So, unfortunately in your case, if there are native codes involved, regardless of deployment to a new or old version of the app, it has to be a AppStore / Playstore driven deployment.
I am in need of advice of how to deal with something:
I have an app that will soon be published to App Store and Google Play, I would like to find a way to have a clone of this app with less features, this clone is meant to give a taste of the app for users and also for the salesman of the company to demonstrate it, also I would like to keep both apps installed in the same device, so in the case of the salesman, they could demonstrate with this "demo app" and also use the real app for their own purposes.
I know that I could just have a beta user group on TestFlight and Google Play but that would need me to register those users or give them a link to register as beta and would not be possible to have both apps installed.
I want to make this "demonstration app" to be downloadable from the stores, it would have different API calls from the real app, different icon, etc...
but I would like to avoid having to maintain and copying every change from the "production" app to the "demo" app.
The option I thought: create a branch and rename the app to the new signature, name, icons and so I will just have to always pull the diff from the origin/master branch and publish it on the stores, but it didn't worked, since xcode breaks the app and give me random errors when I do it.
I would appreciate to receive ideas and workarounds for this.
I can currently have four different versions of an app I developed installed. The solution for this really depends on your setup, but here is currently how I do it1. It is not the only way but it works for me and I find the issues that this setup causes so small that it doesn't really bother me.
iOS
The simplest solution for iOS is to have different Bundle Identifiers. This requires you to have different provisioning profiles. One provisioning profile for each development environment (if you want to put them on device for testing away from the development machine they need to be distribution profiles) and one profile for submission to the App Store.
Xcode has the ability to manage different environments with different provisioning profiles, however this caused me major issues when using CocoaPods and I ended up having to stop Xcode from managing it.
What I do now is I add a script to my workflow2 that forces the correct Bundle Identifier for the environment. If I want to build locally, I just manually change the Bundle Identifier and the provisioning profile (it only takes a second)
Android
For Android I use the built in flavors to manage the different environments. It is really easy to set up. in my app/build.gradle I added the following:
flavorDimensions "version"
productFlavors {
dev {
dimension "version"
applicationIdSuffix ".dev"
}
uat {
dimension "version"
applicationIdSuffix ".uat"
}
staging {
dimension "version"
applicationIdSuffix ".staging"
}
prod {
dimension "version"
applicationIdSuffix ".prod"
}
}
This adds a applicationIdSuffix to your builds which means that you can install multiple types on to your device. Using flavors is a really powerful way to manage your android applications. You can read more about using flavors here
One important point to note is that using flavors does change how you have to run your application.
Instead of using react-native run-android I now have to use react-native run-android --variant=devDebug.
When I want to build it instead of using ./gradlew assembleRelease, I have to use ./gradlew assembledevRelease (you have to change this for each flavor that you use)
There is also a small bug with react-native that when using the --variant flag it doesn't launch the app, so you just have to click on the icon on the device. But if you launch it from Android Studio it launches just fine.
So if you launch your application from Android Studio, or add the appropriate scripts to your package.json these issues melt away.
1 I don't use Expo for my production applications, only for prototyping, so these solutions are for full react-native applications with access to native code.
2 I use Bitrise to build my apps so it is easy to add bash scripts or similar to the build process.
If you want them to download the apps from stores then apps have to have different package/applicationIDs.
I've worked on a react native project recently and we actually handled staging and production apps in single branch. Although we didn't release staging app on play store, we were sharing using Google drive and since both app had different packages, it was possible to install both of them together.
To change the applicationId, you need to make changes in app's build.gradle file in Android. Simply add .demo or .anything at the end of your production applicationId. And also change your api end point and App name and icons if you'd like. So this becomes cumbersome doing manually after sometime because you have to change back and forth. So we wrote a shell script to make all these changes before building the apk.
We actually didn't need to install 2 versions on iPhone, so we didn't do anything about it. Also I'm not familiar with iOS development but I guess process will be somewhat similar.
Now we don't have to keep track of changes from one branch to another. Setup(Shell scripts) will take some but it will be worth it.
When I changed a library (like 'react-native-image-crop-picker') version on package.json and distribute it with code push in users app the version not changed.
They see older version of that library in app.
what should I do?
Code Push only works with JS code. It doesn't allow to push native binaries. In your case, you have to update app bundles in stores to update your native dependencies.
The CodePush plugin helps get product improvements in front of your end users instantly, by keeping your JavaScript and images synchronized with updates you release to the CodePush server.
Taken from Code Push docs.
Scenario
I have two apps that are identical except for some minor textual differences. Currently I have 2x projects and would like to condense them into one.
eg.
React Native Project
/ \
Xcode build 1 Xcode build 2
Another important caveat: App Signatures
I assume the App Stores recognize app uploads by some sort of archive/compilation signature, not by app name. This is why I'm wanting to do 2 separate xcode builds rather than 1 xcode build.
Question
Can a React Native project maintain 2 separate Xcode builds?
Running multiple builds off of the same application is a pretty common paradigm in iOS development, and this holds true for React Native as well.
The instructions here should get you well on the way to configuring multiple builds, with unique bundleIds (what the app store will use to recognize it as a unique application).
To test them out on your machine after configuring everything, you can use the following command as an example.
react-native run-ios --simulator 'iPhone X' --scheme 'YOUR_SCHEME' --configuration 'YOUR_NEW_CONFIGURATION'
I would start by just duplicating your Release config and renaming it, just to make sure that it runs fine on your machine before you start playing around with the configuration.