watchos: migrate AppSettings and UserData from ObservableObject to @Observable - #1267
Open
timbms wants to merge 11 commits into
Open
watchos: migrate AppSettings and UserData from ObservableObject to @Observable#1267timbms wants to merge 11 commits into
timbms wants to merge 11 commits into
Conversation
…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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ObservableObject/@Published/Combine inAppSettingswith@ObservableanddidSetpersistence observersUserData(sitemapForWatch, connection configs,haveReceivedAppContext) withwithObservationTrackingtask 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@Environment(Type.self)and@Bindablein place of@EnvironmentObject/@ObservedObjectpersistStoredHomescall inAppSettings.init()to seed the App Intents suite on first launch (previously handled automatically by the@Publishedinitial emission)Test plan
openHABWatchscheme — no errorsupdateNetwork()fires after 500 ms debounceupdateNetwork()is called on firsttruetransition