diff --git a/docs/widgets-runbook-mac.md b/docs/widgets-runbook-mac.md index 6eecddf..80c7d6e 100644 --- a/docs/widgets-runbook-mac.md +++ b/docs/widgets-runbook-mac.md @@ -107,3 +107,47 @@ la complication lit ce conteneur. Tout ce code est déjà écrit & committé. - Lockscreen widgets iPhone (`accessoryRectangular` / `accessoryCircular`) — ajouter les familles aux widgets iOS. - `transferCurrentComplicationUserInfo` (réveil complication, budget ~50/j) si besoin de fraîcheur en arrière-plan. - Background refresh iPhone (App Background Tasks) pour un widget à jour sans ouvrir l'app. + +--- + +## Widget « Saisie rapide » (ajouté 2026-08-06) + +Noter l'eau et le café **sans ouvrir l'app** ; photo et code-barres l'ouvrent — +la caméra exige le premier plan, aucun widget ne peut y échapper. + +### Fichiers et Target Membership + +| Fichier | Cibles | +|---|---| +| `ios/App/App/CoachQuickLog.swift` | **App + CoachLiveActivity** (+ CoachWatch et CoachWatchWidgets pour la complication) | +| `ios/App/CoachLiveActivity/CoachQuickWidget.swift` | **CoachLiveActivity** seule | +| `ios/App/App/CoachWidgetSnapshot.swift` | inchangé — déjà App + CoachLiveActivity | + +`CoachQuickLog.swift` doit être dans **les deux** cibles : l'extension écrit la +file, l'app la vide. + +### À faire sur le Mac + +1. **Prérequis** : App Group `group.ch.hypnotruck.coach` créé et actif sur les + deux cibles (étapes plus haut). Rien ne fonctionne sans. +2. Ajouter les deux fichiers au projet Xcode, avec le Target Membership ci-dessus. +3. Enregistrer le widget dans le `WidgetBundle` de `CoachLiveActivity` : + ajouter `CoachQuickWidget()` à côté des widgets existants. +4. **Schéma d'URL** : vérifier `coachapp://` dans le `Info.plist` de l'App + (`CFBundleURLTypes`). Les boutons pointent sur `coachapp://meals?photo=1` et + `coachapp://meals?scan=1`. +5. Cible de déploiement **iOS 17 minimum** : en dessous, le widget compile mais + les boutons d'App Intent n'apparaissent pas. +6. Builder sur un device réel — les App Intents ne s'exécutent pas de façon + fiable en simulateur. + +### Ce qui reste à câbler côté app + +La file `CoachQuickLog.pending()` doit être transmise au serveur à l'ouverture +de l'app, puis retirée par `CoachQuickLog.remove(ids:)` — **par identifiant, pas +en vidant la file** : une saisie faite pendant la synchronisation serait sinon +perdue sans laisser de trace. Endpoint : `POST /api/drinks` +(`drink_type`, `volume_ml`, `date`). + +Tant que ce câblage manque, les saisies restent locales : le widget affiche une +flèche de synchronisation et son compteur reste juste.