iOS
基于 Rust 的 Slint 应用程序可以交叉编译到 iOS,并在 iPhone、iPad 及其各自的 模拟器上运行。这是通过 Winit 后端 和
Skia 渲染器 实现的。
- 一台运行 macOS 的电脑。
- 最新安装的 Xcode。
- Xcodegen。
- Rust
- Rust 设备端和模拟器工具链。运行
rustup target add aarch64-apple-ios和rustup target add aarch64-apple-ios-sim来添加它们。
为现有的 Rust 应用程序添加 iOS 支持
Section titled “为现有的 Rust 应用程序添加 iOS 支持”以下步骤假设你已经准备好一个使用 Slint 的 Rust 应用程序。如果你刚入门,请使用我们的 Slint Rust Template 让一个最小应用跑起来。
使用 XCode 构建、部署 iOS 应用程序并提交到 App Store。 使用 Xcodegen 从一份最简描述创建 Xcode 项目。
- 通过运行以下命令,验证你的应用程序能为 iOS 编译:
cargo build --target=aarch64-apple-ios- 创建一个名为
project.yml的文件,内容如下:
name: My Appoptions: bundleIdPrefix: com.companysettings: ENABLE_USER_SCRIPT_SANDBOXING: NOtargets: MyApp: type: application platform: iOS deploymentTarget: '13.0' info: path: Info.plist properties: CADisableMinimumFrameDurationOnPhone: true UILaunchScreen: - ImageRespectSafeAreaInsets: false UIApplicationSceneManifest: UIApplicationSupportsMultipleScenes: false UISceneConfigurations: UIWindowSceneSessionRoleApplication: - UISceneConfigurationName: Slint UISceneDelegateClassName: SlintWindowSceneDelegate sources: [] postCompileScripts: - script: | ./build_for_ios_with_cargo.bash slint-rust-template outputFileLists: $TARGET_BUILD_DIR/$EXECUTABLE_PATH根据需要调整名称、bundle id 和其他字段。
这个配置文件通过一个 shell 脚本把构建过程委托给 cargo。
CADisableMinimumFrameDurationOnPhone 条目让动画以屏幕的
完整刷新率运行。
没有它,即使 ProMotion 显示屏支持 120,iOS 也会把 iPhone 应用限制在每秒 60 帧。
iPad 不受影响。
UIApplicationSceneManifest 条目让应用选择使用 UIKit 的场景生命周期,
这是 iOS 27 所要求的:没有它的应用会启动失败。
SlintWindowSceneDelegate 是 Slint 的 winit 后端提供的场景委托,
它把 Slint 的窗口附加到 UIKit 所连接的场景。
保持该条目原样。
关于此要求的背景,请参见 Apple 的
TN3187。
- 在一个名为
build_for_ios_with_cargo.bash的新文件中,粘贴以下脚本代码:
#!/usr/bin/env bash# Copyright © SixtyFPS GmbH <info@slint.dev># SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
set -euvx
# Fix up PATH to work around https://github.com/rust-lang/rust/issues/80817 and add cargo.export PATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:$PATH:$HOME/.cargo/bin"
# based on https://github.com/mozilla/glean/blob/main/build-scripts/xc-universal-binary.sh
if [[ "$CONFIGURATION" != "Debug" ]]; then CARGO_PROFILE=release MAYBE_RELEASE=--releaseelse CARGO_PROFILE=debug MAYBE_RELEASE=fi
# Build with debug info so a dSYM can be produced below. Release builds carry no# debug info by default, which makes the archive fail validation with a missing# dSYM for the (cargo-built) executable.export CARGO_PROFILE_RELEASE_DEBUG="${CARGO_PROFILE_RELEASE_DEBUG:-1}"
# Make Cargo output cache files in Xcode's directoriesexport CARGO_TARGET_DIR="$DERIVED_FILE_DIR/cargo"
# Xcode Cloud exposes its build counter as CI_BUILD_NUMBER. Forward it as# SLINT_BUILD_NUMBER so the viewer's idle screen can show which CI build it# came from. Local Xcode builds don't set CI_BUILD_NUMBER, in which case we# leave SLINT_BUILD_NUMBER unset and the idle screen omits the build line.if [ -n "${CI_BUILD_NUMBER:-}" ]; then export SLINT_BUILD_NUMBER="$CI_BUILD_NUMBER"fi
IS_SIMULATOR=0if [ "${LLVM_TARGET_TRIPLE_SUFFIX-}" = "-simulator" ]; then IS_SIMULATOR=1fi
executables=()for arch in $ARCHS; do case "$arch" in arm64) if [ $IS_SIMULATOR -eq 0 ]; then CARGO_TARGET=aarch64-apple-ios else CARGO_TARGET=aarch64-apple-ios-sim fi ;; x86_64) export CFLAGS_x86_64_apple_ios="-target x86_64-apple-ios" CARGO_TARGET=x86_64-apple-ios ;; esac
cargo build $MAYBE_RELEASE --target $CARGO_TARGET --bin "$1" "${@:2}"
executables+=("$DERIVED_FILE_DIR/cargo/$CARGO_TARGET/$CARGO_PROFILE/$1")done
# Combine executables, and place them at the output path excepted by Xcodelipo -create -output "$TARGET_BUILD_DIR/$EXECUTABLE_PATH" "${executables[@]}"
# Generate a dSYM for the executable into the folder Xcode collects dSYMs from# for the archive. Xcode only produces dSYMs for what it compiles, not for this# cargo-built binary, so without this the archive has no dSYM matching its UUID.if [ -n "${DWARF_DSYM_FOLDER_PATH:-}" ] && [ -n "${DWARF_DSYM_FILE_NAME:-}" ]; then mkdir -p "$DWARF_DSYM_FOLDER_PATH" dsymutil "$TARGET_BUILD_DIR/$EXECUTABLE_PATH" -o "$DWARF_DSYM_FOLDER_PATH/$DWARF_DSYM_FILE_NAME"fi
# Force code signing every run for device builds (non-simulator), unless code# signing is disabled (e.g. unsigned archive builds with CODE_SIGNING_ALLOWED=NO).if [ $IS_SIMULATOR -eq 0 ] && [ "${CODE_SIGNING_ALLOWED:-YES}" != "NO" ] && [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" ]; then # Only pass --entitlements when the .xcent file is non-empty (needed for Xcode Cloud). ENTITLEMENTS_FILE="${TARGET_TEMP_DIR}/${PRODUCT_NAME}.app.xcent" if [ -s "$ENTITLEMENTS_FILE" ]; then codesign --force --sign "${EXPANDED_CODE_SIGN_IDENTITY}" \ --entitlements "$ENTITLEMENTS_FILE" \ "${TARGET_BUILD_DIR}/${EXECUTABLE_PATH}" else codesign --force --sign "${EXPANDED_CODE_SIGN_IDENTITY}" \ "${TARGET_BUILD_DIR}/${EXECUTABLE_PATH}" fifi-
用
chmod +x build_for_ios_with_cargo.bash使脚本可执行。 -
运行
xcodegen创建My App.xcodeproj,并在 Xcode 中打开它。现在你可以构建、部署和调试你的 iOS 应用程序。

© 2026 SixtyFPS GmbH