diff --git a/CHANGELOG.md b/CHANGELOG.md index f809dcb..fd03a4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,10 @@ All notable changes to this project are documented here. advances the set count on the iPhone and a finished set is never un-counted, and reopening an exercise jumps straight to the first unfinished set (skipping completed work/rest pairs) instead of snapping back to set 1. +- Fixed: progress made on the watch now updates open iPhone screens live. The + phone applies a watch-forwarded workout to its cache directly on receipt, instead + of waiting on an `NSMetadataQuery` event that a same-process file overwrite + doesn't reliably emit. - Starting a workout on the iPhone now launches the Apple Watch app straight into the session via HealthKit (a one-time Health permission); the watch holds an `HKWorkoutSession` to stay active while you train and releases it when the diff --git a/Workouts/Sync/SyncEngine.swift b/Workouts/Sync/SyncEngine.swift index 7690a5f..34b746e 100644 --- a/Workouts/Sync/SyncEngine.swift +++ b/Workouts/Sync/SyncEngine.swift @@ -112,10 +112,20 @@ final class SyncEngine { onCacheChanged?() } - /// Apply a workout received from the watch through the normal write path - /// (file → observer → cache), keeping iCloud Drive the single source of truth. + /// Apply a workout received from the watch. iCloud Drive stays the source of + /// truth (we write the file), but we also upsert the cache directly here. + /// + /// The phone's own edits drive a local view copy, so they don't need this — but a + /// watch-originated change has nothing else refreshing the phone UI, and a + /// same-process file overwrite doesn't reliably wake the `NSMetadataQuery` + /// observer. Upserting the doc we just wrote keeps cache and file consistent (the + /// observer re-applies idempotently if it does fire) and lets open phone screens + /// reflect watch progress live. func ingestFromWatch(_ doc: WorkoutDocument) async { await save(workout: doc) + CacheMapper.upsertWorkout(doc, relativePath: doc.relativePath, into: context) + try? context.save() + onCacheChanged?() } // MARK: - Public CRUD (write path: files only)