Introducing Trapeze: Easy iOS and Android Project Configuration
Today I’m excited to announce the public availability of Trapeze, our new open-source project that makes it easy to manage native and cross-platform mobile projects from a simple YAML-based configuration-file format.
Through this configuration file, Trapeze can work with the common file formats found in native iOS and Android projects, such as Gradle, XML, JSON, XCConfig, Strings, PBXProj, PList, Android Resources, and others. Trapeze supports traditional iOS and Android apps, and cross-platform frameworks like Ionic, Capacitor, React Native, and Flutter.
Trapeze was built to solve key challenges the mobile community faces when managing mobile projects at scale, especially in Mobile CI/CD workflows. Read on to learn more about Trapeze and where we’re taking it.
Solving Mobile Project Automation
As apps become more complex, teams need to manage their project configuration in safer, more automated ways. For example, keeping an auto-incrementing build number, or applying a set of project changes for a while-labeled app. These tasks are slow and error-prone to do by hand, and the current best alternative is to write custom configuration scripts that are hard to build and even harder to maintain.
With Trapeze, these tasks are as simple as defining the changes in a YAML file and running the Trapeze Configure tool. For example, the incrementBuild
operation increments the build number each time the tool is run:
platforms:
ios:
incrementBuild: true
npx trapeze run config.yml
Trapeze comes with a large set of supported operations across iOS and Android, as well as some other useful operations that can work across projects.
Common Tasks
Some examples of tasks that Trapeze is well suited for:
Build Settings
Adjusting build settings and basic app configuration can be done in a central place:
vars:
BUNDLE_ID:
default: io.ionic.app
PACKAGE_NAME:
default: io.ionic.app
platforms:
ios:
targets:
App:
bundleId: $BUNDLE_ID
version: 16.4
buildNumber: 198
productName: Awesome App
displayName: My Awesome App
android:
packageName: $PACKAGE_NAME
versionName: 5.2.1
versionCode: 197
Build-specific Configuration Files
Apps often have to provide different configuration files and values when building for different environments (dev/qa/prod/etc). For example, swapping out values in a google-services.json
file depending on the environment:
vars:
GOOGLE_PROJECT_ID:
default: "default_id"
platforms:
android:
json:
- file: google-services.json
set:
project_info:
project_id: $GOOGLE_PROJECT_ID
ios:
targets:
App:
json:
- file: google-services.json
set:
project_info:
project_id: $GOOGLE_PROJECT_ID
i18n and l10n
Swapping out translations and other localized values can be done by modifying the relevant platform-specific files (such as .strings on iOS and XML resource files on Android):
platforms:
ios:
targets:
App:
strings:
- file: App/Lang/fr.strings
set:
"App name": Name
android:
- resFile: values-fr/strings.xml
target: resources/string[@name="app_name"]
replace: |
<string name="app_name">Name</string>
This is just a taste of the use-cases for Trapeze!
Support for Environment Variables
Trapeze can work with Environment variables, including complex JSON-valued ones. When running interactively, Trapeze can prompt the user to provide values for all specified variables, if they aren’t already defined in the environment. For JSON values, Trapeze supports substituting in portions of the YAML configuration for complex variable substitution.
vars:
KEYCHAIN_GROUPS:
default:
[
'$BUNDLE_ID',
]
platforms:
ios:
targets:
App:
entitlements:
- keychain-access-groups: $KEYCHAIN_GROUPS
CI/CD Ready
As more teams start to adopt a Mobile CI/CD workflow, such as those using our Appflow Mobile CI/CD service, we’ve seen a rise in questions around automating project configuration in these systems.
Trapeze was built with CI/CD in mind, and is a perfect fit for Appflow. For example, here is how developers would run a Trapeze configuration step in their build pipeline, before the app is packaged by Appflow:
"scripts": {
"appflow:build": "npx trapeze run appflow.yml -y && npm run build"
},
For Plugin Authors
Another key audience we have in mind for Trapeze are plugin authors. Often, plugins require some manual project configuration in order to install. This can be difficult for users of these plugins and result in incorrectly configured apps and increased support burden.
To fix this, plugin authors can ship a Trapeze YAML file and then apply it after plugin install. Combined with interactive environment variable support, users of the plugin can be prompted to customize the values their project will be configured with.
Let’s look at two real plugin examples to see how this might be used.
The first one is the Capacitor Camera plugin. On iOS and Android some additional permission configuration needs to be set by the developer before the plugin can be used. We could supply a Trapeze configuration file to prompt the user for these values and modify the project for them automatically:
platforms:
ios:
targets:
App:
plist:
- entries:
- NSCameraUsageDescription: "Take photos"
- NSPhotoLibraryAddUsageDescription: "Add photos"
- NSPhotoLibraryUsageDescription: "Access photos"
android:
manifest:
- file: AndroidManifest.xml
target: manifest/application
inject:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
On another one of Ionic’s plugins, a set of build options and Android manifest changes need to be applied after the plugin is installed.
platforms:
ios:
targets:
App:
buildSettings:
ENABLE_BITCODE: false
STRIP_SWIFT_SYMBOLS: false
plist:
replace: false
entries:
- CFBundleURLTypes:
- CFBundleURLSchemes:
- msauth.$(PRODUCT_BUNDLE_IDENTIFIER)
- msauth.$(PRODUCT_BUNDLE_IDENTIFIER)-intunemam
- msauth.com.microsoft.intunemam
android:
manifest:
- file: AndroidManifest.xml
target: manifest
inject: |
<queries>
<!-- ... -->
</queries>
Both of these file can be run by the user after installing the plugin or automatically using postinstall hooks.
What’s Next?
The goal for Trapeze is to support all of the file formats and project automation tasks that mobile developers need. Early growth is exciting and we are frequently adding new features based on feedback.
To give Trapeze a try, visit trapeze.dev and install the tool to start running project modification tasks. The project is 100% free and open source and we’d love your feedback on the GitHub repo.