Improve Your Project Builds by Leveraging xcconfig Files

Saturday, 30 September 2023

Managing Xcode project settings can get complicated as your app grows. One powerful, handy tool to simplify this process is the xcconfig file. In this post, we’ll explore what xcconfig files are, why you should use them, and how to implement them in your Xcode projects.


What Is This File and Why Should You Use It?

An Xcode configuration file, xcconfig, is a plain text file that contains build settings for your project. Whether you’re working solo or as part of a team, mastering xcconfig files can streamline your workflow and make your project more robust.

From several other advantages, I’ll highlight the following:

Easier Management of Build Settings

It lets you manage your build settings in one centralized location. This makes it easier to find, update, or remove settings without sifting through Xcode’s often cluttered UI.

Cleaner Separation of Configuration From Code

You can separate your configuration settings from your actual code. This makes your codebase cleaner and easier to read, as you don’t have to dig through lines of code just to tweak a setting.

Version Control Advantages, Like Reducing Merge Conflicts in Project Files

Storing settings in xcconfig files helps minimize the chances of running into merge conflicts when using version control systems. By isolating settings from the project file, you avoid messy conflicts that often need manual resolution.


Syntax and Structure

Let’s now take a look at the syntax and structure of xcconfig files. We’ll cover the basics, as well as some more advanced topics.

Key-Value Pairs

At its core, an xcconfig file is a list of key-value pairs. Each line sets a configuration key to a specific value. And, to use a variable you’ve defined, wrap it in parentheses and precede it with a dollar sign.

// Setting the Bundle Identifier
PRODUCT_BUNDLE_IDENTIFIER = com.example.MyCoolApp

// Setting the Product Name
PRODUCT_NAME = $(APP_NAME)

Whitespace

Whitespace generally doesn’t matter in xcconfig files, making it flexible to format. You can align values neatly or leave space around the equals sign for better readability.

CODE_SIGN_IDENTITY = iPhone Developer

Including Other xcconfig Files

To keep things organized, you can include one xcconfig file in another using the #include directive. This way, you can have base configurations that are extended by more specific ones. It’s worthy pointing out that variables defined in the including file will override those in the included file.

// Base.xcconfig
COMMON_FLAGS = -Wall

// Debug.xcconfig
#include "Base.xcconfig"
OTHER_SWIFT_FLAGS = $(COMMON_FLAGS) -DDEBUG

// Release.xcconfig
#include "Base.xcconfig"
OTHER_SWIFT_FLAGS = $(COMMON_FLAGS) -DRELEASE


Your First xcconfig File

There’s no big secret to getting started with xcconfig files. You can create one in a few simple steps.

Creating an xcconfig File

First up, open your Xcode project and go to the ‘File’ menu. Select ‘New’ > ‘File’, or use ⌘ + N, then choose ‘Configuration Settings File’ to create your new xcconfig file.

Creating an xcconfig File

I created 3 files: Debug, Release and Shared.

Creating an xcconfig File

Assigning to Build Configuration

Now, head over to your project settings by clicking on the project name in the navigator. Under ‘Configurations’, you’ll find a list of your build configurations like ‘Debug’ and ‘Release’. Assign your xcconfig file to the desired configuration here.

Assigning to Build Configuration

Verifying the Setup

To make sure everything’s set up correctly, try moving a simple setting, like the bundle identifier, to the xcconfig file. Then, on your Info.plist file, replace the bundle identifier with the variable you just created. If everything’s working, you should see the new bundle identifier in the ‘General’ tab of your target settings. Build your project and verify that the setting takes effect.

Verifying the Setup 1

Verifying the Setup 2

Verifying the Setup 3


Advanced Topics

Here are some more advanced topics to help you get the most out of these special files.

Command-Line Overrides

You can override xcconfig settings directly from the command line during build time. This is useful for temporary changes or for settings that need to be dynamic.

xcodebuild -project MyCoolApp.xcodeproj -scheme "MyCoolApp" PRODUCT_BUNDLE_IDENTIFIER=com.example.NewIdentifier

Integrating with Scripts

You can use xcconfig files in tandem with pre-build or post-build scripts to automate complex build setups.

Environment Variables

In xcconfig files, you can access environment variables from your system, allowing you to integrate external data into your build configuration. For example, you can use stored credentials.


Common Use Cases

From all the companies I’ve worked for, I’ve seen a few common use cases for xcconfig files. Let’s take a look at some of them.

Managing Multiple Environments

One of the most popular use-cases is managing different build environments like Debug, Internal, and Release. You can set up separate xcconfig files for each, making it easy to switch between them.

Sharing Settings Across Targets

If your project has multiple targets, like an app and its corresponding widgets or extensions, xcconfig files help you share common settings across all targets. This ensures consistency and reduces duplication.

Team Collaboration

When working in a team, isolating settings from the main project file with xcconfig smooths collaboration by reducing the risk of merge conflicts, as mentioned before.

Automating Builds

xcconfig files can also be a part of your CI/CD pipeline, allowing you to set or override build settings dynamically during automated builds.

Modularizing Code

If you’re working on a project that includes various modules or libraries, xcconfig files can help you manage settings for each one separately, providing a clean and modular approach to configuration.


Best Practices

Let’s wrap it up with some best practices.

Organizing Files

Keeping your xcconfig files organized in a dedicated folder will facilitate management, especially as your project grows. Consistent naming is also key.

Commenting and Documentation

Good commenting within the xcconfig files can save you and your team a lot of headaches later on. Clearly explain what each setting is for and why specific values are used.

Version Control

Always keep your xcconfig files under version control. This not only tracks changes but also lets you revert to previous configurations if something goes wrong.

Separation of Concerns

Try to segregate settings based on their function or scope. For example, keep build-related settings separate from code signing settings.

Regular Audits

As your project evolves, your settings will too. Periodically audit your xcconfig files to remove obsolete settings and update existing ones.

Use with Caution

Be mindful of the complexity you’re introducing. Only use advanced features like conditional statements when really necessary.


Further Reading


Development Menu for the Rescue

Tuesday, 19 September 2023

A modern approach in app software development involves adding a development menu to the app. This feature is commonly found in larger companies, like Trade Republic, and is designed to streamline the development process.

Rather than navigating through the app or sifting through code for minor adjustments, the menu serves as a centralized hub. Within it, you can visually examine and interact with various elements of your app, such as UI components, color palettes, behaviors, and fonts. Additionally, you can easily change the values of feature flags and also use it as a playground for testing new technologies. At Trade Republic, our development menu is in SwiftUI, even though our app uses UIKit. My personal projects also feature a SwiftUI development menu.

The development menu is solely for development purposes and may not adhere to the same software quality and development rules as the actual app. Based on certain directives, it is stripped out from the versions of the app released on the App Store or Google Play. However, companies may still enable it in internal builds of the app.

It’s like having a secret lab for your app.