Apple Integration (UniFFI)
Relevant source files
The following files were used as context for generating this wiki page:
The Apple Integration system in Dotorixel enables the cross-platform sharing of core pixel art editing logic between the web (WASM) and native Apple platforms (Swift/Metal). This is achieved through UniFFI, a multi-language interface generator that produces Swift bindings from the shared Rust core.
The integration provides a native shell for macOS and iPadOS, allowing the project to utilize high-performance Metal GPU rendering and native system features like Apple Pencil support while maintaining feature parity with the web editor by consuming the same underlying algorithms.
Sources: README.md, issues/013-apple-native-catchup.md
Architecture Overview
The architecture follows a "Shared Core" pattern. The Rust core logic is compiled into a static library and wrapped with UniFFI-generated scaffolding to expose its functionality to the Swift-based UI layer.
The diagram shows the data flow from the shared Rust core through the UniFFI binding layer into the native Apple application components.
Sources: tasks/records/009-uniffi-setup.md, issues/013-apple-native-catchup.md
Core Binding Components
The integration utilizes specific wrappers and configurations to bridge the gap between Rust's memory model and Swift's object-oriented nature.
Object Wrappers and Interior Mutability
Because UniFFI Objects do not natively support Rust's borrowing rules in the same way Swift does, the integration uses wrapper objects in the apple/ crate. These wrappers often employ Mutex<T> to provide interior mutability, allowing the Swift layer to call mutating methods on shared references.
| Wrapper Object | Wrapped Core Component | Responsibility |
|---|---|---|
ApplePixelCanvas | PixelCanvas | Manages pixel buffer and tool application. |
AppleHistoryManager | HistoryManager | Manages undo/redo stacks. |
AppleViewport | Viewport | Handles coordinate transformations and zoom/pan. |
Sources: tasks/records/009-uniffi-setup.md
Data Structures (Records and Enums)
Core data structures are mapped directly to Swift using UniFFI's Record and Enum attributes. This allows for seamless passing of values like coordinates and colors without manual serialization.
- Records:
Color,CanvasCoords,ScreenCanvasCoords,ViewportSize. - Enums:
ToolType. - Errors: A flattened
AppleErroris used in the binding crate to avoid compatibility issues with complex Rust error types (e.g.,usizeorchartypes).
Sources: tasks/records/009-uniffi-setup.md
Build Pipeline and Xcode Integration
The integration is managed through a combination of XcodeGen for project configuration and custom shell scripts for the Rust-to-Apple build process.
Build Script Orchestration
The build-rust.sh script is a critical pre-build step in Xcode. It automatically detects the target platform (macOS vs iOS) and architecture (arm64 vs x86_64) to map them to the correct Rust target triples.
The build flow ensures that the correct architecture of the shared core is compiled and linked before the Swift application compiles.
Sources: scripts/build-rust.sh, apple/project.yml, tasks/records/010-xcode-project.md
Project Configuration
The project uses apple/project.yml for reproducible Xcode project generation via XcodeGen.
- Targets: A single multi-destination target supporting both macOS and iOS (iPadOS).
- Linking: Direct static library linking is used to avoid the complexity of XCFrameworks for the internal app target.
- Bridging Header:
Dotorixel-Bridging-Header.his used to resolve shared type duplication (likeRustBuffer) between multiple UniFFI-generated headers using theUNIFFI_SHARED_Hguard.
Sources: apple/project.yml:1-30, apple/Dotorixel-Bridging-Header.h:1-10, tasks/records/010-xcode-project.md
Technical Specifications
Target Mappings
The build system maps Apple SDKs to the following Rust target triples:
| Apple SDK | Architecture | Rust Target Triple |
|---|---|---|
macosx | arm64 | aarch64-apple-darwin |
macosx | x86_64 | x86_64-apple-darwin |
iphonesimulator | arm64 | aarch64-apple-ios-sim |
iphoneos | arm64 | aarch64-apple-ios |
Sources: scripts/build-rust.sh:10-30
Key Files and Locations
| File Path | Description |
|---|---|
apple/src/lib.rs | The binding crate where Apple-specific wrappers are defined. |
apple/generated/ | Gitignored directory containing the UniFFI-generated Swift code. |
apple/src/bin/uniffi-bindgen.rs | CLI tool for generating Swift bindings from the library. |
crates/core/Cargo.toml | Contains the uniffi dependency and feature flag. |
Sources: tasks/records/009-uniffi-setup.md, tasks/records/010-xcode-project.md
Summary
The Apple Integration system leverages UniFFI to bridge the Rust core with SwiftUI and Metal. By using a sophisticated build pipeline involving XcodeGen and custom Rust compilation scripts, Dotorixel maintains a single source of truth for its editing logic while providing a high-performance, native experience on macOS and iPadOS. This structure allows the native shell to "catch up" to web features by simply wiring existing Rust functions to new SwiftUI components.
Sources: issues/013-apple-native-catchup.md, tasks/records/010-xcode-project.md