You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/content/docs/docs/modules/skip-fuse-ui/index.md
+135-1Lines changed: 135 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -10,5 +10,139 @@ This framework is available at [github.com/skiptools/skip-fuse-ui](https://githu
10
10
:::
11
11
12
12
13
-
Bridging between SwiftUI and Jetpack Compose for [Skip Fuse](/docs/modes/) apps. SkipFuseUI uses [SkipUI](/docs/modules/skip-ui/) under the hood to adapt the SwiftUI APIs to Compose. See its documentation for information about SwiftUI-on-Android.
13
+
SkipFuseUI provides the SwiftUI API surface for [Skip Fuse](/docs/modes/#fuse) apps on Android. It acts as a thin Swift bridging layer that delegates rendering to [SkipUI](/docs/modules/skip-ui/), which implements SwiftUI views as Jetpack Compose composables. On iOS, `import SwiftUI` resolves to Apple's framework as usual; on Android, it resolves to SkipFuseUI, giving you a single SwiftUI codebase that runs natively on both platforms.
14
+
15
+
## How It Works
16
+
17
+
SkipFuseUI sits between your SwiftUI code and SkipUI's Compose implementation. Your Swift views are compiled natively for Android by the Swift Android SDK, and at render time each view produces a Kotlin-side SkipUI counterpart that Compose renders on screen.
18
+
19
+
```mermaid
20
+
flowchart LR
21
+
A["Your SwiftUI Code"] --> B["SkipFuseUI\n(Swift on Android)"]
22
+
B -->|"Java_view"| C["SkipUI\n(Kotlin/Compose)"]
23
+
C --> D["Jetpack Compose\nUI on Screen"]
24
+
25
+
style A fill:#f5f5f5,stroke:#333,color:#fff
26
+
style B fill:#f0e6ff,stroke:#7b2fbe,color:#fff
27
+
style C fill:#e6f0ff,stroke:#4a90d9,color:#fff
28
+
style D fill:#e6ffe6,stroke:#2d8a2d,color:#fff
29
+
```
30
+
31
+
The key mechanism is the `SkipUIBridging` protocol. Every SkipFuseUI view type conforms to it by exposing a `Java_view` property that returns the equivalent SkipUI Kotlin object. When Compose needs to render your view hierarchy, it walks the tree of `Java_view` references — each one backed by [SkipBridge](/docs/modules/skip-bridge/) JNI calls between Swift and Kotlin.
On iOS, `SkipFuseUI` simply re-exports Apple's `SwiftUI` — the entire SkipSwiftUI layer is compiled away.
79
+
80
+
### Bridging Pattern
81
+
82
+
Every SwiftUI type in SkipFuseUI follows the same pattern: a Swift struct or class holds the view's parameters, and its `Java_view` property constructs the Kotlin equivalent on demand.
83
+
84
+
```mermaid
85
+
sequenceDiagram
86
+
participant App as Your View (Swift)
87
+
participant Fuse as SkipFuseUI VStack (Swift)
88
+
participant Bridge as SkipBridge (JNI)
89
+
participant UI as SkipUI VStack (Kotlin)
90
+
participant Compose as Jetpack Compose
91
+
92
+
App->>Fuse: VStack { Text("Hello") }
93
+
Note over Fuse: Stores alignment,<br/>spacing, content
Content views are recursively bridged via `Java_viewOrEmpty`, which walks the view tree and converts each Swift view into its Kotlin counterpart.
101
+
102
+
### State Bridging
103
+
104
+
SwiftUI property wrappers (`@State`, `@Binding`, `@AppStorage`) are backed by bridge-aware box types that synchronize values between Swift and Compose's reactive state system:
105
+
106
+
```mermaid
107
+
flowchart LR
108
+
S["@State var count = 0\n(Swift)"] -->|"BridgedStateBox"| K["StateSupport\n(Kotlin/Compose)"]
109
+
K -->|"MutableState"| C["Compose\nRecomposition"]
110
+
C -->|"read triggers\naccess()"| S
111
+
112
+
style S fill:#f0e6ff,stroke:#7b2fbe,color:#fff
113
+
style K fill:#e6f0ff,stroke:#4a90d9,color:#fff
114
+
style C fill:#e6ffe6,stroke:#2d8a2d,color:#fff
115
+
```
116
+
117
+
When Swift code writes to a `@State` property, the `BridgedStateBox` notifies Compose's `MutableState`, triggering recomposition. When Compose reads the value, it calls back into Swift via the bridge. This two-way sync ensures that SwiftUI's declarative state model works identically on Android.
118
+
119
+
`@Observable` types require `import SkipFuse` to enable this state tracking. See the [App Development](/docs/app-development/#ui) guide for details.
120
+
121
+
## What SkipFuseUI Covers
122
+
123
+
SkipFuseUI mirrors the SwiftUI API surface for iOS 16+, including:
0 commit comments