Comme l'app Exercice : deux boutons sur la bannière de l'écran verrouillé et dans l'île dépliée. iOS n'expose aucun geste de balayage pour révéler des actions — depuis iOS 17, ce sont des boutons intégrés (App Intents), et c'est le seul mécanisme public. - Intents `CoachTogglePauseIntent` / `CoachEndWorkoutIntent`, conformes à LiveActivityIntent (sans quoi `perform()` n'est jamais appelé). - Ils vivent dans CoachLiveActivityAttributes.swift, seul fichier déjà membre des deux targets : un fichier neuf imposerait une manip Target Membership dans Xcode, source d'erreurs répétées ici. - Commandes relayées à la montre par WCSession, avec repli transferUserInfo : isReachable retombe à false quand la séance tourne en arrière-plan profond, la commande est alors différée au réveil de l'app montre. - L'état de pause remonte depuis HKWorkoutSession (seule source fiable : la montre peut mettre en pause d'elle-même) et bascule le libellé du bouton. - Le watchdog de LiveStore est neutralisé pendant la pause : sans ça, l'absence de samples aurait affiché « connexion perdue » puis terminé l'activité. - L'app watchOS gagne le bouton Pause qui lui manquait, aligné sur le même état. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
5.9 KiB
Build du correctif « Live Activity fantôme » — runbook Mac
Écrit le 2026-08-11. Concerne le commit 5e9b4a3 (La Live Activity
restait affichée après la fin de séance).
Compte 15 minutes. C'est un build simple : aucun fichier nouveau, aucune
target à créer, aucune capability à ajouter. Les cinq fichiers modifiés sont
déjà membres de leurs targets (vérifié dans project.pbxproj).
⚠️ La montre doit être rebuildée aussi, pas seulement l'iPhone : le message
de fin de séance part de CoachWatch. Un build iPhone seul ne corrige rien.
Étape 1 — Récupérer le code
Xcode fermé (Cmd+Q, pas juste la fenêtre) :
cd ~/coach-ios
git pull
git log --oneline -1 # doit afficher 5e9b4a3 ou plus récent
Pas besoin de npm install ni de npx cap sync ios : aucune dépendance ni
config Capacitor n'a bougé. Si Xcode râle sur no such module 'Capacitor',
alors seulement, lance npx cap sync ios (Xcode fermé).
Étape 2 — Build sur l'iPhone
open ios/App/App.xcodeproj
- iPhone branché et déverrouillé, Apple Watch au poignet et appairée
- Schéma App + ton iPhone comme destination
- Run (
Cmd+R)
Pas de Clean Build Folder nécessaire — cinq fichiers modifiés, la compilation incrémentale suffit.
Étape 3 — Installer la nouvelle app sur la Watch
L'app watchOS est embarquée dans l'app iPhone, mais watchOS ne la réinstalle pas toujours tout de suite. Le plus fiable : builder directement dessus.
- Schéma CoachWatch (menu des schémas, en haut)
- Destination : ton Apple Watch Ultra 3
- Run (
Cmd+R)
Le premier lancement sur la montre peut demander 2-3 minutes et afficher « Waiting to attach » — c'est normal.
Alternative sans Xcode : iPhone → app Watch → Apps installées → Coach → attendre la réinstallation. Plus lent et moins déterministe.
Vérifier que la montre a bien la nouvelle version : dans les logs (étape
4), la ligne fin de séance signalée à l'iPhone n'existe que dans ce build.
Étape 4 — Tester (3 minutes)
Le test se fait dans cet ordre, en gardant Console.app ouvert sur le Mac :
Console.app → ton iPhone dans la colonne de gauche
Filtre : subsystem:ch.hypnotruck.coach
- Démarrer une séance depuis l'app Coach sur la Watch
→ la Live Activity apparaît sur l'iPhone (cœur + FC qui bouge)
→ log
Live Activity started - Terminer la séance sur la Watch
→ log côté montre :
fin de séance signalée à l'iPhone (reason=session-ended)→ log côté iPhone :fin de séance reçue de la WatchpuisLive Activity ended→ la Live Activity disparaît immédiatement de l'écran
C'est ce dernier point qui valide le correctif. Avant, elle restait ~4 h avec la dernière FC figée.
-
Écran verrouillé : referme l'iPhone pendant la séance, termine sur la montre, rallume l'écran. La bannière ne doit plus être là. C'est le cas qui échouait vraiment — le watchdog reposait sur un
Timerqui ne tourne pas quand l'app est suspendue. -
Vérifie au passage que la FC remonte toujours sur
/live(le flux de samples n'a pas changé, maisCoachLiveBridgea été touché).
Le cœur fantôme actuellement à l'écran
Il vient de l'ancien build. Il partira soit au premier liveEnded reçu (la
nouvelle app reprend la main dessus via adoptExisting()), soit après 6 h,
soit tout de suite si tu le fermes à la main (appui long → fermer).
Étape 4bis — Les boutons Pause / Terminer (build du 2026-08-11, second lot)
La Live Activity porte maintenant deux boutons, comme l'app Exercice : Pause / Reprendre et Terminer. Ils apparaissent sur la bannière de l'écran verrouillé et dans l'île dynamique dépliée (appui long sur l'île) — pas en mode compact, où iOS n'accepte aucun bouton.
Aucune manipulation Xcode : les intents vivent dans
CoachLiveActivityAttributes.swift, déjà membre des deux targets.
À tester, séance en cours :
- Appui long sur l'île → les deux boutons apparaissent
- Pause → la séance se met en pause sur la montre, le bouton devient
Reprendre, et la page
/livene bascule pas en « Connexion perdue » (le watchdog est neutralisé pendant la pause) - Reprendre → la FC repart
- Terminer → la séance s'arrête sur la montre et la Live Activity disparaît immédiatement
⚠️ Limite Apple, à connaître avant de crier au bug : WCSession.isReachable
retombe à false quand l'app watchOS tourne sa séance en arrière-plan profond
(poignet baissé, écran éteint). La commande bascule alors sur
transferUserInfo : elle est garantie mais différée, donc elle s'applique
au réveil de l'app montre et non à la seconde. Poignet levé, c'est immédiat.
Aucune API publique ne fait mieux.
Détail mineur : en mode test (FC simulée), la pause bascule l'état mais la simulation continue d'émettre des samples. Sans effet sur une vraie séance.
Étape 5 — TestFlight (facultatif)
Rien de spécifique ici : c'est la procédure habituelle, étapes 7 à 9 de
docs/SESSION-XCODE.md. Pense à incrémenter le numéro de build.
Si ça ne compile pas
| Erreur | Cause probable | Solution |
|---|---|---|
cannot find 'CoachAuth' in scope |
CoachAuth.swift absent (non versionné) |
étape 2 de docs/SESSION-XCODE.md |
no such module 'Capacitor' |
sync manquant | npx cap sync ios, Xcode fermé |
value of type 'ConnectivityManager' has no member 'sendEnded' |
la target CoachWatch compile un ancien ConnectivityManager.swift |
vérifie que le git pull a bien eu lieu et que Xcode n'a pas restauré un pbxproj en mémoire |
| erreur de signing sur CoachWatch | profil pas régénéré | Signing & Capabilities → décoche/recoche Automatically manage signing |
En cas de blocage, envoie-moi l'étape, le message exact, et :
cd ~/coach-ios && git log --oneline -3 && git status -sb