Add default automatic SKIE StateFlow discovery - #3
Conversation
|
Implemented in |
|
Follow-up |
|
Follow-up |
|
Architecture cleanup in |
|
Final routing cleanup in
Verification: 30 strict-concurrency tests passed, including direct NativeFlow routing and |
Summary
Adds automatic SKIE
StateFlowobservation as the default no-state behavior:Externally owned models use the same default:
The strategy can still be written explicitly as
.automaticSKIE, while.nonedisables automatic subscriptions:No generated Swift file, Xcode project mutation, build script, macro, Kotlin bridge dependency, or
$registration is required. Existingstate:,states:, adapter, generated-conformance, and KMP-NativeCoroutines APIs remain available and unchanged. Explicit state/adapters bypass runtime discovery.How discovery works
Kotlin/Native does not emit usable Objective-C property metadata for these properties, so
Mirrorandclass_copyPropertyListcannot enumerate them. Kotlin property getters are still exported as Objective-C methods.The bridge installs a guarded, one-time interceptor for eligible getters on the concrete Kotlin class. It never calls a getter speculatively. When application code naturally reads a getter, the bridge:
Kotlinx_coroutines_coreStateFlowprotocol;A replacement flow identity cancels the previous iterator. Multiple Swift stores can listen to the same Kotlin model without duplicate getter discovery, and the last listener teardown cancels active collections. Store generations continue suppressing stale emissions during rebinding.
Compatibility considerations
Automatic SKIE discovery is the convenience default, but explicit key paths remain the maximum-stability option:
SkieColdFlowIteratorABI, which is not documented as a stable third-party runtime API.AsyncSequencekey paths.The implementation checks the framework image, protocol, iterator class, and required selectors before activation. Unsupported frameworks safely create no automatic observation. Applications can use explicit state key paths for deterministic observation or
.noneto disable automatic behavior entirely.Safety and lifecycle behavior
StateFlowreturn values are ignored..nonepreserves ownership, disposal, model access, and rebinding while installing no automatic subscriptions.API and documentation
KMPAutomaticObservation.automaticSKIEas the default automatic strategy.KMPAutomaticObservation.noneas the explicit disable strategy..none, and when explicit key paths should be preferred.project.pbxprojchanges and noXcodeProjdependency.Verification
swift test -Xswiftc -strict-concurrency=complete -Xswiftc -warnings-as-errors— 30 tests passed.StateFlowreplay and a subsequent Kotlin emission, then cancelled the iterator.git diff --checkpassed.Relates to #2