SkipFuseUI
SkipFuseUI 为 Android 上的 Skip Fuse 应用提供 SwiftUI API 接口层。它是一个轻量的 Swift 桥接层,将渲染委托给 SkipUI;后者将 SwiftUI 视图实现为 Jetpack Compose 可组合项。在 iOS 上,import SwiftUI 会像往常一样解析到 Apple 的框架;在 Android 上,它会解析到 SkipFuseUI,让你能够使用同一套 SwiftUI 代码库,并在两个平台上以原生方式运行。
SkipFuseUI 位于你的 SwiftUI 代码与 SkipUI 的 Compose 实现之间。Swift 视图由 Swift Android SDK 原生编译为 Android 代码;渲染时,每个视图都会生成对应的 Kotlin 端 SkipUI 对象,再由 Compose 将其渲染到屏幕上。
flowchart LR
A["Your SwiftUI Code"] --> B["SkipFuseUI\n(Swift on Android)"]
B -->|"Java_view"| C["SkipUI\n(Kotlin/Compose)"]
C --> D["Jetpack Compose\nUI on Screen"]
style A fill:#555555,stroke:#333,color:#fff
style B fill:#6b3fa0,stroke:#4a2d6e,color:#fff
style C fill:#2e6da4,stroke:#1a4a6e,color:#fff
style D fill:#2d7a2d,stroke:#1a5c1a,color:#fff
其核心机制是 SkipUIBridging 协议。SkipFuseUI 中的每种视图类型都通过公开 Java_view 属性来遵循该协议,该属性会返回对应的 SkipUI Kotlin 对象。当 Compose 需要渲染视图层级时,它会遍历 Java_view 引用树;每个引用背后都由 SkipBridge 在 Swift 与 Kotlin 之间进行 JNI 调用。
flowchart TB
subgraph "Your App"
APP["App SwiftUI Code"]
end
subgraph "SkipFuseUI Package"
SFUI["SkipFuseUI\n(re-exports SwiftUI\non Android)"]
SSU["SkipSwiftUI\n(Swift view types,\nproperty wrappers,\nmodifiers)"]
end
subgraph "Bridging Infrastructure"
SB["SkipBridge\n(JNI object lifecycle,\ntype conversion)"]
SF["SkipFuse\n(@Observable,\nOSLog, bridging\nsupport)"]
SAB["SkipAndroidBridge\n(Android-specific\nJNI helpers)"]
SJNI["SwiftJNI\n(low-level JNI\nC/Swift wrapper)"]
end
subgraph "Compose Implementation"
SUI["SkipUI\n(SwiftUI → Jetpack\nCompose mapping)"]
SM["SkipModel\n(Compose state\ntracking)"]
end
APP --> SFUI
SFUI --> SSU
SSU --> SB
SSU --> SF
SSU --> SUI
SB --> SAB
SB --> SJNI
SUI --> SM
style APP fill:#555555,stroke:#333,color:#fff
style SFUI fill:#6b3fa0,stroke:#4a2d6e,color:#fff
style SSU fill:#6b3fa0,stroke:#4a2d6e,color:#fff
style SB fill:#b33030,stroke:#8a1a1a,color:#fff
style SF fill:#b33030,stroke:#8a1a1a,color:#fff
style SAB fill:#b33030,stroke:#8a1a1a,color:#fff
style SJNI fill:#b33030,stroke:#8a1a1a,color:#fff
style SUI fill:#2e6da4,stroke:#1a4a6e,color:#fff
style SM fill:#2e6da4,stroke:#1a4a6e,color:#fff
在 iOS 上,SkipFuseUI 只是重新导出 Apple 的 SwiftUI,整个 SkipSwiftUI 层都不会被编译进来。
SkipFuseUI 中的每种 SwiftUI 类型都遵循同一种模式:由一个 Swift 结构体或类保存视图参数,其 Java_view 属性按需构造对应的 Kotlin 对象。
sequenceDiagram
participant App as Your View (Swift)
participant Fuse as SkipFuseUI VStack (Swift)
participant Bridge as SkipBridge (JNI)
participant UI as SkipUI VStack (Kotlin)
participant Compose as Jetpack Compose
App->>Fuse: VStack { Text("Hello") }
Note over Fuse: Stores alignment,<br/>spacing, content
Compose->>Fuse: Request Java_view
Fuse->>Bridge: Create SkipUI.VStack<br/>with bridged content
Bridge->>UI: JNI call → Kotlin object
UI->>Compose: Emit Column composable
内容视图通过 Java_viewOrEmpty 递归桥接。它会遍历视图树,将每个 Swift 视图转换为对应的 Kotlin 对象。
SwiftUI 属性包装器(@State、@Binding、@AppStorage)由支持桥接的容器类型提供支撑,这些类型会在 Swift 与 Compose 的响应式状态系统之间同步值:
flowchart LR
S["@State var count = 0\n(Swift)"] -->|"BridgedStateBox"| K["StateSupport\n(Kotlin/Compose)"]
K -->|"MutableState"| C["Compose\nRecomposition"]
C -->|"read triggers\naccess()"| S
style S fill:#6b3fa0,stroke:#4a2d6e,color:#fff
style K fill:#2e6da4,stroke:#1a4a6e,color:#fff
style C fill:#2d7a2d,stroke:#1a5c1a,color:#fff
当 Swift 代码写入 @State 属性时,BridgedStateBox 会通知 Compose 的 MutableState,从而触发重新组合。当 Compose 读取该值时,它会通过桥接回调 Swift。这种双向同步可确保 SwiftUI 的声明式状态模型在 Android 上以相同方式工作。
@Observable 类型需要使用 import SkipFuse 才能启用此状态跟踪。详情请参阅应用开发指南。
SkipFuseUI 的覆盖范围
Section titled “SkipFuseUI 的覆盖范围”SkipFuseUI 对 iOS 16 及更高版本的 SwiftUI API 接口进行了映射,包括:
- 容器:
VStack、HStack、ZStack、List、ScrollView、LazyVGrid、LazyHGrid、NavigationStack、TabView、Form、Section、Group - 控件:
Button、Toggle、Slider、Stepper、Picker、DatePicker、TextField、SecureField、TextEditor - 组件:
Text、Image、AsyncImage、Label、Link、ProgressView、Divider、ShareLink - 图形:
Color、Gradient、Shape(Circle、Rectangle、Capsule 等)、Path、Material - 布局:
GeometryReader、Alignment、EdgeInsets、ViewThatFits、Grid - 状态:
@State、@Binding、@Environment、@AppStorage、@FocusState - 修饰符:
.padding、.frame、.background、.overlay、.opacity、.rotation、.shadow、.clipShape、.sheet、.alert、.onAppear、.task等 - 导航:
NavigationStack、NavigationLink、NavigationPath、.navigationTitle、.toolbar - 手势:
TapGesture、LongPressGesture、DragGesture,以及针对受支持手势观察器的部分.simultaneousGesture桥接 - 动画:
withAnimation、.animation、.transition、Spring - UIKit 兼容性:
UIApplication、UIColor、UIImage、UIPasteboard
有关受支持 SwiftUI 组件的完整列表,请参阅 SkipUI 文档。
SkipFuseUI 支持以编程方式控制文本选择,适用于公开 TextSelection 绑定的可编辑文本控件,例如 TextField 和 TextEditor。
使用 String.Index 值创建 TextSelection 时,请使用 TextSelectionRange 和 TextSelectionIndex:
import SkipFuseUI
@State private var text = "https://skip.tools"@State private var selection: TextSelection?
var body: some View { TextField("URL", text: $text, selection: $selection) .onAppear { selection = TextSelection( range: TextSelectionRange(text.startIndex..<text.endIndex, in: text) ) }}对于插入点,请使用 TextSelectionIndex:
selection = TextSelection( insertionPoint: TextSelectionIndex(text.startIndex, in: text))这些包装类型使源代码形式与 SwiftUI 原生的 TextSelection(range:) 和 TextSelection(insertionPoint:) 初始化器保持接近,同时让 SkipFuseUI 能够在 Android 上以一致的方式验证并桥接字符串位置。
- 应用开发 — 使用 Skip 构建双平台应用,包括 UI 和视图模型编码
- Skip 模式 — Fuse 与 Lite 模式的区别及各自适用场景
- 桥接参考 — 支持桥接的 Swift 语言功能和类型
- 跨平台主题 — 使用
#if SKIP和#if os(Android)集成平台专属代码 - SkipUI 模块 — 受支持的 SwiftUI 组件与 Compose 集成主题
- SkipBridge 模块 — SkipFuseUI 所依赖的 JNI 桥接基础设施
- SkipFuse 模块 — 可观察状态跟踪与 Android 运行时支持
skiptools/skip-fuse-ui ↗ 最近发布的 10 个版本:
- 版本 1.18.2 ↗ — 2026-09-08
- 版本 1.18.1 ↗ — 2026-07-23
- 版本 1.18.0 ↗ — 2026-07-18
- 版本 1.17.3 ↗ — 2026-07-02
- 版本 1.17.2 ↗ — 2026-06-24
- 版本 1.17.1 ↗ — 2026-06-17
- 版本 1.17.0 ↗ — 2026-06-13
- 版本 1.16.0 ↗ — 2026-06-02
- 版本 1.15.2 ↗ — 2026-05-25
- 版本 1.15.1 ↗ — 2026-05-15
完整历史记录:github.com/skiptools/skip-fuse-ui/releases ↗ — .atom 订阅源 ↗