mirror of
https://github.com/sudosylabs/vnidrop.git
synced 2026-08-07 11:19:58 +02:00
Package.swift named its module VniDropApp while all 16 test files import VniDrop, and it never declared the SFSafeSymbols dependency that project.yml links, so neither swift build nor swift test worked. The Xcode project is already the only functioning build definition for the UI and the tests. Removes a second dependency list that had drifted, and corrects the README, which documented the CLI path as if it worked.
122 lines
5.5 KiB
Markdown
122 lines
5.5 KiB
Markdown
# 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, Windows, and Linux 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 bundle (VniDropTests target)
|
|
project.yml # XcodeGen spec for the iOS/macOS app and test targets
|
|
```
|
|
|
|
## 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
|
|
# From the repository root:
|
|
make apple-core # Rust core, Swift bindings, and XCFramework
|
|
make apple-project # generate apple/VniDrop.xcodeproj
|
|
make open-apple-project # generate and open the project in Xcode
|
|
make build-apple-macos # unsigned macOS build (App Store target)
|
|
make open-apple # build and launch the macOS app
|
|
make build-apple-ios # unsigned iOS simulator app
|
|
make check-apple # iOS simulator tests
|
|
```
|
|
|
|
`make apple-project` also generates ignored Store and Direct version xcconfig
|
|
files. Their `CURRENT_PROJECT_VERSION` values come from the central version
|
|
resolver as UTC `YYYYMMDD.HHMM.SS` build identifiers. Regenerate the project
|
|
before creating another App Store archive so it receives a fresh build number;
|
|
direct DMG builds refresh their own value automatically.
|
|
|
|
### macOS shipping channels
|
|
|
|
The macOS app ships through two targets that build identical sources:
|
|
|
|
- **`VniDrop`** (`Release`) — Mac App Store / TestFlight. Sandboxed, no
|
|
self-updater.
|
|
- **`VniDropDirect`** (`Release-Direct`) — direct-download `.dmg` on GitHub
|
|
Releases + Homebrew cask. Adds the **Sparkle** auto-updater behind the
|
|
`DIRECT_DISTRIBUTION` compile flag, so the App Store binary never links Sparkle.
|
|
|
|
```bash
|
|
make build-apple-macos-direct # unsigned compile-check of the direct target
|
|
make build-apple-dmg # signed (+ notarized) .dmg
|
|
```
|
|
|
|
Full signing, notarization, appcast, and cask flow: see
|
|
[`RELEASE-MACOS.md`](RELEASE-MACOS.md).
|
|
|
|
Use `APPLE_PROFILE=release` to request a release Rust core, or set
|
|
`APPLE_DESTINATION` to override the automatically selected iOS simulator.
|
|
Code signing is disabled for the app and test targets; local and CI builds do
|
|
not require an Apple Development team or provisioning profile. Make builds can
|
|
opt in with `APPLE_CODE_SIGNING=YES`. For signed builds from Xcode, create the
|
|
ignored `apple/Local.xcconfig` and override the signing settings there, including
|
|
the development team.
|
|
|
|
## Typecheck & tests
|
|
|
|
The Xcode project is the only build definition: it owns the UI, its package
|
|
dependencies, and the `VniDropTests` bundle (module `VniDrop`, which is what the
|
|
tests import). Everything runs through `xcodebuild`:
|
|
|
|
```bash
|
|
make check-apple # iOS simulator unit tests
|
|
make build-apple-macos # unsigned macOS build (typecheck)
|
|
```
|
|
|
|
There is deliberately no SwiftPM manifest for the app. A second build definition
|
|
would duplicate the target's package dependencies, and the previous one had
|
|
already drifted out of sync with `project.yml` badly enough that neither
|
|
`swift build` nor `swift test` worked.
|
|
|
|
## 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 `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.
|
|
- Bug reporting is stubbed behind `BugReportService` (`NoopBugReportService`) and
|
|
a real transport lands in a later phase. There is no telemetry or crash
|
|
auto-reporting.
|
|
```
|