Configurations and Code, a way to separate them (iOS)

David Martinez
5 min readJan 6, 2022

--

It is a common practise that web developers have more than one environment to deploy their webservices and you need, into your app, configure the differents hosts based on which environment you are currently working.

https://sandbox.myhost.com
https://production.myhost.com

In this scenario, one of the best practises of software development is separate the configuration from the code due to the code is the same in all you environments (production, development, …) but your configurations not.

This article explain an easy way (from scratch) to use xcconfig files to build and read these configurations and use it to multiple environments.

Before we start

At first, we start enumerating all the components that we need to create or modify to reach our goal:

  1. Create an xcconfig file for each configuration (eg: Development and Release) with the keys and values that we want to read.
  2. Update main Info.plist file to connect xcconfig file with the code.
  3. Create a class that read these configurations.

Let’s start

At first step, we add the two xcconfig files that we will use into our project (new or existing one). By default, Apple create two environments, Debug and Release, so we will create a xcconfig file separately for each one

Xcode default configuration

So, click into File > New > File (or use cmd+N shortcut) and, in the selection dialog, choose Configuration Settings File

Select Configuration Settings File

and give it a human-readable name that refers the environment that you want link to (useful in the future). In our example we use Development.xcconfig

Repeat this step to create Release.xcconfig for the production environment.

Once this files are created we must link them to the project configuration, so, click into your project settings and open the “Info” tab.

Project Configurations

Once you’re there, expand the Debug and Release configurations, and, in the project, link the configuration file you want to link to each one.

Link xcconfig file with a configuration

Development, for the first one (Debug configuration), Release to the second one (Release configuration).

One more thing to finish the step one. Include a variable that could be read by your app in both xcconfig files, for example API_URL with different values for each one.

Include a configuration variable

Nice!, step two, open your application Info.plist file and include a new variable following this specification:

  • The property name must match with the name you gave before into xcconfig file (API_URL for this example)
  • The type must be related with the type you gave into xcconfig file (String for this example)
  • The value must use variable notation with the same name you gave into xcconfig file ($(API_URL) for this example)

wow! this looks great, let’s finish adding a simple class that read our Info.plist file and some helpers to use them. Remember you could implement this part following your heart, there are a lot of ways to implement this :).

Note: There are some problems involves the read for special characters. The sequence // is considered a comment, and if you scape it using \/\/ when you read the variable you need to replace \/ with /. That’s the reason why we include the https:// directly into the code.

And … that’s all you need!, here is an example that read the api value.

This code will print into the screen the value of the url read from xcconfig file.

If you want to test if it works remember that you can change the configuration when you run your application clicking on your scheme > Edit scheme > Run and changing the Build configuration from Debug to Release, if you do this and relaunch you will see the urls from the related xcconfig file.

Change build configuration

Update I — Teach me more things!

As @jbstevenard include in the comments, we could use the xcconfig files to modify the Build Settings of our project in a simple way (like Cocoapods configure its own Pods project).

Before build our example let’s take a look into our project build settings page in the following screenshots (Click Project -> Build Settings tab).

This file contains all the set of properties that involves compilation, build locations, schemes, code generation, our custom xcconfig variables … for each environment we are defined.

Xcode — Build settings (custom variables below)

In Levels view, we could see, by column, the value defined for any variable and how it will be finally Resolved (first column). In the bibliography you could read a raywenderlich tutorial that explain more in detail this information.

Well, all these variables have an id that you could see if open the project with another text editor.

Build Settings — Debug environment

With this information, we will try change de swift version (id: SWIFT_VERSION) of our project for each environment. For example, for Debug we will use 4.2 and for Release 5.0.

  • Open the Development.xcconfig and include `SWIFT_VERSION = 4.2`
  • Open the Release.xcconfig and include `SWIFT_VERSION = 5.0`

And it’s done! Xcode automatically checks if there is a key in the linked xcconfig file for the environment and update it as you could see in the following screenshot.

SWIFT_VERSION configurated by xcconfig file

Here is the github with this example.

Happy new year! Happy coding 🎉!

Thanks to Adrián Ruiz and Eva Gonzalez.

Bibliography

--

--