> ## Content Index
> Fetch the complete content index at: https://developerinsider.co/llms.txt
> Use this file to discover other available public pages before exploring further.

# Best way to manage Development, Testing and Production iOS builds with different settings
- URL: https://developerinsider.co/manage-different-settings-for-development-testing-and-production-ios-builds/
- Published: 2016-03-16T08:06:19.000Z
- Updated: 2018-06-24T05:50:48.000Z
- Author: Vineet Choudhary
- Tags: iOS

## Problem Statement

Suppose you need to manage three `API` with different `API Keys` and some different settings

- **For development or internal testing build** \- Development distribution outside the iOS App Store  
`Host` \- devapi.project-name.com  
`API Key` \- development\_key
- **For client testing build** \- Enterprise distribution outside the iOS App Store  
`Host` \- stgapi.project-name.com  
`API Key` \- enterprise\_key
- **For production build** \- Distribution in the iOS App Store  
`Host` \- api.project-name.com  
`API key` \- app\_store\_key

---

You are able to manage two setting by using `DEBUG`

```objective-c
#if DEBUG
    #define API_BASE_URL @"http://devapi.project-name.com/api/v1"
    #define API_KEY @"development_key"
#else
    #define API_BASE_URL @"http://stgapi.project-name.com/api/v1"
    #define API_KEY @"enterprise_key"
#endif

```

#### First Problem

Enterprise distribution (for client testing) and iOS App Store distribution (production) build, for Enterprise and App Store distribution every time need to change code

- **For Enterprise distribution**

```objective-c
#if DEBUG
    //debug setting
#else
    //enterprise setting
    #define API_BASE_URL @"http://stgapi.project-name.com/api/v1"
    #define API_KEY @"enterprise_key"
#endif

```

- **For App Store distribution**

```objective-c
#if DEBUG
    //debug setting
#else
    //app store setting
    #define API_BASE_URL @"http://api.project-name.com/api/v1"
    #define API_KEY @"app_store_key"
#endif

```

We need a way something like this

```objective-c
#ifdef DEVELOPMENT
    #define API_BASE_URL @"http://devapi.project-name.com/api/v1"
    #define API_KEY @"development_key"
#elif ENTERPRISE
    #define API_BASE_URL @"http://stgapi.project-name.com/api/v1"
    #define API_KEY @"enterprise_key"
#elif APP_STORE
    #define API_BASE_URL @"http://api.project-name.com/api/v1"
    #define API_KEY @"app_store_key"
#endif

```

---

#### Second Problem

Is there any way to create three build with different name without creating different target?

- `ProductName` \- For App Store
- `ProductName-Dev` \- For Internal Development build
- `ProductName-Stg` \- For Client Testing (Enterprise) build

---

## Solution

#### Create Individual Configurations

In the project (not target) settings, create (duplicate from the originals) the following configurations:

- Debug\_Dev
- Debug\_Staging
- Debug\_Prod
- Release\_Dev
- Release\_Staging
- Release\_Prod

![](https://github.com/developerinsider/developer-insider-content/blob/master/Post%20Images/iOS%20Insider/16-03-2016/1%20create%20config.png?raw=true)

Note that if you use Cocoapods then you will need to set the configurations back to none, delete the contents of the Pods folder in your project (**Not the Pods project**) and re-run `pod install`.

#### Create a scheme for each environment

Instead of just having a MyApp scheme, create the following (duplicate the original):

![](https://github.com/developerinsider/developer-insider-content/blob/master/Post%20Images/iOS%20Insider/16-03-2016/2%20Create%20Scheme.png?raw=true)

- MyApp\_Dev (Development)
- MyApp\_Stg (Staging)
- MyApp (Production)

In each scheme, use the associated Debug\_\* and Release\_\* configurations where appropriate.

![](https://github.com/developerinsider/developer-insider-content/blob/master/Post%20Images/iOS%20Insider/16-03-2016/6.%20Assosiation%20Env.png?raw=true)

Here the final look

![](https://github.com/developerinsider/developer-insider-content/blob/master/Post%20Images/iOS%20Insider/16-03-2016/3%20Created%20Scheme.png?raw=true)

#### Add a preprocessor macro to identify environments

Add an additional preprocessor macro to identify what environment you are building against.

In the project build settings, click the + and add a user defined build setting and call it something like `MYAPP_ENVIRONMENT`. Then, for each different group of environments, add a different preprocessor macro to each one. i.e `DEVELOPMENT=1`, `STAGING=1` and `PRODUCTION=1`.

![](https://github.com/developerinsider/developer-insider-content/blob/master/Post%20Images/iOS%20Insider/16-03-2016/new%20preprocessor.png?raw=true)

![](https://github.com/developerinsider/developer-insider-content/blob/master/Post%20Images/iOS%20Insider/16-03-2016/4%20Add%20Environment.png?raw=true)

Then, in the c preprocessor macros (again on a project level and not the target level) add this new MYAPP\_ENVIRONMENT setting using `$(MYAPP_ENVIRONMENT)`.

![](https://github.com/developerinsider/developer-insider-content/blob/master/Post%20Images/iOS%20Insider/16-03-2016/new%20preprocessor%202.png?raw=true)

Finally it's look like this  
![](https://github.com/developerinsider/developer-insider-content/blob/master/Post%20Images/iOS%20Insider/16-03-2016/5%20add%20preprocessor.png?raw=true)

This way, you can then determine what environment you are building against like so:

```objective-c
#ifdef DEVELOPMENT
    NSString * const MyAppAPIBaseURL = @"https://api-dev.myapp.com/";
#elif STAGING
    NSString * const MyAppAPIBaseURL = @"https://api-staging.myapp.com/";
#elif PRODUCTION
    NSString * const MyAppAPIBaseURL = @"https://api.myapp.com/";
#endif

```

It's probably a lot to take in.

---

You can then also create different user defined build settings to do different things, like change the display name of your app.

You could do this by creating a new setting called `MYAPP_DISPLAY_NAME` for example (same as we create preprocessor macro to identify environments), set the correct name for each configuration and then in your `info.plist` set the value of the Bundle Display Name to `$(MYAPP_DISPLAY_NAME)`.

## Completed Project -

[https://github.com/vineetchoudhary/BuildManagement](https://github.com/vineetchoudhary/BuildManagement?ref=developerinsider.co)