Using the Mapbox SDK for iOS with Xcode Cloud

This reference covers how to write custom build scripts for Xcode Cloud to use the Mapbox SDK as a dependency with Swift Package Manager.

Using the Mapbox SDK for iOS with Xcode Cloud

Xcode Cloud is a new cloud-based toolchain introduced by Apple during WWDC 2021 that allows to automatically build, test, and distribute apps from within Xcode. It is available in beta currently, and you can join the waiting list here.

The initial configuration is quite straight forward and the system can be set up in a few minutes within any development project. For a quick guide on how to get started, consider our article "Setting up Xcode Cloud for Automated Builds, Tests and Distribution".

However, when using third-party dependencies in your project, things might get a bit more complicated. Apart from requiring access to the git repositories for all dependencies, some packages may require additional configuration before they can be used with Xcode Cloud. Apart from many other usage scenarios, this is where build scripts come in.

The Mapbox SDK for iOS for example requires that the Mapbox API token is stored locally in a .netrc file to access the frameworks repository on Github. Without the file being present, the package can not be resolved to build the project. Even though the framework is managed through Swift Package Manager, the build fails when trying to load the Mapbox SDK from Github.

To create this file on the cloud container in which the project will be built, custom build scripts can be used. The Xcode Cloud pipeline supports three types of build scripts.

  1. Post-clone: It runs after the project source git repository is cloned to the temporary environment and before all other dependencies are resolved. It can be used to install additional tools, edit files before building the project, etc and has to use ci_post_clone.sh as a file name.
  2. Pre-Xcodebuild: It runs before the xcodebuild command is run in the Xcode Cloud environment and can be used to compile additional dependencies for example. It has to use ci_pre_xcodebuild.sh as a filename.
  3. Post-Xcodebuild: It runs after the xcodebuild command is run in the Xcode Cloud environment and is executed also if the build fails. As an example, it can be used to upload artifacts to other services and has to use ci_post_xcodebuild.sh as a file name.

In our case, Post-clone is the appropriate moment within the pipeline to solve the issue of creating the .netrc in the temporary build environment on Xcode Cloud.

Inside the Xcode project, create a new folder called ci_scripts and then add a new file to that folder. When using the New File assistant, choose Shell Script and call it ci_post_clone.sh and do not add it to the target. Then, inside the script file, the .netrc file can be created with the required information to work with the Mapbox SDK.

#!/bin/sh

touch ~/.netrc

echo "machine api.mapbox.com" > ~/.netrc
echo "login mapbox" >> ~/.netrc
echo "password ${MAPBOX_TOKEN}" >> ~/.netrc

The Mapbox SDK also required the Mapbox API token to be in this file. However, it may be smart to not add the token to this file in plain text, but rather use an environment variable. Therefore, in this example, we are using MAPBOX_TOKEN as a variable.

The environment variable can be configured for the Xcode Cloud workflow. For this navigate to the Report Navigator in Xcode and edit your workflow. In this example, it is the Default workflow that was created when Xcode Cloud was initially set up for this project.

Inside the workflow settings, the Environment can be configured by specifying the Xcode and macOS version as well as any Environment Variable. This is where we can set the MAPBOX_TOKEN and add the Mapbox API key. If you don't know how to set up Mapbox and get an access token, refer to our article "Integrating Mapbox with SwiftUI" which covers how to get started with Mapbox.

That's it. With the ci_post_clone.sh custom build script we are creating the needed .netrc file with the access credentials that the Mapbox SDK requires to resolve all dependencies after cloning the packages. To obscure the API access token from the file, we are using an environment variable to provide the token to the script when it is run.

To learn more about custom build scripts and environment variables, stay tuned for more articles on Xcode Cloud and join our free mailing list to not miss when new content is out.