mirror of
https://github.com/sudosylabs/vnidrop.git
synced 2026-08-05 02:29:55 +02:00
feat(apple): native SwiftUI app for iOS and macOS
Add a native SwiftUI VniDrop app (Send/Receive/Settings) talking to the Rust core via generated UniFFI Swift bindings, plus the uniffi-bindgen helper crate. iOS uses a TabView, macOS a NavigationSplitView sidebar.
This commit is contained in:
93
apple/README.md
Normal file
93
apple/README.md
Normal file
@@ -0,0 +1,93 @@
|
||||
# VniDrop — native Apple app (iOS / iPadOS / macOS)
|
||||
|
||||
A native SwiftUI app for Apple platforms, sharing the existing Rust transfer core
|
||||
(`crates/vnidrop`) through UniFFI-generated Swift bindings. The Rust crate is not
|
||||
modified; the Kotlin/Compose app layer is ported to Swift and mirrors the Compose
|
||||
UI screen-for-screen. Android and desktop JVM continue to use `shared/` + Compose.
|
||||
|
||||
## Layout
|
||||
|
||||
```
|
||||
apple/
|
||||
scripts/build-core.sh # builds the Rust core + generates Swift bindings + xcframework
|
||||
VnidropCore/ # local SwiftPM package: xcframework + generated Vnidrop.swift
|
||||
VniDrop/ # SwiftUI app sources
|
||||
App/ # entry point, object graph, root view, environment
|
||||
Core/ # repository, models, preferences, notifications, progress
|
||||
Features/Send|Receive|Approvals|Settings/
|
||||
UI/Theme|Components|Navigation|Feedback|Shell/
|
||||
Platform/ # pickers, QR, NFC, share/export, per-OS file services
|
||||
Resources/ # Localizable.xcstrings, Info.plist, entitlements, assets
|
||||
Tests/ # XCTest (ported progress-derivation assertions)
|
||||
Package.swift # builds VniDrop/ as a library for CLI build/test
|
||||
project.yml # XcodeGen spec for the iOS/macOS app target
|
||||
```
|
||||
|
||||
## Build & run
|
||||
|
||||
Prerequisites: Xcode, Rust with the Apple targets
|
||||
(`aarch64-apple-ios`, `aarch64-apple-ios-sim`, `x86_64-apple-ios`,
|
||||
`aarch64-apple-darwin`), and `xcodegen` (`brew install xcodegen`).
|
||||
|
||||
```bash
|
||||
# 1. Build the Rust core and generate the Swift bindings + xcframework.
|
||||
apple/scripts/build-core.sh debug # or: release (see note below)
|
||||
|
||||
# 2. Generate the Xcode project.
|
||||
cd apple && xcodegen generate
|
||||
|
||||
# 3. Open and run, or build from the CLI:
|
||||
open VniDrop.xcodeproj
|
||||
# macOS:
|
||||
xcodebuild -project VniDrop.xcodeproj -scheme VniDrop -destination 'platform=macOS' build
|
||||
# iOS simulator:
|
||||
xcodebuild -project VniDrop.xcodeproj -scheme VniDrop \
|
||||
-destination 'platform=iOS Simulator,name=iPhone 15' build
|
||||
```
|
||||
|
||||
## Command-line typecheck & tests
|
||||
|
||||
`Package.swift` builds the same sources as a library (minus the `@main` entry),
|
||||
so the shared logic can be checked and unit-tested without Xcode:
|
||||
|
||||
```bash
|
||||
cd apple
|
||||
swift build # macOS
|
||||
swift test # runs Tests/ (ported progress-derivation assertions)
|
||||
# iOS typecheck:
|
||||
swift build --triple arm64-apple-ios16.0-simulator --sdk "$(xcrun --sdk iphonesimulator --show-sdk-path)"
|
||||
```
|
||||
|
||||
## Generated / ignored artifacts
|
||||
|
||||
`build-core.sh` produces build outputs that are gitignored (see `apple/.gitignore`):
|
||||
`VnidropCore/vnidrop.xcframework/`, `VnidropCore/Sources/VnidropCore/Vnidrop.swift`,
|
||||
and `.build-core/`. A clean checkout must run `build-core.sh` before generating or
|
||||
opening the Xcode project. `VniDrop.xcodeproj` itself is generated by XcodeGen from
|
||||
`project.yml` and does not need to be committed.
|
||||
|
||||
## Build profile note
|
||||
|
||||
The default is `debug`. The workspace `[profile.release]` uses thin LTO, which the
|
||||
current macOS toolchain miscompiles into corrupt host proc-macro dylibs
|
||||
("mis-aligned LINKEDIT string pool"). `build-core.sh` sets
|
||||
`CARGO_PROFILE_DEV_STRIP=none` (matching the existing Gobley Xcode run-script) so
|
||||
debug builds succeed. For a release core, disable LTO for proc-macros/build
|
||||
scripts (e.g. add a `[profile.release.build-override] lto = false` locally) — the
|
||||
Rust crate itself is never changed.
|
||||
|
||||
## System frameworks
|
||||
|
||||
The Rust core (iroh network stack) links `SystemConfiguration`, `Security`, and
|
||||
`libresolv`. These are declared in both `Package.swift` (for CLI build/test) and
|
||||
`project.yml` (for the app target).
|
||||
|
||||
## Parity & scope
|
||||
|
||||
Screens mirror the Compose UI in `shared/`. Two deliberate simplifications:
|
||||
- Empty-state Lottie animations are rendered as SF Symbols (no `lottie-ios`
|
||||
dependency); swap in `lottie-ios` if exact-parity animation is required.
|
||||
- The full diagnostics/telemetry stack (`diagnostics/*`) is stubbed behind
|
||||
`BugReportService` / `DiagnosticsBuildConfig` and lands in a later phase; the UI
|
||||
hides the diagnostics toggle when not compiled in.
|
||||
```
|
||||
Reference in New Issue
Block a user