Skip to content

Android state regression: cross-build environment issue #3

@codelynx

Description

@codelynx

Problem

Android button taps return null from nativeOnButtonClick@State mutations don't trigger rebuilds. This affects all interactive examples including the previously-working StateDemo.

Investigation findings

The code is correct

  • testSessionButtonTapTriggersRebuild passes on macOS — creates session, wires state, renders, invokes action, asserts pendingJSON is non-nil with updated value
  • The Swift-side reactive plumbing (StateStorage → host → scheduleRebuild → pendingJSON) works in unit tests

The cross-build is broken

Root-package Android build fails with:

error: could not find module 'Foundation' for target 'aarch64-unknown-linux-android';
found: armv7-unknown-linux-android

This happened after rm -rf .build was run to clear JavaScriptKit macro cache corruption (caused by switching between Xcode 6.2.4 and 6.3 snapshot toolchains). The .build directory contained cached module maps for aarch64 that SPM can't re-resolve.

Build path inconsistency

The branch has conflicting Android build arrangements:

  • Root Package.swift declares BackendAndroid (restored from stash)
  • android/renderer/swift-lib/Package.swift also declares BackendAndroid (from examples-shared branch)
  • build-so.sh builds from root, but android-setup.md references swift-lib

To reproduce

rm -rf .build
source ~/.swiftly/env.sh
swift build --swift-sdk swift-6.3-DEVELOPMENT-SNAPSHOT-2026-03-05-a_android \
    --triple aarch64-unknown-linux-android28 --product BackendAndroid -c release
# → Foundation module not found for aarch64

To fix

  1. Resolve the dual BackendAndroid target conflict (pick root or swift-lib, not both)
  2. Re-establish aarch64 module resolution after .build clear
  3. Document that rm -rf .build breaks Android cross-compilation — use targeted cache clears instead
  4. Verify StateDemo works on emulator after fix

Separate issue: nested @State

Composed child views with their own @State (e.g., GestureDemo inside BasicInteractiveView) don't persist state on Android. This is architectural — needs a structural state store keyed by node ID. Tracked separately from the build regression.

Context

  • Android Phase 2 renderers (gestures, navigation, animations) are written and correct but can't be tested until the build is fixed
  • Web Phase 2 features are complete and working
  • macOS/Xcode environment is working

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions