Managing iOS Configurations per Environment in Xcode 4

Posted on by in Development

Update 4/2014

I recommend using .xcconfig files for managing your configurations. Take a look at this post.

At Carbon Five we usually have 3 – 4 environments our iOS applications will run against: development, acceptance, staging and production. Often, the property values that are unique across environments are URLs to APIs that we are integrating with. There have been several approaches for managing different configurations per environment. Some have included conditional compilation or build-time file substitution. While all are valid approaches, I opted to use Xcode’s build configurations to manage configurations per environment. Here is how I did it:

Step 1: Modify Your Default PList File

Your default plist file is usually named ${PRODUCT_NAME}-Info.plist and is located beneath the “Supporting Files” group of your Xcode project. Add a new row/item of type String to the plist file and name it Configuration. Set the value to be ${CONFIGURATION}, the Xcode provided environment variable for the current build configuration.

Step 2: Create a Custom Environments.plist File to Store Configuration Data

Right-click on the “Supporting Files” group and select “New File” (New File > Resource > Property List). Save File as “Environments”, this will create a file named “Environments.plist”. Now that you have your custom plist file ready to be modified, add all of your build configurations (Debug and Release by default) of type Dictionary to the plist. You can also begin to enter custom properties underneath each build configuration (entered as myAPIURL in my example).

Optionally, you can segregate your property files per build configuration. For example, create plist files for each of your build configurations (i.e. Debug.plist, Release.plist).

Add Custom Properties to Configuration by Environment (Build Configuration)

Step 3: Make your Custom Configuration Available to your Application

Create a singleton or implement a strategy to load your configuration data on a per build configuration basis. You can determine your scheme’s current build configuration by reading the “Configuration” property within your default plist file (as applied in step one).

For example, here is a singleton that will load your configuration:

Now you should be able to access properties within your application by sending getter messages to the Environment instance.

Environment *myEnvironment = [Environment sharedInstance];
NSString *apiURL = myEnvironment.myApiURL;

Step 4: Add Additional Build Configurations to your Application

Within Xcode, select your Project within the left-hand navigation. Your project and target settings should be visible and editable. Next, select your project settings so that your build configurations are exposed (by default, Xcode creates the Debug and Release build configurations for you). At this point you can create a new build configuration for a custom environment (i.e. acceptance, staging or demo).

Also, don’t forget to add your custom configuration data for your new build configuration.

Now Your Ready!

Your application now has access to configurations per environment by use of build configurations. We’ve made the current build configuration readable by adding it to the default plist file. We used the current build configuration as an identifier for key’ing entries in a custom properties file (Environments.plist). The custom properties file contains configuration properties per build configuration. In order to read the custom properties programmatically, we created an object (Environment.m) to read the file. Finally, we added custom build configurations to support new, application specific, environments.


p>Some side notes:

  • One target, configurable schemes: You can change the build configuration you would like to use for a target by editing (or creating) your scheme. This will quickly allow you to run your target against different application environments.
  • Properties like bundle identifier and bundle name can be set by user defined properties and further specified by your build configurations. This will make deploying you application to devices easier.
  • The Xcode command line build tool has a parameter named “configuration”. This will allow you to build your application per environment (i.e. xcodebuild -configuration Debug).