How to Use Multiple Targets in Xcode

This guide will help you better understand how to use multiple targets in Xcode for the different environment in your iOS development workflow.

What is the proper set of environments for a better software development workflow? We recommend using development, testing, staging, and production. This is great, but how should you organize different environments in your development workflow? Each might have its own base URL, database, log level, and so on.

Changing the codes in a particular target for an environment is vexing.

If you are struggling with managing multiple environments, listen to me I have the right solution for you.
The whole process for this may be quite intimidating for you to start with, but, once you have reached the end of this article, you’ll be heavenly satisfied. Just be sure not to miss any of the steps.


  • Duplicate the configurations
  • Create user-defined settings for Bundle ID, Build number and Version number.
  • Set the flags Other Swift Flags.
  • Create schemes for each environment.
  • Reflect them in info.plist

Step 1:

Create your project and go to info setting in the project section and duplicate both the release and debug configurations.

Step 2:

Select your project from the list of targets, and then go to Build Settingsand create three user defined settings for BUNDLE_IDBUILD_NUMBERand VERSION_NUMBER.

Step 3:

Search for Other Swift Flags in Build Settings itself and set the values as:

You should give a relevant name for a flag. Here, I’ve given it a name — PRODUCTION. Remember, we’ll be using this flag later in our code.

#Note: For Objective-C compiler, you need to use Preprocessor Macros , but since Swift lacks preprocessor we use Conditional Compilation. Here -Dsets the flag for conditional compilation.

Step 4:

Create a new scheme. However, you can duplicate it from the existing schemes.

The number of the environment is proportional to the number of schemes. Btw, it’s my own rule.

Go to Manage Schemes and create one. Give a relevant name for your new scheme

Now, select that scheme and click on Edit button. This’ll take you to a new prompt dialog box.


class ViewController: UIViewController {

override func viewDidLoad() {
func networkCall() {
  var urlString = String()
    urlString = "https://StagingURL"
    urlString = "https://productionURL"
  let url = URL(string: urlString)
  let task = URLSession.shared.dataTask(with: url!) { data,   response, error in
  // Network callback
  urlString = "https://StagingURL"
  urlString = "https://productionURL"


This is the main code block to look into. The flag that we last set in other swift flags , now, we are using those in our code.

Furthermore, if you need the two instances of the app, open info.plist file and edit as follow as:

Now, select one scheme and run the project and you’ll see the magic happen.


Read more of our engineering blogs.

More in Insights

8 DevOps Tools and Services We Love Technology

8 DevOps Tools and Services We Love

The core focus of any DevOps team is evolving and improving products rapidly. At Leapfrog, we value the speed at

Read more
How We Moved Towards Serverless Architecture Technology

How We Moved Towards Serverless Architecture

The scalability, flexibility and reduced cost promised by serverless architecture resulted in a massive growth rate of 75% compared to

Read more
Enhancing Git Workflow with Smart Commit Open Source Tool Technology

Enhancing Git Workflow with Smart Commit Open Source Tool

When you have a predefined process, it is generally a good idea to automate the things that can be and

Read more