La montre avait les données du jour et n'en montrait rien

Le snapshot poussé par l'iPhone (séance prévue, forme, hydratation, énergie,
routine, séance de demain) arrive sur la montre depuis WatchConnectivity et
vit dans son App Group. Les complications le lisent ; l'app, elle, ouvrait
sur le lanceur d'activité et n'en affichait pas une ligne.

Aucun nouveau pont : `ConnectivityManager` publie le snapshot qu'il persistait
déjà, l'accueil en montre un résumé, et une feuille « Aujourd'hui » donne le
détail. Même `asOf(_:)` que les complications, pour qu'un snapshot d'hier se
vide au lieu de mentir.

Les vues vivent dans ContentView.swift, déjà membre de la cible CoachWatch :
pas de Target Membership à régler dans Xcode.

⚠️ Non compilé — SwiftUI et WatchKit n'existent pas sur Linux. Seuls
`swiftc -parse` et les tests Linux existants sont passés. À builder sur le Mac.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Sylvain Bettinelli
2026-08-19 20:34:31 +00:00
parent 4cff1d4603
commit 852e12526a
2 changed files with 304 additions and 1 deletions

View File

@@ -21,6 +21,15 @@ final class ConnectivityManager: NSObject, ObservableObject {
/// rafraîchi à chaque battement coûterait pour rien.
@Published private(set) var zones: HeartRateZones?
/// Dernier snapshot du jour poussé par l'iPhone : séance prévue, score de
/// forme, hydratation, énergie, routine.
///
/// Ces données arrivaient déjà sur la montre les complications les lisent
/// depuis le cadran mais rien ne les publiait, donc l'app elle-même n'en
/// montrait rien. Publié pour la même raison que `zones` : décoder le JSON
/// de l'App Group à chaque rendu coûterait pour rien.
@Published private(set) var snapshot: CoachWidgetSnapshot?
private let queue = DispatchQueue(label: "ch.hypnotruck.coach.connectivity")
private var buffer: [[String: Any]] = []
@@ -32,7 +41,9 @@ final class ConnectivityManager: NSObject, ObservableObject {
session.activate()
// La montre a pu redémarrer depuis le dernier envoi de l'iPhone : on
// repart du dernier snapshot connu plutôt que d'attendre le suivant.
zones = CoachWidgetStore.load()?.zones
let stored = CoachWidgetStore.load()
zones = stored?.zones
snapshot = stored
}
func sendSample(_ payload: [String: Any]) {
@@ -238,6 +249,7 @@ extension ConnectivityManager: WCSessionDelegate {
// Des zones absentes d'un snapshot partiel ne doivent pas effacer
// celles en place : la séance en cours perdrait son repère.
if let received = snapshot.zones { self.zones = received }
self.snapshot = snapshot
WidgetCenter.shared.reloadAllTimelines()
}
}