Skip to content

Replace Skip with AndroidSwiftUI#22

Merged
colemancda merged 33 commits into
masterfrom
feature/androidswiftui
Jul 22, 2026
Merged

Replace Skip with AndroidSwiftUI#22
colemancda merged 33 commits into
masterfrom
feature/androidswiftui

Conversation

@colemancda

Copy link
Copy Markdown
Member

Replaces Skip with AndroidSwiftUI. Apple platforms now
use the system SwiftUI directly with no framework in between; Android uses AndroidSwiftUI, selected
per-file with #if canImport(SwiftUI).

Depends on PureSwift/AndroidSwiftUI#4, which adds the SwiftUI surface this app needs
(NavigationStack, TabView, .sheet, .refreshable, lazy stacks, Observation support).

What changed

  • Dependencies: skip, skip-model, skip-fuse and skip-fuse-ui are gone, replaced by a
    single AndroidSwiftUI dependency linked only .when(platforms: [.android]). The skipstone
    build plugin, all three Skip/skip.yml files and Skip.env are removed.
  • Observation: the model layer already used @Observable/import Observation; the SkipModel
    and SkipFuse imports were purely additive and are dropped.
  • Logging: SkipFuse's Logger is replaced by a small AppLogger shim — os.Logger on Apple
    platforms, printing elsewhere.
  • App entry: /* SKIP @bridge */ annotations are removed. Darwin/Sources/Main.swift was
    already a real @main SwiftUI App, so nothing was needed to replace the bridge on Apple.
  • Skip-only code removed: ComposeView/HeartComposer (Compose interop behind #if SKIP) and
    the unused WelcomeView/"Powered by Skip" template scaffolding, none of which can compile without
    the transpiler. The first tab was labelled "Welcome" with a heart icon while showing the device
    list; it is now "Devices".

Removing Skip also fixed the dependency graph

The package resolves from a clean checkout with no mirrors and no SWIFTPM_ENABLE_MACROS=0, and
the dependency count drops from ~30 to 20. Every blocker documented in Documentation/DependencyState.md
entered through the Skip fork stack:

  • the duplicate swift-android-native identity came from skip-android-bridge pointing at a fork
    while PureSwift/Android pointed at upstream — with the bridge gone there is only one claimant;
  • the swift-java → swift-syntax 603 vs Bluetooth macros conflict came in the same way;
  • skip-fuse-ui no longer constrains skip-ui.

That document is now largely historical. PureSwift/Android#43 and PureSwift/AndroidBluetooth#4 are
still needed — AndroidBluetooth requests AndroidManifest from the wrong package.

Unrelated fix included: plugin deadline

The GATT test suite was failing intermittently. I first blamed machine load; that was wrong — it
failed on an idle machine too. Running each plugin serially showed zero failures, which located
the real cause: the suite loads all 13 bundled plugins per test, each holding a warm interpreter on
its own thread, and running its tests concurrently multiplies that into dozens of contending
interpreters that blow the 50 ms per-call deadline. A healthy plugin was being quarantined for being
slow under contention — which could equally happen on a busy phone during a dense scan.

Two changes: the stress suite is .serialized, and the default per-call deadline is raised from
50 ms to 250 ms. That is still a decisive runaway guard given a real parse takes tens of
microseconds, and warmup is separately bounded at 5 s.

Verification

  • Every target builds on Apple platforms with no Skip involvement.
  • 44 tests pass, stable across 5 consecutive runs (previously intermittent).
  • AndroidSwiftUI's four additions were built together for Android to confirm they compose.

Android is not verified end to end. Before it can be, this needs PureSwift/AndroidSwiftUI#4
merged, the two PureSwift dependency PRs merged, and the Kotlin JNI peers under
Sources/BluetoothExplorer/Skip/ (ScanCallback.kt, BluetoothGattCallback.kt) rehomed into the
Android app project — they are AndroidBluetooth peers, unrelated to Skip, and only lived there
because skipstone collected them. None of the new AndroidSwiftUI code has run on a device;
Documentation/AndroidSwiftUIMigration.md lists its known gaps (no @Bindable, TabView resets
unselected tabs' @State, sheet is a full-screen overlay, .refreshable is inert).

@colemancda
colemancda merged commit 9e34039 into master Jul 22, 2026
0 of 3 checks passed
@colemancda colemancda mentioned this pull request Jul 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant