Many times is useful to have the same application installed multiple times but pointing to a different environment. There are many use cases for this such as:
- Debug application in a production environment without replacing the development installed version.
- Being able to use the production application and also development application to test new features on the same device.
- Compare if bugs are in development version but not in current production version or vice-versa.
Usually, we have at least two environments: development and production. So in order to be able to test both on the same device, we need to be able to install the same application pointing to each environment. In this article, I will show you a step by step guide of doing just that by using the solution configurations.
Let’s Start
1-Adding new configurations
Common project
First, we are going to create two new configurations in the application:
- Release-Dev config: Thig config will set the application to a development environment and will allow us to test new features and bug fixes before we release to production.
- Debug-Prod config: This config will set the application to a production environment and will allow us to debug our app in production.
1- Open the configuration menu in the common project by doing right-click on the project and clicking on Options.
2-On the Build section go to Configurations
We will start with the Release-Dev configuration.
3-Copy the Release configuration (Select current Release configuration and click on the copy) and name it Release-Dev (or any name you prefer).
4-Copy the Debug configuration (Select current Debug configuration and click on the copy) and name it Debug-Prod (or any name you prefer).
Now we have two additional configs.
Android project
Do the same steps in the Android project to add these two new configurations.
iOS project
Do the same steps in the iOS project but also consider to specify the platform when adding a new configuration which could be iPhone/ iPhoneSimulator, make sure to create one for each.
The result will look like this:
Project Solution
Do the same steps in the solution (Doing right-click in the solution). Check here we have 2 configurations more than iOS, copy and create a new configuration for each one.
Result:
Click on ok, then open the Configurations options again, click on Configuration Mappings.
Now we are going to associate the new solution configurations to the configurations created in Common/Android/iOS. Choose Debug-Prod, associate it to each one and do the same for each platform.
Do the same using Release-Dev configuration associate it to each one, and also in each platform.
2-Creating a new compilation symbol
The next step is to create a new compilation symbol so we can use it in the code to set the environment. This new symbol will be only added to the development configurations because it will point to the development environment. So we will add it just to Debug and Release-Dev.
Common project
1-Go to the Compiler section, in configuration select Debug and in the Define Symbols add a new symbol called DEV.
2-Do the same previous step but selecting Release-Dev in Configuration.
Now we can use the new symbol in our code:
As the representation of pointing to a specific environment, we will just set a label text to DEV/PROD and change the background depending on which environment is pointing to based on the selected configuration.
Android project
Do the same steps we did for the common project. Add it to the Release-Dev and Debug configurations
iOS project
We won’t be using the symbol on iOS project, so isn’t necessary to do the steps above.
3-Configure Android project
1- Copy the AndroidManifest.xml file then paste and rename it to AndroidManifestDev.xml
Result:
2- Edit the new AndroidManifestDev.xml file with development environment values
- package – the development package name (it must be different from the one in the original AndroidManifest.xml)
- android:label – the development app name
- android:icon – the development app name
3-In the MainActivity we will compare by using the created DEV symbol to change the application icon/name based on the configuration selected.
4-In the Android .csproj file by default it uses AndroidManifest.xml so for the Debug and Release-Dev configurations we are going to change it to use AndroidManifestDev.xml instead by adding the following to those configurations:
<AndroidManifest>Properties\AndroidManifestDev.xml</AndroidManifest>
Example:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release-Dev|AnyCPU' ">
....<AndroidManifest>Properties\AndroidManifestDev.xml</AndroidManifest>
....
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
....<AndroidManifest>Properties\AndroidManifestDev.xml</AndroidManifest>
....
</PropertyGroup>
The result will look like this.
4-Configure iOS project
1- Copy the Info.plist file then paste and rename it to Info-Dev.plist
Result:
2- Go to the Asset file, create a new set AppIcon and name it AppIconDev.
The result will look like this:
Add your development version icons in the AppIconDev asset.
3- Go to the Info-Dev.plist file and change:
- XSAppIconAssets to use the new icon asset for the development version.
- CFBundleDisplayName and CFBundleName to set the development version app name
- CFBundleIdentifier to set the development version bundle identifier (it must be different from the one in the original Info.plist)
4- Open the iOS .csproj file and check where it includes the Info.plist, then add there a new condition to specify when to include.
- Info.plist: Add this condition Condition=” ‘$(Configuration)|$(Platform)’ == ‘Release|iPhone’ Or ‘$(Configuration)|$(Platform)’ == ‘Debug-Prod|iPhone’ Or ‘$(Configuration)|$(Platform)’ == ‘Debug-Prod|iPhoneSimulator’ ” so that is only included in production environments configurations.
- Info-Dev.plist: Add this condition Condition=” ‘$(Configuration)|$(Platform)’ != ‘Release|iPhone’ And ‘$(Configuration)|$(Platform)’ != ‘Debug-Prod|iPhone’ And ‘$(Configuration)|$(Platform)’ != ‘Debug-Prod|iPhoneSimulator’ ” to include it only in environments different to production. Also here use LogicalName so the application can associate Info-Dev.plist as the application Info.plist.
The result will look like this.
5-Test it
Run the project in each config to test it:
You can check the full sample project here.
References
https://blog.verslu.is/xamarin/different-app-icons-for-different-configurations-in-xamarin/
https://devblogs.microsoft.com/xamarin/demystifying-build-configurations/
Happy multi-environment app!