Configuring projects with xcconfig
Tags: ios, swift
Published: 2019-11-13 09:20:02

Sometimes you want to be able to install two versions of your app side by side, for example, a development version and a release version that show up as individual apps by giving them different bundle identifiers. And maybe they should also use different versions of your REST API depending on the type of build you're using. In this week's Quick Tip I will show you how you can manage this using `xcconfig` files.

## Creating and using your xcconfig file

To create an xcconfig file, choose **File -> New -> File...** in your project. In the new file dialog, scroll down until you see the **Configuration Settings File** in the **Other** section.

<img src="https://www.donnywals.com/wp-content/uploads/Screen-Shot-2019-11-04-at-19.48.04.png" alt="New File Dialog" width="1516" height="1094" class="aligncenter size-full wp-image-513" />

After choosing an appropriate name (like debug.xcconfig for example) you can open your `xcconfig` file in Xcode and add new configuration rules to it. An `xcconfig` file should contain key and value pairs in the following format:

```swift
PRODUCT_BUNDLE_IDENTIFIER = com.xcconfig.sample
PRODUCT_NAME = Config Example
```

You can add configurations for pretty much anything you want. A good way to find out what key should be used for specific purposes you can open your `xcodeproj` file in a text editor and look for the settings you want.

To make Xcode apply your `xcconfig` file, go to your app's project settings, look for the build type you want your configuration to apply to, and select your configuration as shown in the following screenshot:

<img src="https://www.donnywals.com/wp-content/uploads/Screen-Shot-2019-11-04-at-19.54.20.png" alt="Selected build configuration" width="1460" height="610" class="aligncenter size-full wp-image-514" />

After doing this, Xcode might not apply your configuration for all keys you've added in your `xcconfig`. If this is the case, go to your projects **Build Settings** and enable the **Levels** view. The fields that are marked in green are what Xcode will use while building your app. If Xcode uses the wrong field, you can select it and clear it so Xcode will look for the next best fit. The following screenshot shows this:

<img src="https://www.donnywals.com/wp-content/uploads/Screen-Shot-2019-11-04-at-19.57.29.png" alt="Xcode Levels view" width="1380" height="314" class="aligncenter size-full wp-image-515" />

The number of options you can configure like this are numerous and the **Levels** view is extremely helpful in figuring out what values Xcode uses for certain configuration keys. Next up, using your `xcconfig` file to configure your app's runtime.

## Using xcconfig and your Info.plist to configure your app

If you want your app to use different settings for different builds, like for instance use a development endpoint of your REST API, you can use your `Info.plist` and `xcconfig` file to set this up. All you need to do is add a new key to your config, use a config key as the value and read it in your app. For example, you might have the following key in your `xcconfig`:

```swift
API_ROOT = dev.myapp.com
```

You can use this config value by adding a key to your `Info.plist` and using `$(API_ROOT)` as the value. You can then proceed to read this key from your `Info.plist` just like you would any other key. Nifty, right?

## In Summary

In this week's Quick Tip you learned how you can use an `xcconfig` file to drive build time configurations of your app. At compile time, all values that are in your `xcconfig` are applied to your project. This allows you to specify a special bundle identifier, product name, development team and even code signing strategy that will be applied to any build configuration that you want.

You can even use the `xcconfig` file to add different values to your `Info.plist` file so you can configure certain runtime features for your app. All in all, a very powerful feature that I personally use in many projects. If you have any questions, compliments or feedback, don't hesitate to find and message me on [Twitter](https://twitter.com/donnywals)