Files
coach-ios/docs/SESSION-XCODE.md
Sylvain Bettinelli 1e7adb709e docs(session-xcode): exclut build/ de la vérif de câblage
La commande listait tout DerivedData et les checkouts SPM en « NON CÂBLÉ »
(15 faux positifs constatés sur le Mac le 2026-08-03). Le dossier build/
n'existe pas côté serveur dev, d'où l'angle mort.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 14:44:09 +00:00

262 lines
10 KiB
Markdown

# Session Xcode — guide pas à pas
**Écrit le 2026-08-03 pour Sylvain, à suivre sur le Mac mini.**
Cette session livre **tout le natif accumulé depuis le TestFlight de mai** :
login Apple/Google natif, watchOS live workout, widgets iPhone, complications
Watch, et la routine quotidienne sur la montre.
Compte ~1 h 30 la première fois. Les étapes 1 à 6 mènent à une app qui tourne
sur ton iPhone ; les étapes 7 à 9 la publient sur TestFlight. **Tu peux
t'arrêter après l'étape 6** et publier un autre jour.
---
## Avant de commencer — ce qui a changé
Bonne nouvelle : **il n'y a presque plus de fichiers à ajouter à la main.** Les
Swift sont déjà déclarés dans les bonnes targets (commits `caeac37`, `f30cc60`).
Une seule exception : `CoachWatchComplications.swift`, qui a besoin d'une target
qui n'existe pas encore. C'est l'étape 5 — **et elle est facultative** (elle
n'apporte que les complications sur le cadran de la montre).
| Ce que tu vas activer | Étape |
|---|---|
| Login Apple + Google natif | rien à faire, déjà câblé |
| Live workout watchOS | rien à faire, déjà câblé |
| Routine sur la Watch | rien à faire, déjà câblé |
| Widgets iPhone (Séance du jour, Score de forme) | étapes 2-3 (App Group) |
| Complications sur le cadran Watch | étape 5 (facultative) |
---
## Étape 1 — Récupérer le code
⚠️ **Xcode doit être FERMÉ** (`Cmd+Q`, pas juste la fenêtre). Xcode réécrit le
`project.pbxproj` depuis sa mémoire ; un `git pull` fenêtre ouverte nous a déjà
bloqués deux fois.
```bash
cd ~/coach-ios
git pull
npm install
npx cap sync ios
```
**Vérification** — tu dois voir `f30cc60` ou plus récent :
```bash
git log --oneline -1
```
Si `npx cap sync` râle sur la version de Node :
```bash
nvm use 22 # Capacitor 8 exige Node >= 22
```
## Étape 2 — Le token d'auth (à ne pas oublier)
Le fichier `CoachAuth.swift` n'est pas versionné (il contient un secret). **Sans
lui, le projet ne compile pas.**
```bash
ls ios/App/App/CoachAuth.swift
```
- **Le fichier existe** → passe à l'étape 3.
- **Il n'existe pas** → récupère le token puis crée-le :
```bash
# le token est sur le VPS
ssh ubuntu@83.228.246.229 'grep COACH_WEB_TOKEN ~/.config/infomaniak.env'
# puis, en remplaçant <TOKEN> par la valeur affichée :
cat > ios/App/App/CoachAuth.swift <<'EOF'
import Foundation
enum CoachAuth { static let kCoachWebToken: String = "<TOKEN>" }
EOF
```
## Étape 3 — App Group sur le portail Apple
Nécessaire pour que les widgets lisent les données de l'app. À faire une seule
fois, dans le navigateur.
1. [developer.apple.com](https://developer.apple.com) → **Certificates, IDs & Profiles**
2. **Identifiers** → menu déroulant en haut à droite → **App Groups**
3. Le groupe `group.ch.hypnotruck.coach` existe déjà ? → rien à faire.
Sinon : **+** → *App Group* → Description `Coach Hypnotruck`, Identifier
`group.ch.hypnotruck.coach`**Continue****Register**
## Étape 4 — Activer la capability dans Xcode
```bash
open ios/App/App.xcworkspace
```
Pour **chacune** de ces trois targets (colonne de gauche → projet **App**
onglet **TARGETS**) :
| Target | Capability à ajouter |
|---|---|
| **App** | App Groups |
| **CoachLiveActivity** | App Groups |
| **CoachWatch** | App Groups |
Pour chaque target : onglet **Signing & Capabilities****+ Capability** (en
haut à gauche) → tape « App Groups » → double-clic → **coche**
`group.ch.hypnotruck.coach` dans la liste qui apparaît.
> Si le groupe n'apparaît pas dans la liste, clique sur le bouton **refresh**
> sous la liste, ou re-connecte ton compte (Xcode → Settings → Accounts).
⚠️ **Dès que c'est fait, commit + push** — sinon ton prochain `git pull` sera
bloqué par les modifications locales :
```bash
git add -A ios/App && git commit -m "chore(xcode): App Groups sur App, LiveActivity et Watch" && git push
```
## Étape 5 — Complications Watch *(facultative, ~15 min)*
**Tu peux sauter cette étape** et y revenir plus tard : tout le reste fonctionne
sans. Elle n'ajoute que les complications sur le cadran de la montre.
1. Menu **File → New → Target…**
2. Onglet **watchOS****Widget Extension****Next**
3. Product Name : `CoachWatchWidgets` — décoche *Include Live Activity*
**Embed in Application** : `CoachWatch`**Finish**
4. Xcode propose d'activer le nouveau schéma → **Activate**
5. Dans le dossier `CoachWatchWidgets` créé, **supprime** le fichier
`CoachWatchWidgets.swift` généré (clic droit → Delete → *Move to Trash*)
6. Clic droit sur le dossier `CoachWatchWidgets`**Add Files to "App"…**
sélectionne `ios/App/CoachWatchWidgets/CoachWatchComplications.swift`
**décoche** *Copy items if needed*, **coche** la target `CoachWatchWidgets`
7. Sélectionne `CoachWidgetSnapshot.swift` dans la colonne de gauche →
inspecteur de droite (`Cmd+Option+1`) → **Target Membership** → coche
**CoachWatchWidgets**
8. Target `CoachWatchWidgets`**Signing & Capabilities****+ Capability** →
**App Groups** → coche `group.ch.hypnotruck.coach`
Puis commit + push (même raison qu'à l'étape 4).
## Étape 6 — Compiler et tester sur l'iPhone
1. Branche l'iPhone, déverrouille-le, avec l'Apple Watch au poignet et appairée
2. En haut de Xcode, sélectionne le schéma **App** et ton iPhone comme device
3. **Product → Clean Build Folder** (`Cmd+Shift+K`)
4. **Run** (`Cmd+R`)
### Si ça ne compile pas
| Erreur | Cause | Solution |
|---|---|---|
| `cannot find 'CoachAuth' in scope` | étape 2 sautée | crée `CoachAuth.swift` |
| `no such module 'Capacitor'` | sync manquant | `npx cap sync ios`, Xcode fermé |
| erreur de signing | profil pas régénéré | Signing & Capabilities → décoche/recoche *Automatically manage signing* |
| `CoachWidgetStore` introuvable | Target Membership | vérifie que `CoachWidgetSnapshot.swift` est coché pour la target qui râle |
### Tests, dans l'ordre (5 min)
1. **L'app se lance et tu es connecté** → le cookie natif fonctionne.
2. **Live workout** (le seul flux déjà validé, à ne pas casser) : démarre une
séance sur la Watch → la FC doit apparaître sur `/live` de l'iPhone.
⚠️ *C'est le test le plus important : j'ai touché à `CoachLiveBridge` pour
faire passer la routine. Si la FC ne remonte plus, dis-le-moi.*
3. **Routine sur la Watch** : ouvre `/routine` sur l'iPhone (ça pousse les blocs
vers la montre) → app Coach sur la Watch → **Routine du jour** → les 6 blocs
s'affichent → coche-en un → la page iPhone se met à jour **sans recharger**.
4. **Widgets iPhone** : écran d'accueil → appui long → **+** → cherche *Coach*
ajoute « Séance du jour » et « Score de forme ».
5. **Login natif** : déconnecte-toi, teste *Se connecter avec Apple* et *Google*.
Vérification serveur de la routine :
```bash
ssh ubuntu@83.228.246.229 'cat /home/ubuntu/coach_sportif/data/routine_log.json'
```
**Si tu t'arrêtes ici, c'est déjà un succès** : ton iPhone a tout le natif.
---
## Étape 7 — Préparer la distribution
Deux réglages avant d'archiver.
**a. Numéro de build** — target **App** → onglet **General** :
`Version` = `1.3`, `Build` = `23` (le repo est à 1.2 / 22).
**b. Push notifications en production**`ios/App/App/App.entitlements`
contient `aps-environment = development`. En TestFlight, les notifications push
distantes ne marcheront pas avec cette valeur.
Le plus simple : laisse Xcode gérer. Avec *Automatically manage signing*, le
profil de distribution force `production` à l'archivage. **Vérifie-le après
l'étape 8** : Organizer → clic droit sur l'archive → *Show in Finder* → clic
droit → *Afficher le contenu*`Products/Applications/App.app` → clic droit →
*Afficher le contenu* → ouvre `embedded.mobileprovision` avec TextEdit → cherche
`aps-environment`, il doit valoir `production`.
Si ce n'est pas le cas, édite `App.entitlements` en mettant `production`,
ré-archive, et **remets `development`** ensuite pour ne pas casser tes builds de
dev.
## Étape 8 — Archiver
1. En haut, remplace ton iPhone par **Any iOS Device (arm64)**
2. **Product → Archive** (compte 5-10 min)
3. La fenêtre **Organizer** s'ouvre sur l'archive
Si *Archive* est grisé : tu es encore sur un simulateur, repasse en *Any iOS Device*.
## Étape 9 — Envoyer sur TestFlight
1. Dans l'Organizer : **Distribute App****App Store Connect****Upload**
2. Laisse les options par défaut → **Next****Upload**
3. Attends 5-30 min qu'Apple finisse le *processing* (mail de confirmation)
4. [appstoreconnect.apple.com](https://appstoreconnect.apple.com) → **Coach
Hypnotruck** → **TestFlight** → le build 23 apparaît
5. ⚠️ **Assigne le build au groupe de testeurs internes** — sans ça, il
n'apparaît pas dans TestFlight sur ton iPhone. Ça nous a bloqués en mai :
*Internal Testing* → ton groupe → **+** → coche le build 23
6. Sur l'iPhone : app **TestFlight****Mettre à jour**
⚠️ Le cache WKWebView est tenace. Si l'app affiche encore l'ancienne interface
après mise à jour : **désinstalle l'app** puis réinstalle depuis TestFlight.
---
## En cas de blocage
Note l'étape et le message d'erreur exact, et envoie-les-moi. Utile à joindre :
```bash
# état du repo
cd ~/coach-ios && git log --oneline -3 && git status -sb
# les fichiers Swift sont-ils tous câblés ? (doit ne rien afficher sauf
# CoachWatchComplications si tu as sauté l'étape 5)
# -not -path '*/build/*' est indispensable : DerivedData et les checkouts SPM
# contiennent des centaines de .swift qui n'ont rien à faire dans le pbxproj
for f in $(find ios -name '*.swift' -not -path '*/build/*' -not -path '*/CapApp-SPM/*'); do
grep -q "$(basename $f)" ios/App/App.xcodeproj/project.pbxproj || echo "NON CÂBLÉ: $f"
done
```
Pour les erreurs de plugins à l'exécution : Safari → menu **Développement**
ton iPhone → `coach.hypnotruck.ch` → console :
```js
Object.keys(Capacitor.Plugins).filter(k => k.startsWith('Coach'))
// doit lister : CoachWorkoutKit, CoachHealthRoute, CoachWorkoutObserver,
// CoachLiveBridge, CoachAppleAuth, CoachGoogleAuth,
// CoachWidgetBridge, CoachRoutineBridge
```
## Rappels permanents
- **Toujours quitter Xcode avant un `git pull`.**
- **Toujours commit + push après une modification faite dans Xcode**
(capability, signing, target) — sinon le prochain pull est bloqué.
- Les changements **web** (templates, CSS, routes) ne demandent **aucun build** :
ils arrivent au prochain lancement de l'app.