Blog post image

.xcconfig FTW

Article by

Edward Patel

Published in

iOS, Mobile Development

I am currently working on a project where we have to make different versions of an app for different test groups. As usual, I try not to make changes directly in the Xcode build settings panes but rather use so called .xcconfig files. I think they are great to have, both by moving some of the hassles with Xcode build settings panes to more manageable config files, but they also give the possibility to structure config variables a bit.

In this project, I have structured some of the variables in a way that has turned out to work very well. My goal was to make one single variable master of a number of other variables. I called this variable TEST_GROUP. Then I created the various groups for the variables I want to be able to set from the config file. ie

TEST_GROUP = PLANET9
PLANET9_BUILD_VERSION = 3
PLANET9_BUILD_BUNDLE_ID = com.client.fabric-app
XCODE_BUILD_VERSION = 42
XCODE_BUILD_BUNDLE_ID = com.dynamo.example-app

But the real winning trick was to chain in the TEST_GROUP variable into the receiving variable. Concatenating the desired variable. Like this.

BUILD_VERSION = $($(TEST_GROUP)_BUILD_VERSION)

I also used this chaining trick to add compile time variables for different features. Concatenating into a second variable that activates the actual flag. ie.

GET_LANGUAGE_JSON = YES

And then chained them into activation with variables like.

GET_LANGUAGE_JSON_YES = -DGET_LANGUAGE_JSON
OTHER_SWIFT_FLAGS = $(inherited) $(OFFLINE_MODE_$(OFFLINE_MODE))
$(GET_LANGUAGE_JSON_$(GET_LANGUAGE_JSON))

I even combined these two to control flags on per target basis.

PLANET9_USE_FRONT_CAMERA = NO
PLANET9_ADD_BUILD_DATE = NO
XCODE_USE_FRONT_CAMERA = YES
XCODE_ADD_BUILD_DATE = YES
USE_FRONT_CAMERA = $($(TEST_GROUP)_USE_FRONT_CAMERA)
ADD_BUILD_DATE = $($(TEST_GROUP)_ADD_BUILD_DATE)
USE_FRONT_CAMERA_YES = -DUSE_FRONT_CAMERA
ADD_BUILD_DATE_YES = -DADD_BUILD_DATE
OTHER_SWIFT_FLAGS = $(inherited) $(OFFLINE_MODE_$(OFFLINE_MODE))     
$(GET_LANGUAGE_JSON_$(GET_LANGUAGE_JSON)) $(USE_FRONT_CAMERA_$(USE_FRONT_CAMERA))
$(ADD_BUILD_DATE_$(ADD_BUILD_DATE))

When the pattern was in place, much became very easy to manage. I will probably start doing the same in the next project.

Edward is a Senior Software Engineers at Dynamo with long experience from software projects ranging from telecom, simulation, VR, and mobile. He has a passion for new technologies like IoT and 3D printing.