Le build échouait au lancement sur _UIApplicationEvaluateRuntimeIssueForNo
SceneLifecycleAdoption. Apple est explicite : « Beginning in iOS 27 […] apps
built with the latest SDK must adopt the scene-based life cycle or they fail to
launch » (Transitioning to the UIKit scene-based life cycle). Ce n'est plus un
avertissement comme en iOS 26, c'est un assert. Aucune dérogation n'est
documentée : ni clé Info.plist, ni entitlement, ni date de tolérance — le seul
report possible serait de ne pas construire avec le dernier SDK, ce qui ne fait
que déplacer l'échéance sous contrainte de release.
Capacitor a adopté UIScene en 8.5.0 (PR #8536, « required in iOS 27 »), et
8.5.2 corrige une régression qui faisait échouer chaque démarrage à froid sur
une JS Eval error (#8595). On passe donc de 8.3.1 à 8.5.2, pas à 8.5.0.
⚠️ npx cap migrate N'A PAS été utilisé, et c'est volontaire : le guide officiel
exclut les projets à gestion d'URL personnalisée dans l'AppDelegate — « Projects
with hand-rolled scene delegates or custom AppDelegate URL handling should
follow the manual steps instead ». Notre branche GoogleSignIn en est la
définition. Le SceneDelegate suit le template livré dans le paquet 8.5.2, avec
deux écarts nécessaires décrits ci-dessous.
⚠️ CE QUI CASSE EN SILENCE, et qui est repris dans SceneDelegate.swift. Une
fois le manifeste posé, UIKit cesse d'appeler trois méthodes de l'AppDelegate
« even if you keep them implemented » (Apple) :
- application(_:open:options:) -> le retour OAuth Google partirait vers Safari
sans jamais revenir. Déprécié iOS 26, remplacé par scene(_:openURLContexts:).
La signature change : une URL devient un Set, donc on filtre ce que Google
consomme avant de passer le reste à Capacitor.
- applicationDidBecomeActive -> les saisies du widget (eau, café) resteraient
bloquées dans l'App Group. Reprise dans sceneDidBecomeActive.
- application(_:continue:restorationHandler:) -> les Universal Links des
widgets et complications ouvriraient Safari, où le cookie d'auth n'existe pas.
Aucune des trois ne produit d'erreur de compilation. Elles ne sont pas laissées
en doublon dans l'AppDelegate : une méthode morte qui a l'air vivante fait
chercher la panne au mauvais endroit.
✅ CE QUI NE BOUGE PAS, vérifié dans la doc avant d'écrire une ligne :
didFinishLaunchingWithOptions reste appelé, et Apple documente la séquence
(launch -> création des scènes -> scene(_:willConnectTo:)). L'injection du
cookie garde donc son ordre : elle s'exécute avant que la WKWebView charge. La
règle non négociable n°2 du CLAUDE.md est tenue. Les callbacks de notification
distante restent aussi sur l'AppDelegate — UISceneDelegate n'a aucun équivalent
et ils ne sont pas dépréciés.
Écart au template Capacitor : il pose un CAPBridgeViewController() nu comme
rootViewController. L'appliquer tel quel remplacerait MainViewController, qui
porte l'enregistrement des 9 plugins natifs et la config WKWebView — sans
erreur visible. Le manifeste gardant UISceneStoryboardFile = Main, UIKit charge
déjà le storyboard : on ne crée la fenêtre que s'il ne l'a pas fait, et avec
notre sous-classe.
npm audit : 0 vulnérabilité en production. 13 dans l'outillage de build, qui ne
part pas dans l'app. ⛔ Ne PAS lancer npm audit fix --force : il propose de
redescendre @capacitor/cli en 7.6.9, ce qui supprimerait le support UIScene.
⚠️ RESTE À FAIRE SUR LE MAC, et rien ne compilera sans : ajouter
SceneDelegate.swift au target App dans Xcode. Le dossier App/ utilise des
références explicites dans le pbxproj (les groupes synchronisés ne couvrent que
les targets Watch/Widgets), et je n'édite pas un pbxproj à l'aveugle.
Vérifié ici : plist valide et relu par plistlib, syntaxe des deux fichiers
Swift validée par swiftc -parse. Aucune compilation possible sur Linux.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Ajoute le plugin natif capacitor-native-settings@8.1.0 qui permet
d'ouvrir directement la page Localisation dans Réglages iPhone via
UIApplication.shared.open() (API officielle Apple).
Cas d'usage : depuis /settings → Météo → bouton 'Gérer la permission
iOS' → ouvre Réglages → Confidentialité → Localisation → Coach
Hypnotruck. C'est ce qu'utilisent Strava, Komoot, Uber, etc.
Sync ios/App/CapApp-SPM/Package.swift via npx cap sync ios — le
plugin est maintenant inclus dans le build iOS.
⚠️ Requiert rebuild TestFlight v1.2 :
cd /Users/sylvainbettinelli/Documents/coach-ios/ios/App
pod install (ou via Xcode si SPM)
Xcode → Product → Archive → upload TestFlight
Côté webapp, le bouton tombera en fallback (instructions texte) tant
que la nouvelle build TestFlight n'est pas installée. Le code détecte
window.Capacitor.Plugins.NativeSettings et bascule selon dispo.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- package.json : name 'coach-mobile', description mentionne iOS+Android,
scripts 'sync', 'sync:ios', 'sync:android', 'open:android', 'build:android'
- README.md : titre "Coach Hypnotruck — Mobile (iOS + Android)", section
Architecture mentionne Coque Android Capacitor + Health Connect, commande
cap-assets sans --ios pour générer les deux plateformes en une fois
- coach-ios.local.json filename CONSERVÉ pour ne pas casser les references
dans le code Swift natif AppDelegate.swift / CoachAuth.swift
Action user pour finaliser :
1. Renommer le repo Gitea : Settings → Repository name → coach-mobile
2. Local : `mv ~/coach-ios ~/coach-mobile && cd ~/coach-mobile`
3. Update remote : `git remote set-url origin git@gitea:sylvain/coach-mobile.git`
Génère la structure Capacitor Android (gradle + manifest + activity Java/Kotlin)
avec applicationId 'ch.hypnotruck.coach' (cohérent avec iOS), minSdk 24, target 36.
8 plugins synchronisés au passage (déjà déclarés dans package.json) :
@capacitor/{app,geolocation,haptics,local-notifications,push-notifications,
splash-screen,status-bar} et @capgo/capacitor-health.
Build APK toujours bloqué côté infra (Android SDK non installé sur cette machine,
+ attente validation Play Console pour signing/upload). Mais la structure est
prête : `cap sync` après modification du web puis `./gradlew assembleDebug`
sur une machine avec Android SDK.
Étape suivante : configurer permissions Health Connect dans AndroidManifest +
sync iOS pour cohérence cross-platform.
- Capacitor 8 + plugins natifs (push, local-notif, geoloc, HealthKit Capgo, splash, status bar, haptics)
- Config pointe vers https://coach.hypnotruck.ch (server.url)
- Icône 1024×1024 + splash 2732×2732 depuis icon-512 PWA coach_sportif
- README complet avec procédure build sur Mac mini
- Bundle ID : ch.hypnotruck.coach, App name : Coach Hypnotruck