skip-dev
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSkip Multiplatform Development
Skip 多平台开发
Overview
概述
Skip (https://skip.dev) enables building native iOS and Android apps from a single Swift/SwiftUI codebase. It works as an Xcode plugin that continuously generates an equivalent Android project using Jetpack Compose. iOS runs SwiftUI directly; Android uses Skip-generated Kotlin/Compose code.
Skip(https://skip.dev)支持通过单一 Swift/SwiftUI 代码库构建原生 iOS 和 Android 应用。它作为 Xcode 插件运行,可持续生成使用 Jetpack Compose 的等效 Android 项目。iOS 直接运行 SwiftUI;Android 使用 Skip 生成的 Kotlin/Compose 代码。
Decision Tree: Skip Mode Selection
决策树:Skip 模式选择
Before writing code, determine the correct Skip mode:
Is this a NEW project?
├── YES → Does it need C/C++ code or complex Swift features?
│ ├── YES → Use Skip Fuse (native)
│ └── NO → Does app size matter (Fuse adds ~60MB)?
│ ├── YES → Use Skip Lite (transpiled)
│ └── NO → Use Skip Fuse (native) — preferred default
└── NO → Check skip.yml for `mode:` setting
├── mode: 'native' → Skip Fuse
└── mode: 'transpiled' → Skip Lite编写代码前,请确定正确的 Skip 模式:
Is this a NEW project?
├── YES → Does it need C/C++ code or complex Swift features?
│ ├── YES → Use Skip Fuse (native)
│ └── NO → Does app size matter (Fuse adds ~60MB)?
│ ├── YES → Use Skip Lite (transpiled)
│ └── NO → Use Skip Fuse (native) — preferred default
└── NO → Check skip.yml for `mode:` setting
├── mode: 'native' → Skip Fuse
└── mode: 'transpiled' → Skip LiteSkip Fuse (Native Mode)
Skip Fuse(原生模式)
- Compiles Swift natively for Android using the Swift SDK for Android
- Full Swift language support, faithful runtime, complete stdlib/Foundation
- Can integrate C/C++ libraries
- Trade-off: +60MB app size, requires bridging for Kotlin interop, slower builds
- 使用 Android Swift SDK 为 Android 原生编译 Swift
- 完整支持 Swift 语言、忠实的运行时环境、完整的标准库/Foundation
- 可集成 C/C++ 库
- 权衡点:应用体积增加约60MB,Kotlin 互操作需要桥接,构建速度较慢
Skip Lite (Transpiled Mode)
Skip Lite(转译模式)
- Converts Swift source code → Kotlin source code
- Direct access to Kotlin/Java APIs from blocks
#if SKIP - Smaller app size, faster builds, more transparent output
- Trade-off: limited Swift language features, limited stdlib support
- 将 Swift 源代码转换为 Kotlin 源代码
- 可从 代码块直接访问 Kotlin/Java API
#if SKIP - 应用体积更小、构建速度更快、输出更透明
- 权衡点:Swift 语言特性支持有限,标准库支持有限
Configuration in skip.yml
skip.yml 配置
yaml
undefinedyaml
undefinedFor Fuse (native) mode:
For Fuse (native) mode:
mode: 'native'
bridging: true
mode: 'native'
bridging: true
For Lite (transpiled) mode:
For Lite (transpiled) mode:
mode: 'transpiled'
undefinedmode: 'transpiled'
undefinedProject Structure
项目结构
App Projects
应用项目
MyApp/
├── Package.swift # SPM dependencies & targets
├── Skip.env # Skip environment config
├── Sources/
│ ├── MyApp/ # Main app module (SwiftUI views)
│ │ ├── MyApp.swift # App entry point (@main)
│ │ ├── ContentView.swift
│ │ └── Skip/ # Android-specific Kotlin files
│ │ └── skip.yml # Skip module configuration
│ └── MyAppModel/ # Shared model module
│ ├── DataModel.swift
│ └── Skip/
│ └── skip.yml
├── Tests/
│ ├── MyAppTests/
│ └── MyAppModelTests/
├── Darwin/ # iOS-specific
│ ├── MyApp.xcodeproj
│ ├── MyApp.xcconfig
│ ├── Assets.xcassets/
│ └── Info.plist
└── Android/ # Android-specific
├── settings.gradle.kts
└── app/
├── build.gradle.kts
├── src/main/AndroidManifest.xml
└── src/main/kotlin/.../Main.ktMyApp/
├── Package.swift # SPM dependencies & targets
├── Skip.env # Skip environment config
├── Sources/
│ ├── MyApp/ # Main app module (SwiftUI views)
│ │ ├── MyApp.swift # App entry point (@main)
│ │ ├── ContentView.swift
│ │ └── Skip/ # Android-specific Kotlin files
│ │ └── skip.yml # Skip module configuration
│ └── MyAppModel/ # Shared model module
│ ├── DataModel.swift
│ └── Skip/
│ └── skip.yml
├── Tests/
│ ├── MyAppTests/
│ └── MyAppModelTests/
├── Darwin/ # iOS-specific
│ ├── MyApp.xcodeproj
│ ├── MyApp.xcconfig
│ ├── Assets.xcassets/
│ └── Info.plist
└── Android/ # Android-specific
├── settings.gradle.kts
└── app/
├── build.gradle.kts
├── src/main/AndroidManifest.xml
└── src/main/kotlin/.../Main.ktFramework Projects (SPM Packages)
框架项目(SPM 包)
MyFramework/
├── Package.swift
├── Sources/
│ └── MyFramework/
│ ├── MyFramework.swift
│ └── Skip/
│ └── skip.yml
└── Tests/
└── MyFrameworkTests/
└── MyFrameworkTests.swiftKey point: Frameworks do NOT have Darwin/ or Android/ folders. The Android build is triggered by running unit tests, not by building an app.
MyFramework/
├── Package.swift
├── Sources/
│ └── MyFramework/
│ ├── MyFramework.swift
│ └── Skip/
│ └── skip.yml
└── Tests/
└── MyFrameworkTests/
└── MyFrameworkTests.swift关键点:框架项目没有 Darwin/ 或 Android/ 文件夹。Android 构建是通过运行单元测试触发的,而非构建应用。
Building
构建
Apps: Build from Xcode
应用:从 Xcode 构建
- Open the in
.xcodeprojDarwin/ - Select an iOS Simulator destination
- Build & Run — the Skip plugin automatically generates and builds the Android project
- Android output appears in the group in the Xcode project navigator
SkipStone/plugins
Android build behavior is controlled in :
.xcconfigSKIP_ACTION = launch # Build and launch Android emulator (default)
SKIP_ACTION = build # Build Android only, don't launch
SKIP_ACTION = none # Skip Android build entirely- 打开 目录下的
Darwin/.xcodeproj - 选择 iOS 模拟器作为目标设备
- 构建并运行 — Skip 插件会自动生成并构建 Android 项目
- Android 输出将显示在 Xcode 项目导航器的 组中
SkipStone/plugins
Android 构建行为由 控制:
.xcconfigSKIP_ACTION = launch # Build and launch Android emulator (default)
SKIP_ACTION = build # Build Android only, don't launch
SKIP_ACTION = none # Skip Android build entirelyApps: Build from CLI
应用:从 CLI 构建
bash
undefinedbash
undefinedBuild iOS project
Build iOS project
xcodebuild -project Darwin/MyApp.xcodeproj -scheme MyApp
-destination 'platform=iOS Simulator,name=iPhone 17 Pro,OS=latest' build
-destination 'platform=iOS Simulator,name=iPhone 17 Pro,OS=latest' build
xcodebuild -project Darwin/MyApp.xcodeproj -scheme MyApp
-destination 'platform=iOS Simulator,name=iPhone 17 Pro,OS=latest' build
-destination 'platform=iOS Simulator,name=iPhone 17 Pro,OS=latest' build
Export Android APK
Export Android APK
skip export --project Darwin/MyApp.xcodeproj --appid com.example.myapp
undefinedskip export --project Darwin/MyApp.xcodeproj --appid com.example.myapp
undefinedFrameworks: Trigger Android Build via Tests
框架:通过测试触发 Android 构建
bash
undefinedbash
undefinedRun against macOS destination to trigger Android build
Run against macOS destination to trigger Android build
swift test
swift test
OR
OR
skip test
**Critical:** You MUST run framework tests against a **macOS** destination to perform an Android build. Testing against an iOS destination will NOT run Android tests.skip test
**重要提示**:必须针对 **macOS** 目标运行框架测试才能执行 Android 构建。针对 iOS 目标测试不会运行 Android 测试。Debugging
调试
iOS Debugging
iOS 调试
- Standard Xcode debugging: breakpoints, LLDB, view hierarchy inspector
- Use for logging (NOT
OSLog.Logger— print doesn't work on Android)print()
swift
import OSLog
let logger = Logger(subsystem: "com.example.myapp", category: "networking")
logger.info("Request started: \(url)")
logger.error("Request failed: \(error.localizedDescription)")- 标准 Xcode 调试:断点、LLDB、视图层次结构检查器
- 使用 进行日志记录(不要使用
OSLog.Logger— print 在 Android 上无法工作)print()
swift
import OSLog
let logger = Logger(subsystem: "com.example.myapp", category: "networking")
logger.info("Request started: \(url)")
logger.error("Request failed: \(error.localizedDescription)")Android Debugging
Android 调试
- Logcat — primary Android debugging tool:
bash
undefined- Logcat — 主要的 Android 调试工具:
bash
undefinedFilter logs by app tag
Filter logs by app tag
adb logcat -s MyApp
adb logcat -s MyApp
Filter by Skip logger output
Filter by Skip logger output
adb logcat | grep "com.example.myapp"
2. **Android Studio** — open the generated Gradle project:
- For apps: find generated source under `SkipStone/plugins` in Xcode navigator → right-click → "Open in Android Studio"
- For frameworks: open the `SkipLink/` folder in Android Studio
3. **View generated Kotlin code** — invaluable for debugging transpilation issues:
- In Xcode, expand `SkipStone/plugins` (apps) or `SkipLink` (frameworks)
- Find the `.kt` files corresponding to your Swift source
- Use Kotlin compiler line numbers to locate the failing generated statement, then map it back to the matching Swift declaration
- Apply fixes in Swift source (or Skip Comments), then rebuild; do not edit generated `.kt` files directly (they are overwritten)
4. **Crash traces** — demangle Swift symbols:
```bash
xcrun swift-demangle <mangled_symbol>adb logcat | grep "com.example.myapp"
2. **Android Studio** — 打开生成的 Gradle 项目:
- 对于应用:在 Xcode 导航器中找到 `SkipStone/plugins` 下的生成源码 → 右键 → "在 Android Studio 中打开"
- 对于框架:在 Android Studio 中打开 `SkipLink/` 文件夹
3. **查看生成的 Kotlin 代码** — 对调试转译问题非常重要:
- 在 Xcode 中展开 `SkipStone/plugins`(应用)或 `SkipLink`(框架)
- 找到与 Swift 源码对应的 `.kt` 文件
- 使用 Kotlin 编译器行号定位失败的生成语句,然后映射回对应的 Swift 声明
- 在 Swift 源码(或 Skip 注释)中应用修复,然后重新构建;不要直接编辑生成的 `.kt` 文件(它们会被覆盖)
4. **崩溃追踪** — 还原 Swift 符号:
```bash
xcrun swift-demangle <mangled_symbol>Common Build Errors
常见构建错误
| Error | Cause | Fix |
|---|---|---|
| Skip plugin not installed | Run |
| Unsupported Swift API on Android | Use |
| Gradle sync failure | Android SDK issue | Run |
| Missing bridge annotation | Add |
| Using unsupported SkipUI feature | Check SkipUI docs; provide Android-specific alternative |
| 错误 | 原因 | 修复方案 |
|---|---|---|
| Skip 插件未安装 | 运行 |
| Android 不支持该 Swift API | 使用 |
| Gradle 同步失败 | Android SDK 问题 | 运行 |
| 缺少桥接注解 | 添加 |
| 使用了不支持的 SkipUI 特性 | 查看 SkipUI 文档;提供 Android 特定的替代方案 |
Transpilation Error Workflow (Using Generated Kotlin)
转译错误处理流程(使用生成的 Kotlin 代码)
When Lite mode transpilation fails, use this quick loop:
- Trigger a build (, Xcode Run, or
xcodebuild) and capture the first Kotlin error.skip test - Open the generated Kotlin file and line from the compiler output (for apps,
SkipStone/pluginsfor frameworks).SkipLink - Identify the original Swift declaration that produced that Kotlin block.
- Fix the Swift source using one of:
- simpler type annotations (especially around generics/optionals)
- platform guards (/
#if os(Android)/#if !os(Android))#if SKIP - Skip Comments (,
SKIP INSERT,SKIP REPLACE,SKIP DECLARE)SKIP NOWARN
- Rebuild and verify the same Kotlin section now compiles.
Rule of thumb: treat generated Kotlin as a diagnostic artifact, not a source of truth. Keep permanent fixes in Swift and support files.
Skip/当 Lite 模式转译失败时,使用以下快速流程:
- 触发构建(、Xcode 运行或
xcodebuild)并捕获第一个 Kotlin 错误。skip test - 打开编译器输出中指定的生成 Kotlin 文件和行(应用为 ,框架为
SkipStone/plugins)。SkipLink - 识别生成该 Kotlin 代码块的原始 Swift 声明。
- 使用以下方式修复 Swift 源码:
- 更简单的类型注解(尤其是泛型/可选类型)
- 平台保护(/
#if os(Android)/#if !os(Android))#if SKIP - Skip 注释(、
SKIP INSERT、SKIP REPLACE、SKIP DECLARE)SKIP NOWARN
- 重新构建并验证同一 Kotlin 部分现在可以编译。
经验法则:将生成的 Kotlin 代码视为诊断工件,而非事实来源。永久修复应保留在 Swift 和 支持文件中。
Skip/Testing
测试
Running Tests
运行测试
bash
undefinedbash
undefinedSwift tests only (iOS)
Swift tests only (iOS)
swift test
swift test
Cross-platform parity tests (iOS + Android via Robolectric)
Cross-platform parity tests (iOS + Android via Robolectric)
skip test
skip test
Android emulator tests
Android emulator tests
ANDROID_SERIAL=emulator-5554 skip test
undefinedANDROID_SERIAL=emulator-5554 skip test
undefinedWriting Cross-Platform Tests
编写跨平台测试
swift
import XCTest
final class MyTests: XCTestCase {
func testSharedLogic() {
// Runs on both platforms
XCTAssertEqual(calculate(2, 3), 5)
}
#if !os(Android)
func testIOSOnly() {
// iOS-specific test
}
#endif
#if os(Android) || ROBOLECTRIC
func testAndroidOnly() {
// Android-specific test (runs on Robolectric too)
}
#endif
}swift
import XCTest
final class MyTests: XCTestCase {
func testSharedLogic() {
// Runs on both platforms
XCTAssertEqual(calculate(2, 3), 5)
}
#if !os(Android)
func testIOSOnly() {
// iOS-specific test
}
#endif
#if os(Android) || ROBOLECTRIC
func testAndroidOnly() {
// Android-specific test (runs on Robolectric too)
}
#endif
}Robolectric Testing
Robolectric 测试
Skip uses Robolectric for fast, Mac-based Android testing without an emulator. Use to include tests that should run on both Android emulator and Robolectric.
#if os(Android) || ROBOLECTRICSkip 使用 Robolectric 进行快速的基于 Mac 的 Android 测试,无需模拟器。使用 包含应在 Android 模拟器和 Robolectric 上都运行的测试。
#if os(Android) || ROBOLECTRICConditional Compilation
条件编译
Platform Directives
平台指令
swift
#if os(Android)
// Android-only code
#else
// iOS-only code
#endif
#if !os(Android)
// iOS-only code
#endif
#if SKIP
// Only in transpiled Kotlin code (Skip Lite)
// Can call Kotlin/Java APIs directly here
#endif
#if !SKIP
// Only in native Swift (iOS, or Fuse Android)
#endif
#if ROBOLECTRIC
// Only during Robolectric test execution
#endifswift
#if os(Android)
// Android-only code
#else
// iOS-only code
#endif
#if !os(Android)
// iOS-only code
#endif
#if SKIP
// Only in transpiled Kotlin code (Skip Lite)
// Can call Kotlin/Java APIs directly here
#endif
#if !SKIP
// Only in native Swift (iOS, or Fuse Android)
#endif
#if ROBOLECTRIC
// Only during Robolectric test execution
#endifSkip Comments
Skip 注释
Skip Comments control how Swift code is transpiled to Kotlin:
swift
// SKIP INSERT: val androidSpecificVal = "only in Kotlin output"
// SKIP REPLACE: fun customKotlinImplementation() { ... }
func swiftImplementation() { ... }
// SKIP DECLARE: annotation class MyAnnotation
// SKIP DECLARE: typealias PlatformType = android.content.Context
// SKIP NOWARN
let _ = someUnsupportedPattern // Suppresses transpilation warning
// SKIP @bridge
public func bridgedFunction() { } // Exposes to Kotlin in Fuse mode
// SKIP @nobridge
public func noBridge() { } // Prevents bridging
// SKIP @nocopy
struct LargeData { } // Skip copy semantics for structs
// SKIP SYMBOLFILE
// Generates .skipmodule symbol file for the moduleSkip 注释控制 Swift 代码如何转译为 Kotlin:
swift
// SKIP INSERT: val androidSpecificVal = "only in Kotlin output"
// SKIP REPLACE: fun customKotlinImplementation() { ... }
func swiftImplementation() { ... }
// SKIP DECLARE: annotation class MyAnnotation
// SKIP DECLARE: typealias PlatformType = android.content.Context
// SKIP NOWARN
let _ = someUnsupportedPattern // Suppresses transpilation warning
// SKIP @bridge
public func bridgedFunction() { } // Exposes to Kotlin in Fuse mode
// SKIP @nobridge
public func noBridge() { } // Prevents bridging
// SKIP @nocopy
struct LargeData { } // Skip copy semantics for structs
// SKIP SYMBOLFILE
// Generates .skipmodule symbol file for the moduleSkip CLI Quick Reference
Skip CLI 速查参考
bash
skip create # Interactive project creation wizard
skip init # Non-interactive project init
skip test # Run cross-platform tests
skip export # Export Android APK/AAB
skip checkup # Verify Skip installation
skip doctor # Diagnose and fix issues
skip upgrade # Update Skip to latest version
skip verify # Verify project configurationbash
skip create # Interactive project creation wizard
skip init # Non-interactive project init
skip test # Run cross-platform tests
skip export # Export Android APK/AAB
skip checkup # Verify Skip installation
skip doctor # Diagnose and fix issues
skip upgrade # Update Skip to latest version
skip verify # Verify project configurationAndroid-specific
Android-specific
skip android build # Build Android project
skip android test # Run Android tests
skip android emulator create # Create AVD emulator
skip android emulator launch # Launch emulator
skip android sdk install # Install Android SDK components
skip android sdk list # List available SDK packages
undefinedskip android build # Build Android project
skip android test # Run Android tests
skip android emulator create # Create AVD emulator
skip android emulator launch # Launch emulator
skip android sdk install # Install Android SDK components
skip android sdk list # List available SDK packages
undefinedReferences
参考文献
For detailed reference material, load from the directory:
references/- — Swift language features support table, builtin types, generics, structs, concurrency, numeric types, plus a Kotlin-output troubleshooting workflow for transpilation failures
references/transpilation.md - — Supported SwiftUI components, ComposeView integration, composeModifier, Material3 customization, animation, images, navigation, lists, gestures
references/skip-ui.md - — Calling Kotlin/Java APIs, Compose integration, AnyDynamicObject, Kotlin files in Sources, Android Studio workflow, model integration patterns
references/cross-platform.md - — skip.yml configuration, @bridge/@bridgeMembers/@nobridge annotations, bridging Swift↔Kotlin, kotlincompat option, AnyDynamicObject usage
references/bridging.md - — Adding Skip/SwiftPM/Java/Kotlin dependencies, platform-conditional dependencies, skip.yml build blocks
references/dependencies.md - — Full Skip CLI command reference with options, examples, and common workflows
references/cli.md - — How unit testing works in Skip, execution model (
references/unit-testing.mdvsswift test), cross-platform test patterns, Robolectric usage, and CI strategyskip test
Load a reference with:
read_file('<base_dir>/references/<filename>')如需详细参考资料,请从 目录加载:
references/- — Swift 语言特性支持表、内置类型、泛型、结构体、并发、数值类型,以及针对转译失败的 Kotlin 输出故障排除流程
references/transpilation.md - — 支持的 SwiftUI 组件、ComposeView 集成、composeModifier、Material3 自定义、动画、图片、导航、列表、手势
references/skip-ui.md - — 调用 Kotlin/Java API、Compose 集成、AnyDynamicObject、Sources 中的 Kotlin 文件、Android Studio 工作流、模型集成模式
references/cross-platform.md - — skip.yml 配置、@bridge/@bridgeMembers/@nobridge 注解、Swift↔Kotlin 桥接、kotlincompat 选项、AnyDynamicObject 使用
references/bridging.md - — 添加 Skip/SwiftPM/Java/Kotlin 依赖、平台条件依赖、skip.yml 构建块
references/dependencies.md - — 完整的 Skip CLI 命令参考,包含选项、示例和常见工作流
references/cli.md - — Skip 中的单元测试工作原理、执行模型(
references/unit-testing.mdvsswift test)、跨平台测试模式、Robolectric 使用和 CI 策略skip test
加载参考资料的命令:
read_file('<base_dir>/references/<filename>')