Publishing an application not an easy task there are many phases under which the app needs to go. Such as development, testing, etc. Out of that, testing the application is a major task to make the application stable. While testing it we actually maintain different servers(staging, production, development, etc) that we only use while developing and in testing. But when times come where the client wants the final build where we have to change all setup of the server URL and other stuff which we using while testing to Production set. During this time developers have to do it manually by changing the URL. What if we got a chance where we don’t need to do this all manual work. Yes!, You can do it that is what we are going to discuss it here.
There are multiple ways/approaches to provide a build for testing and for production.
First aproach is manually changing the code
This is the easiest way of doing this where we are actually using a global variable to point the server/current environment. The environment could be set using enum swift or we can actually uncomment the current environment and commenting on the unuseful environment in the app delegate. But this leads to some manual error as sometimes the developer forgot to change the environment. Also, some time tested don’t know which build he is testing like is it staging or production, where he needs to confirm it from the developer, and the developer need to confirm it by seeing the code.
Second is build scheme and build configuration
In this approach, Xcode provides us a pre-included solution for this. In this solution, we can read words like Target, build scheme, and build configuration. So we will discuss these things before diving into it.
Each project has one or more target where it contains a list of classes, assets, etc. Target is another application with an enhanced feature of the current app or we can say the same application with different names, bundle id. Or we can say a copy of the project which we are providing it to other clients.
A build scheme is a collection of targets to build an application, it is a configuration to use when building, and a collection of tests to execute.
Is a kind of setting that can be applied to target.
Build Configuration and Build Scheme
These two things we must have to use when we are using the different-different environments. Let’s start setting up the environment. The following are the basic steps we need to perform.
- Create a single view application.
- Create a different build configuration in the project editor.
- Create a different scheme for each build configuration.
- Create a .xconfig file.
1.Create a single view application
Create an app on how you are creating it normally. By default you can see the two build configuration with Debug and Release.
2.Create different build configurations in the project editor.
As you have seen two build configurations created now you can add it by clicking the plus button and selecting duplicate Debug configuration or Duplicate Release configuration as per your choice.
Let’s consider we have three build configuration like Dev, QA, Production. we are creating three configurations and one scheme for each. You can actually rename current Debug and Release configuration like Dev and Production by double-clicking it. And then you can add one more for QA by clicking on plus button.
3.Create a different scheme for each build configuration.
Now click on the current scheme located at the top left corner. Click on that you can see a drop-down of Edit scheme, New scheme.
Select the Manage scheme where we are creating a different-different scheme for different-different build configurations.
Here rename the current scheme name EnvironmentSetDemo to DebugDemo. You can create the other two schemes by clicking on the plus button. I have created the other two schemes like PriductionDemo and QADemo.
Now try to edit each scheme and change the build configuration of each scheme. You are changing the build configuration for each scheme from build configuration. I am editing the Debug scheme’s build configuration to debug. But while editing you can see multiple options and you will get confused for which we need to change the configuration. So my suggestion is a change for the Run and Archive option. As we are running and archiving applications mostly. I am changing it to dev as DebugDemo is for dev environment.
You can change other configuration accordingly.
Until now you have done the setup for all environments. Now, how can I access this configuration for different-different setup? So for that, we need to create a build configuration file
4.Create .xconfig file
This file plays important role in the environment setup. From this file, we are actually fetching the values for each environment separately.
To create this file goto File->New File->Configuration Settings File.
Name it the same as the scheme name. Like DebugDemo, QADemo, ProductionDemo. In the end, your file structure looks like the following.
Keep in mind while creating this config file do not select any target.
Each of .xconfig file containg key-value pair. Where we are using the key info.plist
For example, I am using the key of ENDPOINT which points to different-different servers in each .xconfig file.
Now this configuration file’s setting is done. How can I use these URL's in the project. For that, you need to add key in info.plist. Where the key is anything and value should be the key(i.e ENDPOINT) in the config file. The key should be included in $(). Like in our case it should be $(ENDPOINT).
See following screen shot of info.plist where serverurl is key and its value is $(ENDPOINT)
Now we all are done with the initial setup now how can we use it in code? No worries here is the final thing we need to do to get access of the endpoint url
let url = Bundle.main.infoDictionary?[“serverurl”] as? String
Now you are ready to use all environments just by changing the scheme only. While uploading the build you have to just change the scheme and accordingly, you can submit build no need to do extra work.
Now we are clear to the basic setup of the environment but we can actually change the Name, App Icon, Bundle ID for each scheme. For that, you can do the following steps.
For changing you need goto Target->Build setting then search Product name. Then you can see each environment and name. Now you can change the name whatever you want. I have done it as DEV, PROD, QA.
For changing again you need goto Target->Build setting then search Bundle ID. Like before a set, you can see each environment and can change the bundle as you wish. In my case, I have just appended it with .dev, .QA, and .production
Make sure that in build configuration for each configuration we have selected the right configuration. Check the following screen-shot.
If the above way is your selection then only your config file gets read. Otherwise, It will return an empty value.
Using Xcode configuration files is an efficient and powerful solution for configuring different build settings. This is a good practice to get rid of manual work. I recommend you should always do these setup before starting any project which helps you to be a good developer.