TechnologyNov 16, 2015

Using Compiler Flags to Switch Between QA and Production Servers in iOS Applications

Aaron Wolin

Using Compiler Flags to Switch Between QA and Production Servers in iOS Applications

Many iOS applications we develop are tested against a QA server before we submit to the Apple store. These servers have different URLs than their production-ready counterparts, and we do not want to accidentally submit a build to Apple that uses a QA server URL.

This article explains how we implemented a reliable URL-switching mechanism for our QA and production app builds to prevent human error in app submissions. It assumes you have familiarity with XCode 6, Swift, and the general iOS build and submission process.

Source code from this example can be found on GitHub.

  1. Setup Your Target Parameters

Much of the work to have a reliable QA and production app is in setting up your project to have different settings for debug and release builds.

Go to your project file Targets > Build Settings and search for “code signing”. Set the Debug Provisioning Profile to your Development or QA provisioning profile, and your Release profile to your Distribution. Then change your Code Signing Identity for Debug to use your Developer or Ad Hoc Distribution identity. The Release identity should use the iTunes Store iOS Distribution identity. These changes will force all of your release builds to use your production standards.

Still in Targets > Build Settings, search for “swift compiler – custom flags”. Add a Release flag with the value -DPROD. This setting allows us to conditionally compile code using an #if PROD <code> #endif pattern. More on this in step two.

Optionally, we can also change the package name to reflect our current build. Search for “product name” in the Build Settings and set a different package name for Debug and Release. In our case, we use “Example QA” and “Example”.

  1. Use the Compiler Constant to Change Servers

In our example app, we created a Constants.swift file to hold our QA and production server URLs. Using a single file for our production/QA constants will allow us to easily switch between them in one location during development.

Set up the file to contain structs with static variables. Switch between the variables using an #if PROD <code> #endif, which uses the -DPROD compiler setting from our Build Settings to change what portions of code are in our final target. For us, this will create a Server.URL variable that switches between the Server.QA and Server.PROD variables available.



  1. Manage Your Product Schemes

Now that we have our Build Settings and Constants file in place, let’s create some product schemes for utilizing our QA/production switching code.

On the application toolbar, go to Product > Scheme > Manage Schemes. Delete the current schemes and create two new ones; in our example, we’ve used Example QA and Example PROD

Fig. 1 – Product schemes set up for QA and Prod

Edit “Example QA” and set both the “Run” and “Archive” builds to use the a “Debug” build configuration (Fig. 2). For Example PROD, set both the “Run” and “Archive” settings to use a “Release” build configuration (Fig. 3).

Fig. 2 – Example QA scheme using debug build configurations

Fig. 3 – Example PROD scheme using release build configurations

  1. Build!

You can now test and archive your QA app for development and ad hoc testing purposes, and iTunes Connect submissions should use the Example PROD Archive. The build configuration “Release” will compile with the -DPROD flag and force the app to use your production URL configured in your Constants.swift file.

  1. Additional Safeguards (Optional)

Although setting up the compiler branching in the Constants.swift file should be enough to prevent human error when compiling builds, it never hurts to have more safeguards. We’ve also added some functionality to our AppDelegate file to check that a production build is using production constants. We can alert the user that the wrong constants are used, or abort the app completely which will prevent any Apple submission review from being accepted.


Using Swift compiler constants with build targets and production schemes can reduce human error in compiling iOS builds for QA and production. We’ve used the presented patterns with great effect for our clients, and we hope you can utilize them as well.