How to configure iOS apps for multiple environments (Dev, QA, Prod)
In this blog, we are going to learn something related to project scheme configurations. As we proceed with a project we have to manage environments (Development, QA, Staging, Production) and when we use different environments there are different server URLs, icons, Plist files, and configurations for each environment. While creating a project, a scheme is created by default and still is not configured as per our needs, It’s tough to manage things while sharing builds in a bottleneck situation. So we will create schemes, that can manage all these hassles at the time of sharing build for a particular environment
Now there comes a question, how to manage configuration automatically by switching schemes (Environment)?
Starting with Creating Schemes and their Configurations
Now, Setup a Project :
Open XCode, select Create New Project > Apps > add a name.
Create schemes and Add configuration :
Here, we need to understand that when an Xcode scheme is created it creates two different build Configurations, i.e. Debug and Release, Now here if we need to, we can configure these as per our requirement for a particular environment.
Step 1: To add our build configurations, Select Project from the Project Navigator Pane from the left, and Select Info from the options
Step 2: Now in Configuration, Add your configuration for the environments (like- Development, QA, Staging, Production etc.)
Click on the + icon showing Duplicate Debug Configuration, to add multiple configurations repeat these steps as needed. Double click on the Debug and you can rename it Like Development, QA, Staging and Production like the image below.
![Default Configuration](https://www.tothenew.com/blog/wp-ttn-blog/uploads/2024/07/Screenshot-2024-07-28-at-9.59.18 PM-1024x189.png)
Default Configuration
![Create Configuration for all Environment](https://www.tothenew.com/blog/wp-ttn-blog/uploads/2024/07/Screenshot-2024-07-28-at-10.03.32 PM-1024x310.png)
Create Configuration for all Environment
![Add Duplicate Configuration for Environment](https://www.tothenew.com/blog/wp-ttn-blog/uploads/2024/07/Screenshot-2024-07-28-at-10.07.24 PM.png)
Add Duplicate Configuration for Environment
![Add and update scheme configuration](https://www.tothenew.com/blog/wp-ttn-blog/uploads/2024/07/Screenshot-2024-07-28-at-10.44.02 PM-900x1024.png)
Add and update scheme configuration
Add the configuration file for each scheme, In this file, Add all dependencies related to particular environments (like ServerURL, icons and other configurations) as required.
![Showing Configuration file](https://www.tothenew.com/blog/wp-ttn-blog/uploads/2024/07/Screenshot-2024-07-17-at-11.48.21 AM-1024x446.png)
Showing Development Configuration file
![Access Environment variables](https://www.tothenew.com/blog/wp-ttn-blog/uploads/2024/07/Screenshot-2024-07-17-at-12.09.16 PM-2-1024x179.png)
Access Environment variables
Step 3: For the Development Scheme configuration file content, keys are added to the screen above, to fetch the environment variable when needed. Showing the steps for the Development Environment, repeated it for each environment.
Step 4: Link your configuration file and pod configuration file with each created environment. After adding all the settings it will look something like this
![Link configuration file for environment](https://www.tothenew.com/blog/wp-ttn-blog/uploads/2024/07/Screenshot-2024-07-17-at-11.59.26 AM-2-1024x699.png)
Link configuration file for environment
![Link Pod configuration file for selected scheme](https://www.tothenew.com/blog/wp-ttn-blog/uploads/2024/07/Screenshot-2024-07-17-at-11.59.38 AM-2-1024x666.png)
Link Pod configuration file for the selected scheme
![Showing environment configuration file linked with selected schemes](https://www.tothenew.com/blog/wp-ttn-blog/uploads/2024/07/Screenshot-2024-07-17-at-12.03.00 PM-2-1024x693.png)
Showing environment configuration file linked with selected schemes
There is one more trick to do that, for Step 4: Just follow the process which is shown in the image below:
![Add path of pod xcconfig here in environment config file](https://www.tothenew.com/blog/wp-ttn-blog/uploads/2024/08/Screenshot-2024-08-02-at-11.39.59 PM.png)
Add the path of pod .xcconfig here in the environment config file
![select environment configuration file as per configuration.](https://www.tothenew.com/blog/wp-ttn-blog/uploads/2024/08/Screenshot-2024-08-02-at-11.36.40 PM.png)
Select the environment configuration file as per configuration.
Now all the schemes with their respective environment are linked. There is one last step to working on this configuration properly.
Step 5: Select any scheme -> edit scheme -> and set your desired configuration.
![Final Step for Environment Scheme Configuration](https://www.tothenew.com/blog/wp-ttn-blog/uploads/2024/07/Screenshot-2024-07-17-at-12.07.49 PM-1024x543.png)
The final step to achieving Environment Scheme configuration
The project is ready to run for multiple Schemes and the configuration setup is completed:
Select scheme from drop down and run — the environment will be automatically configured as required
var environment: String { let env = Bundle.main.infoDictionary!["ENVIRONMENT"] as? String ?? "" return env }
var hostURL: String { let env = Bundle.main.infoDictionary!["HOST_URI"] as? String ?? "" return env }
Firebase Crashlytics for Multiple Environment
Why do we need Multi-Environment Configuration for Firebase Crashlytics?
Using multi-environment configuration for Firebase Crashlytics allows you to manage and separate the data and settings for different stages of your app development process, such as development, staging, and production. Here are several reasons why this is beneficial:
- Environment Separation:
By using different configurations for each environment, you can keep your crash reports organized. This helps in distinguishing crashes occurring in the development phase from those in production. - Focused Debugging:
Crashes in the development environment can be addressed without interference from production data. This allows for more focused debugging and testing. - Data Privacy and Security:
Keeping production data separate ensures that sensitive user data and logs from the production environment are not accessible in development or staging environments, enhancing security and privacy. - Release Management:
Different configurations help in managing releases and hotfixes more effectively. You can test new features and fixes in staging before deploying them to production. - Performance Optimization:
It allows for performance monitoring and crash reporting to be tailored to each environment’s specific needs, optimizing resource usage and ensuring that performance metrics are accurate for each stage of the app lifecycle. - Compliance and Monitoring:
Different environments can have different compliance requirements. Multi-environment configurations help in meeting these requirements by ensuring that only relevant data is collected and monitored.
Overall, the multi-environment configuration for Firebase Crashlytics provides a structured and efficient way to manage, monitor, and respond to crashes throughout the app development lifecycle.
To create a separate Firebase environment
Step 1: Create/add a project
Step 2: Add Project with a bundle ID you have for each environment
Step 3: Now download GoogleService-info.plist for each environment
Make a folder in a project and name it, as I have shown a folder named Firebase, and add a folder for each environment and name it as schemes (Development, QA, Staging, Production). These folders will contain GoogleService-info.plist for each environment downloaded from the Firebase console as shown
Make sure for all the GoogleService-info.plist in every environment folder -> the Target Membership is unchecked because these will be handled from a script
Step 4: Now go to Project and select Targets -> Go to Build Phases -> click on + icon here -> Click New Run Script Phase
Add these script codes to your New Run Script Phase Gist link please click here
Build now -> On successful building of code.
Conclusion:
Implementing multiple configurations is often useful in the App development life cycle as it enables the developer to develop, integrate, test, and deploy the App individually for every environment resulting in better tracking of analytics, crashes, and environment-related data. Make sure the Firebase Crashlytics Configuration is implemented properly, to re-evaluate use the following points:
1. Verify Configurations:
Confirm that each environment has its own Firebase App/Project and configuration file (e.g. GoogleService-Info.plist for iOS). Ensure that the correct configuration file is included in the build for each environment.
2. Test Integration:
Trigger a crash in each environment to ensure Crashlytics is correctly logging crashes. This can be done by adding a test crash code snippet (fatalError()). Verify that the crash reports appear in the Firebase Console under the desired app/project.
3. Check Console Data:
Go to the Firebase Console to confirm that crashes are logged in the correct environments.
Note: You can access the complete code at GitHub.
Sample code: https://github.com/Vibhashkumar2022/ME-FirebaseConfigurationApp