How to manage build settings using Xcode configuration files
If you are working as part of a team in a bigger company, it's likely you have multiple environments set up. The names can be different, but these are usually a development environment for devs to do their work, a testing environment for QAs and a production environment.
If you are working alone, you might not have these environments set up for a smaller app. But even if you don't, you could still benefit from creating an Xcode build configuration file for different build settings.
You can open Xcode configuration files outside of Xcode and with any text editor. Because all properties are in plain text, they are easier to read and you don't have to navigate Xcode's maze of build settings.
One of the popular use-cases for using a configuration file is to manage constants across different environments. We're going to use it to store a base URL for our API.
I suggest reading this article by Matt from NSHipster on Secret Management on iOS. He suggests never to use Xcode Configuration files to manage your API Keys (or secrets). The best way to keep your secrets secure, is to obfuscate them using code generation.
Or, in the words of Julian Assange:
"The only way to keep a secret is to never have one."
Configuration Settings File
Xcode build configuration files or .xcconfig files allow us to define and manage build settings for our apps in plain text. Each file consists of a sequence of key-value properties in a KEY_NAME = value format, where value can be String
, Int
, Bool
, or other defined formats. You can read more on configuration settings file format in Apple's Xcode Help documentation.
In your Xcode project, create a new Configuration Settings File anywhere you'd like and name it Configuration. Make sure not to select any targets for it.
Next, add a property for your base url to the file:
// Example:
BASE_URL = awesome.example.com
Info.plist
Build settings defined by Xcode project and configuration files are only available at build time. When you compile the app, none of it is available. As it should be.
After creating the BASE_URL property, you need to add it to your Info.plist file. It'll get compiled during build time based on the build settings provided and copied into the app bundle.
But wait, there's no Info.plist file in Xcode. Following Xcode 13 release, there's no Info.plist file by default anymore when you create a new project in Xcode. This file is a feature and only created when needed. We're nudged to use Xcode's Build Settings instead.
Select your project in Xcode and go to Info tab. Expand Configurations and add your Configuration.xcconfig file to both Debug and Release. We only have a single configuration file, but this is where you can set up different configuration files for different environments:
Now all that's left to do is to add a reference to the property in target's build settings.
Custom iOS Target Properties
By adding a reference to the configuration properties, you can access their values with Foundation's Bundle
API.
Select your project's target in Xcode and go to Info tab. Select any property in Custom iOS Target Properties and click on the + button to add a new property.
Add BASE_URL with the reference to your configuration property $(BASE_URL):
After adding the property, an Info.plist file gets added to your project automatically. All your custom user properties will get stored here.
Now all you have to do is access the base url in your code.
Bundle
Create a new Swift file and name it any way you'd like. I'll name it Environment. Add the following code to the file:
import Foundation
public struct Environment {
enum Keys {
static let baseURL = "BASE_URL"
}
// Get the BASE_URL
static let baseURL: String = {
guard let baseURLProperty = Bundle.main.object(
forInfoDictionaryKey: Keys.baseURL
) as? String else {
fatalError("BASE_URL not found")
}
return baseURLProperty
}()
}
Here you create a new Environment struct
and a Keys enum
that defines all your custom keys. Then you create a baseURL constant to get the value from the bundle. Now you have access to its value where needed.
Let's print it out in a View to make sure it's working:
Final Thoughts
Xcode build configuration files are quite useful to manage configuration properties between different environments. You can also use them to easily assing a different app name and an app icon for specific environment.
What makes them especially useful is you can open them outside of Xcode with any text editor. It also keeps your configuration properties outside of your code.
Please feel free to reach out on Twitter if you have any questions, comments, or feedback.
Thank you for reading and happy coding!