Skip to content

watchos: migrate AppSettings and UserData from ObservableObject to @Observable - #1267

Open
timbms wants to merge 11 commits into
developfrom
watchos/observable-migration
Open

watchos: migrate AppSettings and UserData from ObservableObject to @Observable#1267
timbms wants to merge 11 commits into
developfrom
watchos/observable-migration

Conversation

@timbms

@timbms timbms commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Replaces ObservableObject/@Published/Combine in AppSettings with @Observable and didSet persistence observers
  • Replaces three Combine subscriptions in UserData (sitemapForWatch, connection configs, haveReceivedAppContext) with withObservationTracking task loops using a true cancellable debounce pattern — both initial and subsequent values pass through the same 300 ms / 500 ms timer, matching the old pipeline's behaviour
  • Updates all 14 call sites across the Watch target to use @Environment(Type.self) and @Bindable in place of @EnvironmentObject / @ObservedObject
  • Adds an explicit persistStoredHomes call in AppSettings.init() to seed the App Intents suite on first launch (previously handled automatically by the @Published initial emission)

Test plan

  • Build openHABWatch scheme — no errors
  • Cold-start: sitemap loads after ~300 ms debounce (not instantaneously)
  • Switch sitemap in preferences — page handling restarts after 300 ms; rapid changes only trigger one reload
  • Network switch (local ↔ remote) — updateNetwork() fires after 500 ms debounce
  • Receive app context from iOS — updateNetwork() is called on first true transition
  • Stored homes round-trip correctly to App Intents suite on first launch

timbms and others added 11 commits June 20, 2026 17:46
…bservable

Replace Combine/ObservableObject with the Swift @observable macro across the
Watch target. AppSettings gains didSet persistence observers in place of
@published sinks; UserData replaces three Combine subscriptions with
withObservationTracking task loops that implement true cancellable debounce
(300 ms for sitemap, 500 ms for connection configs). Both the initial and
subsequent values are routed through the same debounce timer, matching the
behaviour of the former Combine pipeline. All call sites are updated to use
@Environment(Type.self) and @bindable in place of @EnvironmentObject and
@ObservedObject.

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Task<Void, Never> is Sendable so nonisolated(unsafe) has no effect on
@Observable-backed storage — the macro generates @MainActor-isolated
backing vars that deinit cannot reach without the annotation.

Add @ObservationIgnored to all five task properties and notificationObservers
so the macro leaves them as plain stored properties, then nonisolated(unsafe)
correctly permits the deinit cancel calls for the non-Sendable observer array
and silences the remaining isolation check for the task slots.

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
…contradiction

The Swift compiler simultaneously requires nonisolated(unsafe) on
notificationObservers ([any NSObjectProtocol] is not Sendable, so deinit
access is rejected without it) and warns that it has no effect — its
suggestion of plain nonisolated is itself rejected on mutable stored
properties. Add a comment explaining the contradiction so the annotation
is not silently removed by a future cleanup pass.

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
… debounce closure

Drop the local let taskSitemapName = sitemapName inside pageHandlingTask —
the function parameter is already captured and can be referenced directly,
reducing the class body to the 450-line SwiftLint limit.

Also add explicit self. to the three currentlyLoadingSitemap / startPageHandling
references inside the ongoing sitemap debounce task; these were hidden by
incremental build caching and are now exposed by the forced recompile.

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
…imit

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
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