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.
Related
I know it might be very basic question. But I am very new and got a codebase with only android support. I need to add iOS for it. Please help me
As you're aiming to build a cross-platform app, React Native provides two ways to organize the code and seperate it by platform: platform module or platform-specific file extensions.
As you already have an Android app, I assume it has more complexity so you might want to split the code out into separate files.
You say you have an Android app but i don't thing that at any point you specified that the app should only build for Android (you can review in the package and the project configuration). So, the following command should be enough:
react-native run-ios
If you created your react native app from a template (e.g. using npx react-native init ProjectName), it already provides an ios and android folder, so it already supports it. If the file is not there, you could follow the instructions that #Rajan shared above to recreate the ios folder.
If your problem is running the iOS application using npm run ios, and its failing to build or the javascript throws an error, the quickest thing to try is cd ios, then pod install. If this does not work, it might be because you have additional dependencies you have installed, which require specific instructions and configuration to be done in the ios folder. This is library dependent, if needed, will be explained in depth in the README.md of the library. For example, react-native-firebase has a lot of steps, and is different to the android configuration.
Sometimes it is helpful to modify these configurations in XCode instead of editing the files manually (e.g. plist, xml, xproj). You can open xcode quickly using xed ios when in the root project folder.
Note: As usual, remember to have the libraries available in the node_modules folder, npm install.
In the future, you might choose to run different javascript code based on the platform (platform-specific code). React native allows that by using file.android.js and file.ios.js. However, your IDE is likely to struggle with the 2 files, and won't be as helpful compared to file.js. Alternatively, you can import Platform and conditionally check at runtime, what your platform is.
If you used Expo, you don't have access to the native code, but will already support iOS.
I have installed a react-native app built with expo cli from playstore, I am migrating to react-native cli. I am not able to install the react-native cli build(signed with the same android key) over the existing expo build. I am getting the following error
App not installed, the package conflicts with an existing package by
same name
any solution will be greatly appreciated
Expo and React-native cli are two different things , as i am too implementing both in single app , after that my app start crashing so you can only use one cli at a moment .
here are the difference and merits -demerits of both .
React Native init:
Merits:
You can add native modules written in Java/Objective-C (probably the only but the strongest one)
Demerits:
Needs Android Studio and X Code to run the projects
You can't develop for iOS without having a mac
Device has to be connected via USB to use it for testing
Fonts need to be imported manually in X Code
If you want to share the app you need to send the whole .apk / .ipa file
Does not provide JS APIs out of the box, e.g. Push-Notifications, Asset Manager, they need to be manually installed and linked with npm for example
Setting up a working project properly (including device configuration) is rather complicated and can take time
Expo:
Merits:
Setting up a project is easy and can be done in minutes
You (and other people) can open the project while you're working on it
Sharing the app is easy (via QR-code or link), you don't have to send the whole .apk or .IPA file
No build necessary to run the app
Integrates some basic libraries in a standard project (Push Notifications, Asset Manager,...)
You can eject it to Expo Kit and integrate native code continuing using some of the Expo features, but not all of them
Expo can build .apk and .ipa files (distribution to stores possible with Expo)
Demerits:
You can't add native modules (probably a game changer for some)
You can't use libraries that use native code in Objective-C/Java
The standard Hello World app is about 25MB big (because of the integrated libraries)
If you want to use: Face Detector, Ar Kit o Payments you need to eject it to Expo Kit
Ejecting it to Expo Kit has a trade-off of features of Expo, e.g. you cannot share via QR code
When ejecting to Expo Kit you are limited to the react native version that is supported by Expo Kit at that point in time
Debugging in Expo Kit (with native modules) is a lot more complicated, since it mixes two languages and different libraries (no official Expo support anymore)
And you can use any one which satisfies your applications requirement.
Hope it will make you understand the difference between these two Clis.
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.
I'm wanting to setup a proper deployment pipeline for our apps using React Native so that for example in iOS we have a:
Debug version for the development team
Internal Release UAT version
Release Production version
Now with the default setup, using the Schema "Debug" and "Release" allows for 1 and 3 but how can I add another for point 2 which will still make React Native build as a release?
We're using Code-Push and I want to have some separate config for point 2 and 3 which is why I am asking this question. Same will go for Android too.
recently started working with react native and project requires for apps to be build on server. So the theory is that app could be build on request, which means something, lets call this something react native compiler, needs to be on some server which allows me to do this.
For example, this is the location where is react native compiler is "http://example.com/compile", and you have some settings options and button "compile" on that site, and when you click on button, application compiler starts, and after x seconds android and iphone apps are ready to be downloaded. Is this possible?
It is surely possible, although it might be complicated to implement, it all boils down to the level of complexity that you want to achieve (just a build system, an online IDE...).
Each React Native application consists of the JavaScript code and one Android and iOS projects (you can include more platforms through 3rd party efforts, but let's keep it simple). Both the iOS and Android SDKs offer command-line tools for the building functionality. In the case of iOS you have the xcrun command and in Android, the project includes some gradle commands that you can execute. So in general, what you have to do is just execute these commands via your backend when an user requests it.
Essentially what you need is the same kind of setup a Continuous Integration server would, but instead of triggering a build whenever changes are made, the server should build the app on demand, and then send back the result of the compilation to the user. You can read more about CI for React Native here and here, for instance.