Cargo runner for Apple targets
Easily bundle, sign and launch binaries on Apple targets, including on the simulator and on real devices.
Usage
Install with:
And add the following to your project's .cargo/config.toml:
[]
= "cargo-apple-runner"
Now you can test and run your (GUI) applications on the iOS simulator with:
# etc.
Or on Mac Catalyst with:
Supported platforms and requirements
Host: Requires at least macOS 10.12, same as rustc.
Targets: macOS, Mac Catalyst, iOS, tvOS, watchOS and visionOS.
Simulators: Uses xcrun simctl, only tested on Xcode 9.2 and above.
Devices: Yet unsupported, will use devicectl (see #1) and fall back to ios-deploy (see #2) on older Xcode.
Bundling
cargo-apple-runner will inspect your binary, and guess whether it needs to bundle it based on a few factors:
- Whether your binary links AppKit, UIKit, WatchKit and similar system GUI frameworks.
- TODO: Maybe something more?
- TODO: Allow overriding this somehow?
Note that this might mean that for documentation tests to be runnable in parallel with cargo nextest, you might need to use the standalone_crate attribute on GUI tests to avoid these making your other doc tests need to be launched as well.
Custom Info.plist
Most real-world applications will want to modify the data in the application's Info.plist, you can use the embed_plist crate to do so:
embed_plist!;
If this is not done, cargo-apple-runner will generate a reasonable Info.plist for you.
Signing
cargo-apple-runner will sign your application with whatever signing identity is passed in the CODE_SIGN_IDENTITY environment variable. If not set, it will default to "ad-hoc" signing.
Custom entitlements
In some cases, you might need to request different entitlements for your application.
You can use the embed_entitlements crate to do so:
embed_entitlements!;
Note that when building for a real (non-simulator) device, you will need to configure a provisioning profile with those entitlements allowed. On macOS, certain entitlements are allowed by default, see this tech note.
As a small optimization when using entitlements, you can consider adding the following to .cargo/config.toml to reduce link-time (since signing will be done by the runner):
[]
# Signing is done by `cargo-apple-runner`.
= ["-Clink-arg=-Wl,-no_adhoc_codesign"]
Launching
Similar to when bundling, cargo-apple-runner will also guess whether it needs to launch your binary, or whether it can simply spawn it.
Spawning is generally more efficient, since it can be done in parallel, while launching must be serialized (as only a single application can be the frontmost application).
Usage in CI
Example GitHub Actions workflow that runs tests on macOS, Mac Catalyst, the iOS simulator, the tvOS simulator and the visionOS simulator.
# ...
jobs:
test:
runs-on: macos-latest
# Configure the job to use `cargo-apple-runner` when launching our binaries.
# (Alternatively, you could commit the `.cargo/config.toml` above).
env:
CARGO_TARGET_AARCH64_APPLE_DARWIN_RUNNER: cargo-apple-runner
CARGO_TARGET_AARCH64_APPLE_IOS_MACABI_RUNNER: cargo-apple-runner
CARGO_TARGET_AARCH64_APPLE_IOS_SIM_RUNNER: cargo-apple-runner
CARGO_TARGET_AARCH64_APPLE_TVOS_SIM_RUNNER: cargo-apple-runner
CARGO_TARGET_AARCH64_APPLE_VISIONOS_SIM_RUNNER: cargo-apple-runner
steps:
- uses: taiki-e/checkout-action@v1
- name: Install Rustup targets
run: rustup target add aarch64-apple-ios-macabi aarch64-apple-ios-sim aarch64-apple-tvos-sim
- name: Install `cargo-apple-runner`
uses: taiki-e/install-action@cargo-apple-runner
- uses: Swatinem/rust-cache@v2
# You can find names of existing simulator devices at:
# https://github.com/actions/runner-images/blob/main/images/macos/macos-26-arm64-Readme.md#installed-simulators
- name: Start iOS simulator
run: xcrun simctl boot "iPhone 17"
- name: Start tvOS simulator
run: xcrun simctl boot "Apple TV"
- name: Start visionOS simulator
run: xcrun simctl boot "Apple Vision Pro"
- name: Run tests on host macOS
run: cargo test
- name: Run Mac Catalyst tests
run: cargo test --target aarch64-apple-ios-macabi
- name: Run iOS simulator tests
run: cargo test --target aarch64-apple-ios-sim
- name: Run tvOS simulator tests
run: cargo test --target aarch64-apple-tvos-sim
- name: Run visionOS simulator tests
run: cargo test --target aarch64-apple-visionos-sim
Limitations
This is intended as a development tool only; when deploying on real devices, consider using something else. I can recommend cargo-xcode, this gives the most control and helps with the complex process of notarizing and submitting to the App Store.
Will only supports bundled assets (at least after #5), reading from other directories may fail (we don't copy the entire workspace to the device).
Only a few Cargo environment variables are automatically passed onwards to the simulator, use SIMCTL_CHILD_* to explicitly pass the environment variables you want to pass to the program being run.
License
This project is trio-licensed under the Zlib, Apache-2.0 or MIT license, at your option.
Credits
- Original idea for this by @simlay: https://simlay.net/posts/rust-target-runner-for-ios/
- cargo-bundle
- cargo-dinghy
- cargo-mobile2
- tauri-bundler
- apple-platform-rs