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>
10 KiB
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.
cd ~/coach-ios
git pull
npm install
npx cap sync ios
Vérification — tu dois voir f30cc60 ou plus récent :
git log --oneline -1
Si npx cap sync râle sur la version de Node :
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.
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 :
# 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.
- developer.apple.com → Certificates, IDs & Profiles
- Identifiers → menu déroulant en haut à droite → App Groups
- Le groupe
group.ch.hypnotruck.coachexiste déjà ? → rien à faire. Sinon : + → App Group → DescriptionCoach Hypnotruck, Identifiergroup.ch.hypnotruck.coach→ Continue → Register
Étape 4 — Activer la capability dans Xcode
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 :
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.
- Menu File → New → Target…
- Onglet watchOS → Widget Extension → Next
- Product Name :
CoachWatchWidgets— décoche Include Live Activity — Embed in Application :CoachWatch→ Finish - Xcode propose d'activer le nouveau schéma → Activate
- Dans le dossier
CoachWatchWidgetscréé, supprime le fichierCoachWatchWidgets.swiftgénéré (clic droit → Delete → Move to Trash) - Clic droit sur le dossier
CoachWatchWidgets→ Add Files to "App"… → sélectionneios/App/CoachWatchWidgets/CoachWatchComplications.swift→ décoche Copy items if needed, coche la targetCoachWatchWidgets - Sélectionne
CoachWidgetSnapshot.swiftdans la colonne de gauche → inspecteur de droite (Cmd+Option+1) → Target Membership → coche CoachWatchWidgets - Target
CoachWatchWidgets→ Signing & Capabilities → + Capability → App Groups → cochegroup.ch.hypnotruck.coach
Puis commit + push (même raison qu'à l'étape 4).
Étape 6 — Compiler et tester sur l'iPhone
- Branche l'iPhone, déverrouille-le, avec l'Apple Watch au poignet et appairée
- En haut de Xcode, sélectionne le schéma App et ton iPhone comme device
- Product → Clean Build Folder (
Cmd+Shift+K) - 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)
- L'app se lance et tu es connecté → le cookie natif fonctionne.
- 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
/livede l'iPhone. ⚠️ C'est le test le plus important : j'ai touché àCoachLiveBridgepour faire passer la routine. Si la FC ne remonte plus, dis-le-moi. - Routine sur la Watch : ouvre
/routinesur 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. - Widgets iPhone : écran d'accueil → appui long → + → cherche Coach → ajoute « Séance du jour » et « Score de forme ».
- Login natif : déconnecte-toi, teste Se connecter avec Apple et Google.
Vérification serveur de la routine :
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
- En haut, remplace ton iPhone par Any iOS Device (arm64)
- Product → Archive (compte 5-10 min)
- 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
- Dans l'Organizer : Distribute App → App Store Connect → Upload
- Laisse les options par défaut → Next → Upload
- Attends 5-30 min qu'Apple finisse le processing (mail de confirmation)
- appstoreconnect.apple.com → Coach Hypnotruck → TestFlight → le build 23 apparaît
- ⚠️ 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
- 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 :
# é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 :
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.