Using Configuration Files When Developing Projects with Xcode
December 6, 2023
For most products, having separate environments for testing and production is common. If you’re building an iPhone application (which utilizes a backend API service) you’ll likely have a variable containing the environment endpoint value. For simple applications, configuration changes could be managed using a debug conditional compiler directive. However, with larger projects or when targeting several environments, a more robust solution is required due to the project’s complex nature. In this case, we would use configuration files.
Configuration Files:
Xcode utilizes a simple file format, xcconfig, to manage application configuration externally from the project file or source code. These files consist of a collection of key-value pairs and can be used to set the project, build, and info.plist values.
xcconfig Syntax:
- By default, values set within these files are treated as strings.
- Can include additional supporting xcconfig files using ‘#include “path/to/config.xcconfig”’.
- Variable names must begin with a letter or underscore and may only include alphanumeric characters.
- Can reference variables using format $(NAME) or ${NAME}.
- Variable substitution is possible in both values and other variables.
- e.g. CURRENT_VERSION = $(CURRENT_VERSION_$(ENV))
- Redeclaring a variable name overwrites variables from included files. If you wish to use the inherited value, replace the variable, then include ‘$(inherited)’ as part of the value.
- e.g. BUILD_ARGS = $(inherited) -ObjC
Setup with Xcode:
As part of the project setup within Xcode, it is common to have multiple schemes defining the settings used and tasks run for the target(s). Build, debug, run, profile, and test are examples of what could be defined within the project. As part of the scheme definition, a configuration file can be set at the project level and for each individual target.
The values are loaded in priority (lowest to highest), replacing any duplicate keys with those of higher priority:
- System default values
- Project configuration file values
- Project specified values
- Target configuration file values
- Target specified values
Configuration variables are not directly accessible in the code. Therefore, if access is required, variables must also be included as user-defined values. User-defined values are set at the very bottom within the build settings tab.
The user-defined variables may then be referenced within the info.plist file by creating a key and value pair. Matching key names are not required but the value must reference the user-defined variable, using the standard syntax.
To access these variables within the code, the following snippet can be used as an example to extract the given key from the info dictionary:
return Bundle.main.object(forInfoDictionaryKey: “BASE_AUTH_API_ENDPOINT”) as? String
See https://developer.apple.com/documentation/foundation/bundle/1408696-object for further details.
Imaginet’s Use Case:
We have multiple project targets and environments that require both shared and unique configuration sets. With our environment configuration moved into files and enabled for specific schemes, we can simply target a different environment by selecting the appropriate build scheme.
Our xcconfig files inherit other shared files where appropriate, resulting in a single project source for our shared build variables.
By utilizing Azure DevOps and Fastlane as part of our build pipelines, we have included tasks that read and write values directly to these configuration files prior to build. This enables us to read or replace values as necessary. For example:
- Writing our build number to the configuration; this is included in the IPA metadata for release to App Store Connect in conjunction with the marking version to generate our full product version.
- Extracting the marketing version for tagging our build pipeline with the app version, enabling us to filter build pipeline runs as necessary.
- Extracting the referenced SDK version ensures the correct SDK is downloaded from Azure Universal Artifacts for the build process.
Once the configuration updates and any additional tasks are complete, the pipeline continues with building and publishing artifact tasks.
Imaginet’s Application Development Team is well-versed in utilizing configuration files for larger and more complex projects. Our team of experts has used configuration files to easily deploy and scale applications for many of our clients.
Thank you for reading this blog. We publish tips, tricks, and hints on our blog every week. Make sure to subscribe so you don’t miss out! If you have an application development project in mind, we’d love to hear from you. Fill out the form below and someone will be in touch.
Discover More
SQL Saturday Part 2: Learning About Microsoft Fabric
SQL Saturday Part 2: Learning About Microsoft Fabric February 29, 2024 I’ve been digging into Microsoft Fabric recently – well overdue, since it was first released about a year ago.…
My Trip to SQL Saturday Atlanta (BI Edition): Part 1
My Trip to SQL Saturday Atlanta (BI Edition): Part 1 February 23, 2024 Recently, I had the opportunity to attend SQL Saturday Atlanta (BI edition), a free annual event for…
Enabling BitLocker Encryption with Microsoft Intune
Enabling BitLocker Encryption with Microsoft Intune February 15, 2024 In today’s data-driven world, safeguarding sensitive information is paramount, especially with the increase in remote work following the pandemic and the…
Let’s build something amazing together
From concept to handoff, we’d love to learn more about what you are working on.
Send us a message below or call us at 1-800-989-6022.