Créer des apps iOS avec des agents IA : le guide pratique
# Créez des apps iOS plus rapidement avec des agents IA. Claude Code, Codex CLI, Xcode 26.3 en natif, MCP, modèles CLAUDE.md, hooks, leçons tirées de 8 apps.
TL;DR : Trois environnements d’exécution d’agents livrent désormais du code pour iOS : Claude Code CLI avec MCP, Codex CLI avec MCP, et les agents Intelligence natifs de Xcode 26.3. Deux serveurs MCP (XcodeBuildMCP avec 59 outils et
xcrun mcpbridged’Apple avec 20 outils) donnent aux agents un accès structuré aux builds, aux tests, aux simulateurs et au débogage. Ce guide couvre des patterns CLAUDE.md réels, des configurations de hooks et des évaluations honnêtes de ce qui fonctionne comme de ce qui casse — à partir de 8 apps iOS en production totalisant 293 fichiers Swift.18 Les agents excellent avec les vues SwiftUI, les modèles SwiftData, le refactoring et le diagnostic d’erreurs de build. Ils échouent sur les modifications de .pbxproj, la signature de code et le débogage visuel. L’écart entre « l’agent écrit du Swift » et « l’agent livre une app iOS » se comble par la configuration, pas par le prompting.
J’ai construit 8 apps iOS avec des agents de codage IA. Pas des prototypes : des apps dans l’App Store, avec des intégrations HealthKit, des shaders Metal, de la physique SpriteKit, la synchronisation iCloud, des Live Activities, des classements Game Center et des cibles multiplateformes couvrant iOS, watchOS et tvOS. Chaque ligne de Swift dans ces apps a soit été écrite par un agent puis relue par moi, soit écrite par moi puis refactorisée par un agent. Selon mon estimation, les agents ont pris en charge l’essentiel de l’écriture au niveau des lignes ; je me suis occupé de la revue, du périmètre et des parties qui exigent un jugement humain (polish visuel, signature, optimisation des performances, soumission à l’App Store).
Ce guide est la référence que j’aurais voulu avoir au début. Il couvre toute la stack : quel environnement d’exécution d’agent utiliser, comment configurer les serveurs MCP pour un accès structuré au build, quoi mettre dans votre CLAUDE.md, quels hooks empêchent l’agent de détruire votre projet Xcode et, surtout, où les agents échouent et où vous devez reprendre la main.
Points clés à retenir
Pour les développeurs iOS qui découvrent les agents IA :
- Commencez avec Claude Code CLI + XcodeBuildMCP. C’est l’environnement d’exécution le plus mature, avec la couverture d’outils MCP la plus profonde. Installez deux commandes, ajoutez un CLAUDE.md à votre projet, et l’agent peut builder, tester et déboguer sans que vous copiiez les messages d’erreur.
- Ne laissez jamais un agent modifier .pbxproj. C’est la règle la plus importante. Un hook PreToolUse qui bloque les écritures vers
.pbxprojet.xcodeproj/vous épargnera des heures de récupération. - Votre CLAUDE.md est le document d’onboarding de l’agent. Les heures passées dessus sont rentabilisées à chaque session d’agent qui touche au projet.
Pour les utilisateurs expérimentés d’agents qui ajoutent iOS à leur workflow :
- MCP transforme la boucle de build iOS. Avant MCP, les agents écrivaient du Swift mais ne pouvaient pas vérifier qu’il compilait. Avec XcodeBuildMCP, l’agent écrit le code, le build, lit les erreurs structurées, les corrige et lance les tests — de façon autonome.
- Trois environnements d’exécution répondent à des besoins différents. Claude Code CLI pour les sessions agentiques approfondies, Codex CLI pour le travail batch headless, les agents natifs de Xcode 26.3 pour des corrections inline rapides sans quitter l’IDE.
- L’infrastructure de hooks se transpose. Vos formatters PostToolUse, bloqueurs PreToolUse et hooks de lancement de tests existants fonctionnent de la même façon pour les projets iOS, avec de petits ajustements de chemins.
Pour les leads d’équipe qui évaluent le développement iOS assisté par IA :
- L’efficacité des agents dépend de la documentation du projet, pas de sa taille. Une app de 63 fichiers avec un CLAUDE.md détaillé produit une meilleure sortie d’agent qu’une app de 14 fichiers sans documentation.
- La frontière .pbxproj n’est pas négociable. Les agents ne savent pas modifier les fichiers de projet Xcode de façon fiable. Votre workflow doit intégrer l’ajout manuel des fichiers aux cibles Xcode.
- ROI honnête : les agents prennent en charge l’essentiel de l’implémentation sur les projets bien documentés — cela se voit dans l’app TV de 15 fichiers livrée en 3 heures de travail assisté par agent (étude de cas ci-dessous). Le reste — polish visuel, signature, optimisation des performances, soumission à l’App Store — exige un jugement humain.
Choisissez votre parcours
| Ce dont vous avez besoin | Où aller |
|---|---|
| Configurer MCP pour la première fois | Configuration de MCP : la configuration complète — installer les deux serveurs, vérifier, configurer les agents |
| Écrire un CLAUDE.md pour votre projet iOS | Patterns CLAUDE.md pour les projets iOS — exemples réels tirés de 8 apps |
| Comparer les trois environnements d’exécution d’agents | Trois environnements d’exécution d’agents pour iOS — Claude Code vs. Codex vs. Xcode natif |
| Comprendre ce que les agents peuvent et ne peuvent pas faire | Ce que les agents font bien et Ce que les agents font mal |
| Configurer des hooks pour le développement iOS | Hooks pour le développement iOS — format-on-save, protection .pbxproj, runners de tests |
| Référence approfondie (cette page) | Continuez la lecture — tout, de la configuration aux patterns avancés |
Comment utiliser ce guide
C’est une référence de plus de 3 000 lignes. Commencez là où votre niveau d’expérience correspond :
| Expérience | Commencez ici | Puis explorez |
|---|---|---|
| Nouveau sur iOS + les agents | Prérequis → Configuration MCP → Votre première session d’agent | Patterns CLAUDE.md, Ce qui fonctionne / ne fonctionne pas |
| Développeur iOS, nouveau avec les agents | Trois environnements d’exécution → Configuration MCP → CLAUDE.md | Hooks, Patterns d’architecture |
| Utilisateur d’agents, nouveau sur iOS | Patterns d’architecture → Ce que les agents font mal → CLAUDE.md | Contexte spécifique aux frameworks, Workflows avancés |
| Expérimenté avec les deux | Workflows avancés → Hooks → Patterns multiplateformes | Comparaison des environnements d’exécution, Le portfolio |
Table des matières
- Le portfolio : 8 apps, 293 fichiers
- Prérequis
- Trois environnements d’exécution d’agents pour iOS
- Configuration de MCP : la configuration complète
- Patterns CLAUDE.md pour les projets iOS
- Votre première session d’agent
- Ce que les agents font bien dans iOS
- Ce que les agents font mal dans iOS
- Hooks pour le développement iOS
- Patterns d’architecture qui fonctionnent avec les agents
- Contexte spécifique aux frameworks
- Patterns multiplateformes
- Workflows avancés
- Études de cas réelles
- Cycle de vie du projet avec les agents
- Configuration des définitions d’agents
- Patterns de test pour iOS assisté par agent
- Gestion de la fenêtre de contexte pour les projets iOS
- Dépannage
- Erreurs courantes des agents dans iOS
- L’évaluation honnête
- FAQ
- Fiche de référence rapide
- Références
Ressources connexes
| Sujet | Ressource |
|---|---|
| Configuration MCP pour Xcode (article de blog plus court) | Deux serveurs MCP ont transformé Claude Code en système de build iOS |
| Référence complète de Claude Code CLI | Claude Code CLI : le guide complet |
| Référence Codex CLI | Codex CLI : le guide complet |
| Analyse approfondie du système de hooks | Anatomy of a Claw : 84 hooks comme couche d’orchestration |
| Patterns d’architecture d’agents | Guide d’architecture d’agents |
| App de bureau Mac + Remote Control | Claude Code Mac Desktop + Remote Control : guide utilisateur CLI |
Série Apple Ecosystem. 21 articles de production sur des apps SwiftUI qui s’intègrent à Apple Intelligence, MCP, Foundation Models, Vision, Core ML et la stack de frameworks iOS 26. Tiré de Water, Get Bananas, Return et du reste du portfolio 941 :
Hub de la série : Apple Ecosystem Series
Agentic Apple (E4) :
| Sujet | Ressource |
|---|---|
| Surface d’intentions d’Apple Intelligence | App Intents Are Apple’s New API to Your App |
| Serveur MCP aux côtés d’une app iOS | Deux écosystèmes d’agents, une liste de courses |
| Quand utiliser lequel | App Intents vs MCP Tools : la question du routage |
| LLM on-device comme fonctionnalité d’exécution vs tooling | Foundation Models + workflow agentique |
| Hooks pour le développement Apple | Hooks pour le développement Apple |
| État entre processus | Source unique de vérité : SwiftData + MCP + iCloud |
Frameworks (E2/E3) :
| Sujet | Ressource |
|---|---|
| LLM on-device de Foundation Models | Foundation Models On-Device LLM |
| Framework Vision (primitives CV) | Vision Framework : ce qui est intégré |
| Patterns d’inférence Core ML | Inférence Core ML on-device |
| Modèle mental spatial RealityKit | RealityKit et le modèle mental spatial |
| Internes de SwiftUI | De quoi SwiftUI est fait |
| Vocabulaire d’animation Symbol Effects | Symbol Effects : le vocabulaire d’animation intégré de SwiftUI |
| Liquid Glass sur iOS 26+ | Liquid Glass dans SwiftUI : trois patterns |
Code livré (E1) :
| Sujet | Ressource |
|---|---|
| Machine à états Live Activities | Machine à états Live Activities |
| Contrat d’exécution watchOS | Contrat d’exécution watchOS |
| Discipline de schéma SwiftData | Discipline de schéma SwiftData |
| Patterns HealthKit + SwiftUI | HealthKit + SwiftUI sur iOS 26 |
| SwiftUI multiplateforme | Cinq plateformes Apple, trois fichiers partagés |
| Intégration XcodeBuildMCP | Deux serveurs MCP, un projet Xcode |
Synthèse (E5) :
| Sujet | Ressource |
|---|---|
| Trois surfaces d’une app iOS | Les trois surfaces d’une app iOS |
| Décisions de cibles plateformes | La matrice des plateformes Apple |
| Ce sur quoi je refuse d’écrire | Ce sur quoi je refuse d’écrire |
Le portfolio : 8 apps, 293 fichiers
Avant de plonger dans la configuration, voici d’où vient ce guide. Il ne s’agit pas de projets jouets : ils couvrent cinq frameworks Apple, trois plateformes et tout l’éventail de complexité iOS, du suivi d’entraînement en 14 fichiers au minuteur de méditation multiplateforme en 63 fichiers.
| App | Stack | Fichiers | Complexité |
|---|---|---|---|
| Banana List | SwiftUI + SwiftData + synchronisation iCloud Drive + serveur MCP pour Claude Desktop | 53 | CRUD complet, synchronisation iCloud, serveur MCP personnalisé qui expose les données de l’app à Claude Desktop |
| Ace Citizenship | App d’étude SwiftUI + backend FastAPI | 26 | Client-serveur, intégration REST API, moteur de quiz |
| TappyColor | Jeu d’association de couleurs SpriteKit | 30 | Boucle de jeu, physique, gestion du toucher, effets de particules |
| Return | Minuteur de méditation zen — iOS 26+, watchOS, tvOS | 63 | HealthKit, Live Activities, exécution prolongée sur Watch, navigation par focus sur TV, synchronisation iCloud des sessions |
| amp97 | Shaders Metal + visualisation audio | 41 | Pipeline de rendu Metal personnalisé, analyse audio, calcul GPU en temps réel |
| Reps | Suivi d’entraînement SwiftUI + SwiftData | 14 | App minimale viable, patterns SwiftData propres |
| Water | Suivi d’hydratation SwiftUI + SwiftData + Metal + HealthKit | 34 | Simulation de fluide Metal, journalisation de la consommation d’eau HealthKit, widget |
| Starfield Destroyer | Jeu de tir spatial SpriteKit + Metal | 32 | 99 niveaux, 8 vaisseaux, classements Game Center, post-traitement Metal |
Pourquoi le nombre de fichiers compte : l’efficacité des agents est corrélée à la lisibilité du projet, pas à sa taille. Return (63 fichiers) produit de meilleurs résultats avec les agents qu’amp97 (41 fichiers), car Return dispose d’un CLAUDE.md détaillé avec annotations de fichiers, schémas d’architecture et patterns explicites. Les shaders Metal d’amp97 sont intrinsèquement plus difficiles à raisonner pour les agents, quelle que soit la qualité de la documentation.
Prérequis
Avant de configurer un runtime d’agent pour le développement iOS :
Échéance App Store Connect : à partir du 28 avril 2026, les apps envoyées à App Store Connect devront être créées avec Xcode 26 ou version ultérieure en utilisant des SDKs pour iOS 26, iPadOS 26, tvOS 26, visionOS 26 ou watchOS 26.12 (Les soumissions macOS ne sont pas concernées par cette exigence.) Si votre équipe utilise encore Xcode 16.x, la chaîne d’outils assistée par agents de ce guide sert aussi de contrainte de mise à niveau : aucun des serveurs MCP ci-dessous ne fonctionne sans Xcode 26.3+ de toute façon.
Obligatoire :
- macOS 15+ (Sequoia) ou macOS Tahoe
- Xcode 26.3+ installé et configuré (le minimum pour xcrun mcpbridge) ; Xcode 26.5+ recommandé pour les améliorations du workflow agent — mise en file d’attente des messages dans l’assistant de codage et prise en charge des questions de clarification — ainsi que les pièces jointes d’images Swift Testing, la sévérité des problèmes enregistrés, les avertissements de plantage des tests UI avec crashlogs et les améliorations de l’éditeur String Catalog ajoutées pour la première fois en 26.4.1314 Xcode 26.5 (11 mai 2026, build 17F42) est la dernière version stable ; 26.4.1 (16 avril 2026, build 17E202) était la dernière version corrective de la branche 26.4.15
- Au moins un runtime iOS Simulator installé
- Un compte Anthropic API (pour Claude Code) ou un compte OpenAI (pour Codex)
Recommandé :
- SwiftFormat installé (brew install swiftformat) — utilisé par les hooks de formatage à l’enregistrement
- SwiftLint installé (brew install swiftlint) — facultatif, mais utile pour faire respecter le style
- Une bonne connaissance du terminal — les trois runtimes fonctionnent depuis la ligne de commande ou s’y intègrent
Vérifiez votre installation de Xcode :
# Check Xcode version
xcodebuild -version
# Expected: Xcode 26.3 or later (26.5+ recommended)
# Check available simulators
xcrun simctl list devices available
# Expected: at least one iPhone simulator
# Verify xcrun mcpbridge is available
xcrun mcpbridge --help
# Expected: usage information (not "command not found")
Si xcrun mcpbridge renvoie « command not found », vous avez besoin de Xcode 26.3 ou version ultérieure. Installez ou mettez à jour Xcode via l’App Store ou developer.apple.com. Remarque : xcode-select --install installe uniquement les Command Line Tools, qui n’incluent pas mcpbridge — vous avez besoin de l’application Xcode.app complète.
Trois runtimes d’agents pour iOS
Trois runtimes distincts peuvent écrire, compiler et tester du code iOS. Ils ne sont pas interchangeables — chacun a des forces différentes, des modèles d’intégration MCP différents et des cas d’usage idéaux différents.
1. Claude Code CLI
Ce que c’est : l’assistant de codage agentique en terminal de Anthropic. Il lit votre base de code, exécute des commandes, modifie des fichiers et se connecte à des outils externes via MCP.
Intégration MCP : prise en charge complète à la fois de XcodeBuildMCP et du MCP Xcode d’Apple. L’agent découvre les outils via le protocole MCP et les appelle avec des paramètres structurés. 59 + 20 outils répartis entre les deux serveurs.
Installation :
# Install Claude Code (if not already installed)
claude --version # verify installation
# Add XcodeBuildMCP (59 tools — builds, tests, simulators, debugging)
claude mcp add XcodeBuildMCP \
-s user \
-e XCODEBUILDMCP_SENTRY_DISABLED=true \
-- npx -y xcodebuildmcp@latest mcp
# Add Apple Xcode MCP (20 tools — file ops, diagnostics, Swift REPL, previews)
claude mcp add --transport stdio xcode \
-s user -- xcrun mcpbridge
Alternative — installateur automatique xcodebuildmcp init (v2.1.0+, 2026-02-23) :
Si vous préférez éviter le câblage manuel de MCP, XcodeBuildMCP v2.1.0+ embarque une sous-commande init qui détecte automatiquement Claude Code, Cursor ou Codex et installe les compétences d’agent ainsi que la configuration MCP en une seule étape :
xcodebuildmcp init
# Or without a global install:
npx -y xcodebuildmcp@latest init
Options : --print (écrire la configuration sur stdout pour les clients non pris en charge), --uninstall (désinstaller). Évitez cette commande si vous voulez un contrôle explicite sur les serveurs MCP câblés et leur portée ; les invocations manuelles claude mcp add ci-dessus vous donnent ce contrôle.16
Idéal pour : les sessions d’implémentation approfondies — création de nouvelles fonctionnalités, refactorisation à travers plusieurs fichiers, débogage de problèmes complexes, exécution autonome de boucles compilation-test-correction. La fenêtre de contexte de 1M de Claude Code (avec Opus 4.6) signifie que l’agent peut conserver la plupart des projets iOS de petite à moyenne taille en mémoire de travail — d’après mon expérience, jusqu’à environ 50 fichiers selon leur taille.
Session typique :
You: Add a new SettingsView with toggles for notifications and haptic feedback.
Use the existing Settings.swift pattern from TimerManager.
Build for simulator after implementation and fix any errors.
Claude: [reads Settings.swift, TimerManager.swift, existing views]
[creates SettingsView.swift]
[calls build_sim via MCP]
[reads structured error: missing import HealthKit]
[fixes import]
[calls build_sim again — success, 0 errors, 1 warning]
[calls test_sim — all tests pass]
La différence clé par rapport au workflow pré-MCP : l’agent ne vous demande jamais de compiler manuellement ou de coller la sortie d’erreur. La boucle compilation-erreur-correction est autonome.
2. Codex CLI
Ce que c’est : l’agent de codage en terminal d’OpenAI. Similaire en concept à Claude Code mais utilise des modèles OpenAI (GPT-4o, o3) et possède un modèle d’autorisations différent.
Intégration MCP : Codex prend en charge MCP via la commande codex mcp add. Le MCP Xcode d’Apple fonctionne directement :
# Add Apple Xcode MCP to Codex
codex mcp add xcode -- xcrun mcpbridge
XcodeBuildMCP fonctionne également avec Codex via la même commande npx :
# Add XcodeBuildMCP to Codex
codex mcp add XcodeBuildMCP -- npx -y xcodebuildmcp@latest mcp
Idéal pour : les opérations batch sans interface, l’intégration CI/CD et les tâches pour lesquelles vous voulez un second avis d’une autre famille de modèles. Le mode sandbox de Codex exécute le code dans des environnements isolés, ce qui s’avère utile pour des opérations destructives comme l’exécution de suites de tests qui modifient l’état.
Différences clés par rapport à Claude Code :
- Utilise des modèles OpenAI au lieu des modèles Claude
- Tailles de fenêtre de contexte et économie de tokens différentes
- Modèle d’autorisations sandbox-first (plus restrictif par défaut)
- Écosystème MCP plus restreint (moins de serveurs communautaires testés)
- Système de hooks disponible (v0.119.0+) mais moins mature que celui de Claude Code — moins de types d’événements et pas de champ if conditionnel
Quand utiliser Codex plutôt que Claude Code pour iOS :
Utilisez Codex lorsque vous voulez de la diversité de modèles — faire relire le code écrit par un premier agent par un second permet de détecter différentes classes d’erreurs. Le workflow collab (Claude construit, Codex relit) s’avère efficace pour iOS car les patterns SwiftUI qui semblent corrects à une famille de modèles peuvent avoir des problèmes subtils qu’une autre détecte. Les shaders Metal et les patterns de concurrence bénéficient particulièrement d’une relecture par double modèle.
3. Agents natifs Xcode 26.3
Ce que c’est : Apple a intégré directement des agents de codage IA dans le panneau Intelligence de Xcode. Depuis Xcode 26.3, vous pouvez configurer Claude Agent et Codex comme fournisseurs d’intelligence dans Xcode Settings > Intelligence.
Installation :
- Ouvrez Xcode 26.3+
- Naviguez vers Settings > Intelligence
- Ajoutez un nouveau fournisseur :
- Pour Claude : sélectionnez « Claude Agent », saisissez votre clé API Anthropic
- Pour Codex : sélectionnez « Codex », saisissez votre clé API OpenAI
- L’agent apparaît dans la barre latérale Intelligence et peut être invoqué en ligne
Idéal pour : les modifications rapides en ligne, la complétion de code avec un raisonnement de niveau agent, et les développeurs qui préfèrent ne pas quitter Xcode. L’intégration native signifie que l’agent a un accès direct au contexte du projet Xcode — fichiers ouverts, cibles de build, configuration de scheme — sans pont MCP.
Limitations par rapport aux agents CLI : - Pas de système de hooks — vous ne pouvez pas imposer le format-on-save ou bloquer les écritures .pbxproj - Pas de chargement de CLAUDE.md — l’agent ne lit pas vos fichiers de configuration au niveau projet - Autonomie limitée — l’agent opère sur le fichier courant ou la sélection, pas sur l’ensemble du projet - Pas de délégation à des sous-agents — les tâches complexes en plusieurs étapes ne peuvent pas être parallélisées - Pas de configuration de serveur MCP — l’agent utilise uniquement les outils intégrés à Xcode
Quand utiliser les agents natifs Xcode :
Pour des modifications rapides et ciblées où passer au terminal représente un coût excessif. « Ajoutez une propriété calculée à ce modèle. » « Écrivez un test unitaire pour cette fonction. » « Refactorisez cette vue pour utiliser @Observable. » Des tâches qui touchent un ou deux fichiers et ne nécessitent pas de cycle compilation-test.
Pour tout ce qui nécessite de la compilation, des tests, de la refactorisation multi-fichiers ou une correction d’erreur autonome, utilisez un agent CLI avec MCP.
Matrice comparative des runtimes
| Capacité | Claude Code CLI | Codex CLI | Xcode 26.3 natif |
|---|---|---|---|
| Prise en charge MCP | Complète (79 outils) | Complète (79 outils) | Outils Xcode intégrés uniquement |
| Système de hooks | Oui (mature) | Oui (basique, v0.119.0+) | Non |
| CLAUDE.md / config projet | Oui | Équivalent codex.md | Non |
| Compilation-test-correction autonome | Oui (via MCP) | Oui (via MCP) | Partielle (en ligne uniquement) |
| Délégation à des sous-agents | Oui (jusqu’à 10 en parallèle) | Non | Non |
| Fenêtre de contexte | 1M tokens (Opus 4.6) | Varie selon le modèle | Varie selon le fournisseur |
| Opérations multi-fichiers | Accès complet à la base de code | Accès complet à la base de code | Fichier courant / sélection |
| Protection .pbxproj | Via hooks | Manuelle | N/A (utilise Xcode nativement) |
| Format-on-save | Via hooks PostToolUse | Outillage externe | Paramètres Xcode |
| Capacité hors ligne | Non | Non | Non |
| Modèle de coût | Usage API Anthropic | Usage API OpenAI | Usage API du fournisseur |
La recommandation : utilisez Claude Code CLI comme runtime principal. Utilisez les agents natifs Xcode 26.3 pour les modifications rapides en ligne. Utilisez Codex CLI pour les passes de relecture et les opérations batch. Les trois se complètent au lieu de se concurrencer.
Configuration de MCP : la configuration complète
MCP (Model Context Protocol) fait passer un agent de « écrit du Swift et espère que vous le compilerez » à « écrit du Swift, le compile, lit des erreurs structurées et les corrige ». Cette section va plus loin que l’article de blog : elle couvre les deux serveurs, toutes les méthodes d’installation, la vérification et la configuration de l’agent qui garantit que les outils sont réellement utilisés.
XcodeBuildMCP : 59 outils pour le développement iOS sans interface
XcodeBuildMCP encapsule xcodebuild, xcrun simctl et LLDB dans 59 outils MCP structurés. Il fonctionne sans Xcode lancé : tout le cycle compilation-test-débogage s’exécute sans interface via les outils en ligne de commande d’Apple.
Options d’installation :
# Option 1: Via npx (recommended — always uses latest version)
claude mcp add XcodeBuildMCP \
-s user \
-e XCODEBUILDMCP_SENTRY_DISABLED=true \
-- npx -y xcodebuildmcp@latest mcp
# Option 2: Via Homebrew (pinned version, manual updates)
brew install xcodebuildmcp
claude mcp add XcodeBuildMCP \
-s user \
-e XCODEBUILDMCP_SENTRY_DISABLED=true \
-- xcodebuildmcp mcp
# Option 3: Project-scoped (omit -s user)
claude mcp add XcodeBuildMCP \
-e XCODEBUILDMCP_SENTRY_DISABLED=true \
-- npx -y xcodebuildmcp@latest mcp
L’option -s user rend le serveur disponible globalement dans tous les projets. Omettez-la pour une installation limitée au projet (utile si vous voulez MCP uniquement dans les projets iOS, pas dans les projets web).
La variable d’environnement -e XCODEBUILDMCP_SENTRY_DISABLED=true désactive la télémétrie des rapports de plantage. XcodeBuildMCP inclut Sentry par défaut, qui envoie des données d’erreur incluant les chemins de fichiers. Désactivez-la, sauf si vous souhaitez contribuer des diagnostics au projet.1
Inventaire complet des outils (59 outils dans 8 catégories) :
| Catégorie | Outils | Ce qu’ils font |
|---|---|---|
| Découverte de projet | discover_projs, list_schemes, list_targets |
Trouver les fichiers .xcodeproj/.xcworkspace, lister les schémas et cibles disponibles |
| Compilation | build_sim, build_device, build_mac |
Compiler avec une sortie d’erreurs/avertissements JSON structurée par fichier et par ligne |
| Tests | test_sim, test_device |
Exécuter les tests avec les résultats réussite/échec par méthode |
| Cycle de vie du simulateur | list_sims, boot_sim, shutdown_sim, open_sim, session_set_defaults |
Créer, démarrer, gérer et configurer des simulateurs |
| Gestion des appareils | list_devices, install_device, launch_device |
Déploiement et gestion sur appareil réel |
| Débogage | debug_attach_sim, debug_attach_device, debug_breakpoint, debug_stack, debug_variables, debug_eval, debug_continue, debug_step, debug_detach |
Intégration LLDB complète avec points d’arrêt et inspection des variables |
| Automatisation UI | snapshot_ui, screenshot, tap, swipe, type_text |
Interaction automatisée et capture visuelle |
| Échafaudage de projet | create_project, add_file, add_package |
Créer des projets et ajouter des dépendances |
Les outils les plus importants au quotidien :
-
build_sim— Vous l’appellerez des centaines de fois. Il renvoie du JSON avec des erreurs catégorisées par fichier, ligne et gravité. L’agent lit l’erreur, navigue jusqu’au fichier et la corrige sans que vous touchiez à quoi que ce soit. -
test_sim— Renvoie les résultats par méthode de test. L’agent sait exactement quel test a échoué et pourquoi, pas seulement que « les tests ont échoué ». -
list_sims+boot_sim— Gestion des simulateurs sans mémoriser les options dexcrun simctl. L’agent découvre les runtimes disponibles et choisit un appareil approprié. -
discover_projs+list_schemes— Introspection du projet. L’agent n’a pas besoin de deviner le nom de votre schéma ni la structure de votre workspace. -
debug_attach_sim+debug_stack+debug_variables— Débogage LLDB à distance. L’agent peut définir des points d’arrêt, inspecter les variables et exécuter le code pas à pas sans que vous ouvriez le débogueur.
Apple Xcode MCP : 20 outils qui font le lien avec Xcode
Le serveur MCP d’Apple est fourni avec Xcode 26.3 via xcrun mcpbridge. Il communique avec un processus Xcode en cours d’exécution via XPC (le framework de communication interprocessus d’Apple), exposant un état interne auquel aucun outil CLI ne peut accéder.
Installation :
# Standard installation (global)
claude mcp add --transport stdio xcode \
-s user -- xcrun mcpbridge
# For Codex CLI
codex mcp add xcode -- xcrun mcpbridge
Nécessite Xcode 26.3+ et un processus Xcode en cours d’exécution. Si Xcode n’est pas ouvert, chaque appel MCP via ce serveur échouera ou restera bloqué. XcodeBuildMCP n’a pas cette limitation.
Inventaire des outils (20 outils dans 5 catégories) :
| Catégorie | Outils | Ce qu’ils font |
|---|---|---|
| Opérations sur les fichiers | XcodeRead, XcodeWrite, XcodeUpdate, XcodeGlob, XcodeGrep |
Lire/écrire des fichiers dans le contexte du projet Xcode |
| Compilation et tests | BuildProject, GetBuildLog, RunAllTests, RunSomeTests |
Compiler et tester avec le système de compilation interne de Xcode |
| Diagnostics | XcodeListNavigatorIssues, XcodeRefreshCodeIssuesInFile |
Diagnostics de code en temps réel (pas seulement les erreurs de compilation) |
| Code et documentation | ExecuteSnippet, DocumentationSearch |
Exécution Swift REPL et recherche dans la documentation Apple |
| Previews | RenderPreview |
Rendu sans interface des previews SwiftUI |
Outils propres à Apple MCP (non disponibles dans XcodeBuildMCP) :
-
DocumentationSearch— Recherche dans la documentation développeur d’Apple, y compris les sessions WWDC. Plus rapide et plus fiable qu’une recherche web pour les questions Apple API. Demandez « is HKQuantityType(.dietaryWater) valid? » et obtenez une réponse définitive depuis la source. -
ExecuteSnippet— Exécution Swift REPL dans le contexte du projet. L’agent peut vérifier le comportement API, tester des conversions de types et valider des expressions sans compiler toute l’app. -
RenderPreview— Rend les previews SwiftUI sans interface. L’agent peut vérifier si une vue s’affiche sans erreur, même s’il ne peut pas évaluer la justesse visuelle (le rendu est renvoyé sous forme de données, pas inspecté visuellement). -
XcodeListNavigatorIssues— Renvoie les diagnostics en temps réel de l’analyseur de Xcode, pas seulement les erreurs de compilation. Capture des problèmes comme les variables inutilisées, les cycles de rétention potentiels et les avertissements de dépréciation que le système de compilation ne remonte pas.
Pourquoi utiliser les deux serveurs
Ils se recoupent sur la compilation et les tests, mais diffèrent fondamentalement :
┌─────────────────────────────────────────────────────────────────┐
│ MCP TOOL COVERAGE │
├─────────────────────────────────────────────────────────────────┤
│ │
│ XcodeBuildMCP (59 tools) Apple Xcode MCP (20 tools) │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ Standalone │ │ Requires Xcode │ │
│ │ (no Xcode process) │ │ (XPC bridge) │ │
│ │ │ │ │ │
│ │ ✓ Simulators │ BOTH │ ✓ Documentation │ │
│ │ ✓ Real devices │ ┌─────┐ │ ✓ Swift REPL │ │
│ │ ✓ LLDB debugging │ │Build│ │ ✓ SwiftUI previews │ │
│ │ ✓ UI automation │ │Test │ │ ✓ Live diagnostics │ │
│ │ ✓ Project scaffold │ └─────┘ │ ✓ Analyzer issues │ │
│ │ ✓ Screenshot │ │ │ │
│ └─────────────────────┘ └─────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Utilisez XcodeBuildMCP pour : Le cycle compilation-test-débogage. Il fonctionne sans Xcode ouvert, consomme moins de mémoire système et offre une gestion plus riche des simulateurs et des appareils. C’est votre principal outil de compilation.
Utilisez Apple Xcode MCP pour : Les recherches de documentation, la vérification Swift REPL, le rendu de previews SwiftUI et les diagnostics en temps réel. Gardez Xcode ouvert pendant les sessions qui nécessitent ces capacités.
En pratique : J’utilise XcodeBuildMCP pour environ 90 % des appels MCP, et Apple Xcode MCP pour la documentation et la vérification REPL. L’agent utilise par défaut XcodeBuildMCP pour les compilations et les tests, car il est plus rapide (pas de surcharge liée au processus Xcode) et plus fiable (pas de dépendance XPC).
Vérification
Après avoir installé les deux serveurs, vérifiez qu’ils sont connectés :
# List all configured MCP servers
claude mcp list
# Expected output includes:
# XcodeBuildMCP: npx -y xcodebuildmcp@latest mcp - Connected
# xcode: xcrun mcpbridge - Connected
Si un serveur affiche « Disconnected » ou n’apparaît pas :
- XcodeBuildMCP ne se connecte pas : Vérifiez que Node.js est installé (
node --version). La commandenpxnécessite Node.js 18+. - Apple Xcode MCP ne se connecte pas : Vérifiez que Xcode 26.3+ est installé et que la commande
xcrun mcpbridgefonctionne dans votre terminal. Ouvrez Xcode au moins une fois pour accepter le contrat de licence. - Aucun des deux n’apparaît : Redémarrez Claude Code (
claudedans un nouveau terminal). Les serveurs MCP enregistrés en cours de session peuvent ne pas apparaître avant un redémarrage.
Apprendre à l’agent à utiliser MCP
Installer des serveurs MCP est nécessaire, mais insuffisant. Sans consignes explicites, l’agent peut revenir à l’exécution de xcodebuild via Bash (sortie non structurée, tokens de contexte gaspillés) ou utiliser la recherche web pour la documentation Apple (plus lente, moins fiable).
Ajoutez ceci à votre CLAUDE.md ou à la définition de votre agent :
## Build & Test — Always Use MCP
Prefer MCP tools over raw shell commands for ALL build operations:
- **Build**: `build_sim` / `build_device` (NOT `xcodebuild` via Bash)
- **Test**: `test_sim` / `test_device` (NOT `xcodebuild test` via Bash)
- **Simulators**: `list_sims`, `boot_sim`, `open_sim` (NOT `xcrun simctl` via Bash)
- **Debug**: `debug_attach_sim`, `debug_stack`, `debug_variables`
- **Apple docs**: `DocumentationSearch` (NOT WebSearch for Apple APIs)
- **Swift verification**: `ExecuteSnippet` (NOT `swift` via Bash)
- **Previews**: `RenderPreview` for headless SwiftUI verification
MCP returns structured JSON. Bash returns unstructured text.
Structured data means fewer tokens consumed and better error diagnosis.
Ces consignes garantissent que l’agent choisit d’abord les outils MCP. Sans elles, vous verrez l’agent construire de longues commandes xcodebuild via Bash, consommer des milliers de tokens de contexte pour analyser la sortie et parfois mal identifier l’erreur réelle.
Modèles CLAUDE.md pour projets iOS
Votre CLAUDE.md est le fichier le plus important du projet pour le développement assisté par agent. C’est le document d’intégration de l’agent : la différence entre une nouvelle recrue qui a lu la documentation d’architecture et une autre qui avance au jugé.
Chaque projet iOS que je maintiens possède un CLAUDE.md. Voici les modèles qui fonctionnent, tirés des 8 apps.
Les sections essentielles
Chaque CLAUDE.md iOS a besoin de ces six sections. Tout le reste est facultatif.
1. Identité du projet
# Return - Zen Focus Timer
**Bundle ID:** `com.941apps.Return`
**Target:** iOS 26+ / macOS Tahoe / watchOS 26+ / tvOS 26+
**Architecture:** SwiftUI with @Observable pattern, companion Watch and TV apps
**Swift version:** 6.2
**Minimum deployment:** iOS 26.0
Pourquoi c’est important : l’agent doit connaître la cible de déploiement avant d’écrire le moindre code. Un agent ciblant iOS 17 utilisera NavigationView et @ObservedObject. Un agent ciblant iOS 26 utilisera NavigationStack et @Observable. Le bundle ID compte pour les entitlements et la configuration HealthKit. La version de Swift détermine le modèle de concurrence (async/await ou gestionnaires de complétion, concurrence stricte ou souple).
2. Structure des fichiers avec annotations d’intention
## File Structure
```
Return/
├── ReturnApp.swift # App entry, dark mode enforcement
├── ContentView.swift # Main timer view with theme backgrounds
├── TimerManager.swift # Timer state, logic, and repeat handling
├── AudioManager.swift # Sound playback with AVAudioPlayer
├── Settings.swift # Centralized settings with validation
├── SettingsSheet.swift # Settings UI
├── HealthKitManager.swift # Mindful session logging + cross-device sync
├── LiveActivityManager.swift # Lock Screen/Dynamic Island
├── Theme.swift # Theme definitions
├── ThemeManager.swift # Theme state management
├── VideoBackgroundView.swift # AVPlayer video backgrounds
├── GlassTextShape.swift # Core Text glyph paths for glass effect
├── GlassTimerText.swift # Timer text with glass material
└── Constants.swift # App constants
```
Les commentaires en ligne après chaque nom de fichier ne sont pas décoratifs. Ce sont la documentation au meilleur levier que vous puissiez écrire. Quand l’agent décide où ajouter une nouvelle fonctionnalité, ces annotations le guident vers le bon fichier dès la première tentative, au lieu de lui faire lire tous les fichiers pour comprendre l’organisation du projet.
Anti-modèle : lister les fichiers sans annotations. TimerManager.swift n’indique pas à l’agent s’il gère l’état, l’UI, ou les deux. TimerManager.swift # Timer state, logic, and repeat handling lui dit exactement ce qui doit s’y trouver et ce qui n’y a pas sa place.
3. Commandes de build et de test
## Build & Test
Build for iOS simulator:
```bash
xcodebuild -scheme Return -destination 'platform=iOS Simulator,name=iPhone 16 Pro' build
```
Run tests:
```bash
xcodebuild -scheme Return -destination 'platform=iOS Simulator,name=iPhone 16 Pro' test
```
Run tvOS tests:
```bash
xcodebuild -scheme ReturnTV -destination 'platform=tvOS Simulator,name=Apple TV' test
```
**Prefer MCP tools** (`build_sim`, `test_sim`) over these raw commands.
MCP returns structured JSON with categorized errors.
Incluez les commandes brutes même si l’agent devrait préférer MCP. Elles servent de documentation de repli et rendent explicites les noms de schemes et les destinations.
4. Modèles et règles clés
## Key Patterns
### Observable Architecture
- ALL view models use `@Observable` (NEVER `ObservableObject`)
- ALL navigation uses `NavigationStack` (NEVER `NavigationView`)
- State management via `@Observable` classes with `@MainActor` isolation
### Settings Pattern
- Centralized `Settings.shared` singleton
- All settings bounded to valid ranges with validation
- Sound names validated against whitelist
- Thread-safe access via @MainActor
### Audio System
- `AVAudioPlayer` with `.playback` category (plays in silent mode)
- Silent audio loop for background execution
- Bell playback with completion callbacks and token-based staleness
Ces modèles empêchent l’agent d’introduire des incohérences. Sans documentation explicite des modèles, l’agent utilisera parfois ObservableObject dans un fichier et @Observable dans un autre, ou créera un nouveau mécanisme de paramètres au lieu d’utiliser le singleton Settings.shared existant.
5. Ce que l’agent ne doit jamais faire
## Rules
- **NEVER modify .pbxproj files** — create Swift files, then I will add them to Xcode manually
- **NEVER modify .xcodeproj/ contents directly**
- **NEVER add new package dependencies** without asking first
- **NEVER change the deployment target**
- **NEVER modify entitlements files** unless explicitly asked
- **NEVER use NavigationView** — always NavigationStack
- **NEVER use ObservableObject** — always @Observable
- **NEVER use @StateObject** — always @State with @Observable
Les interdictions explicites sont plus efficaces que les attentes implicites. L’agent suit plus fiablement les contraintes négatives que les suggestions positives, car elles sont binaires (faire / ne pas faire) plutôt qu’heuristiques (préférer ceci / utiliser parfois cela).
6. Contexte propre aux frameworks
Cette section varie selon l’app. Ajoutez-la pour tout framework dont la configuration n’est pas évidente :
Pour les apps HealthKit :
## HealthKit Configuration
- Entitlement: `com.apple.developer.healthkit`
- Info.plist keys:
- `NSHealthShareUsageDescription`: "Return reads your mindful minutes..."
- `NSHealthUpdateUsageDescription`: "Return logs meditation sessions..."
- Category types: `HKCategoryType(.mindfulSession)`
- Authorization checked on every write (user can revoke at any time)
- HealthKit is unavailable on tvOS — guard with `#if canImport(HealthKit)`
Pour les apps SwiftData :
## SwiftData Models
### Model Relationships
- `GroceryList` has many `GroceryItem` (cascade delete)
- `GroceryItem` belongs to one `GroceryList`
- `GroceryItem` has optional `Category`
### Model Container Setup
- Configured in App struct with `modelContainer(for:)`
- Schema versioning: currently V2
- Migration plan: `GroceryMigrationPlan` handles V1 → V2
### Queries
- `@Query(sort: \GroceryItem.name)` for sorted fetches
- `@Query(filter: #Predicate { !$0.isCompleted })` for active items
- Always use `@Query` in views, `modelContext.fetch()` in managers
Pour les apps SpriteKit :
## SpriteKit Scene Hierarchy
```
GameScene (SKScene)
├── backgroundLayer (SKNode, zPosition: -100)
│ └── StarfieldNode (custom, parallax scrolling)
├── gameLayer (SKNode, zPosition: 0)
│ ├── playerShip (PlayerNode, zPosition: 10)
│ ├── enemyContainer (SKNode, zPosition: 5)
│ └── bulletPool (SKNode, zPosition: 8)
├── effectsLayer (SKNode, zPosition: 50)
│ └── ParticleManager (manages explosion/trail emitters)
└── hudLayer (SKNode, zPosition: 100)
├── scoreLabel (SKLabelNode)
└── healthBar (HealthBarNode)
```
- Physics categories defined in `PhysicsCategory.swift` as bitmasks
- Contact detection via `didBegin(_ contact:)` on GameScene
- Bullet pooling: pre-allocate 50, recycle via `removeFromParent()` + re-add
Pour les apps Metal :
## Metal Pipeline
- Render pipeline: `MetalView` → `Renderer` → `ShaderLibrary`
- Compute pipeline: `AudioAnalyzer` → compute shader → texture output
- Shared uniforms struct: `Uniforms` in `ShaderTypes.h` (bridged to Swift)
- Frame timing: `CADisplayLink` drives render loop
- Buffer triple-buffering: 3 in-flight frames with semaphore
### Shader Files
- `Shaders.metal` — Main render shaders (vertex + fragment)
- `Compute.metal` — Audio analysis compute kernel
- `PostProcess.metal` — Bloom and color grading
### DO NOT modify Metal shaders without testing on device.
Simulator Metal is not representative of device GPU behavior.
CLAUDE.md réel : Banana List (SwiftUI + SwiftData + iCloud + serveur MCP)
Voici un exemple annoté montrant comment les six sections fonctionnent ensemble pour une app de complexité moyenne. C’est le modèle CLAUDE.md que j’utilise pour Banana List, une app de liste de courses de 53 fichiers avec synchronisation iCloud et serveur MCP personnalisé qui expose les données de l’app à Claude Desktop :
# Banana List - Grocery List App
**Bundle ID:** `com.941apps.BananaList`
**Target:** iOS 26+
**Architecture:** SwiftUI + SwiftData + iCloud Drive sync
**Swift version:** 6.2
**Minimum deployment:** iOS 26.0
## Core Features
- Grocery lists with items, categories, and quantities
- iCloud Drive sync via SwiftData CloudKit integration
- Custom MCP server exposing list data to Claude Desktop
- Liquid Glass design system
- Haptic feedback on interactions
- Share sheets for list sharing
## File Structure
```
BananaList/
├── BananaListApp.swift # App entry, model container setup
├── Models/
│ ├── GroceryList.swift # @Model: list with name, items, color
│ ├── GroceryItem.swift # @Model: item with name, quantity, category, isCompleted
│ ├── Category.swift # @Model: user-defined categories
│ └── SampleData.swift # Preview and test data
├── Views/
│ ├── ListsView.swift # Main list of grocery lists
│ ├── ListDetailView.swift # Items within a list
│ ├── ItemRow.swift # Single item row with swipe actions
│ ├── AddItemSheet.swift # New item form
│ ├── CategoryPicker.swift # Category selection with create-new
│ └── SettingsView.swift # App settings
├── Managers/
│ ├── CloudSyncManager.swift # iCloud Drive sync status and conflict resolution
│ └── HapticManager.swift # UIImpactFeedbackGenerator wrapper
├── MCP/
│ ├── MCPServer.swift # MCP server for Claude Desktop integration
│ ├── ListTools.swift # MCP tools: list CRUD operations
│ └── ItemTools.swift # MCP tools: item CRUD operations
└── Extensions/
├── Color+Extensions.swift # Custom color definitions
└── View+Extensions.swift # Reusable view modifiers
```
## SwiftData Models
### Relationships
- `GroceryList` has many `GroceryItem` (cascade delete)
- `GroceryItem` belongs to one `GroceryList` (required)
- `GroceryItem` has optional `Category`
- `Category` has many `GroceryItem` (nullify on delete)
### Container Setup
```swift
@main
struct BananaListApp: App {
var body: some Scene {
WindowGroup {
ListsView()
}
.modelContainer(for: [GroceryList.self, GroceryItem.self, Category.self])
}
}
```
### Query Patterns
- Lists: `@Query(sort: \GroceryList.name) var lists: [GroceryList]`
- Active items: `@Query(filter: #Predicate { !$0.isCompleted })`
- By category: filter in-memory after fetch (SwiftData predicate limitations)
## Build & Test
```bash
xcodebuild -scheme BananaList -destination 'platform=iOS Simulator,name=iPhone 16 Pro' build
xcodebuild -scheme BananaList -destination 'platform=iOS Simulator,name=iPhone 16 Pro' test
```
Prefer MCP tools (`build_sim`, `test_sim`) over raw commands.
## Key Patterns
### Observable + SwiftData
- SwiftData `@Model` classes are automatically Observable
- DO NOT add `@Observable` to `@Model` classes (redundant, causes warnings)
- Use `@Bindable` for two-way bindings to model properties in forms
- Use `@Query` in views, `modelContext.fetch()` in non-view code
### iCloud Sync
- Automatic via SwiftData CloudKit integration
- Conflict resolution: last-write-wins (CloudKit default)
- Sync status exposed via `CloudSyncManager.shared.syncState`
- Test sync by running on two simulators with same iCloud account
### MCP Server Architecture
- Runs as a local WebSocket server on port 8765
- Exposes 6 tools: listAll, getList, createList, addItem, completeItem, deleteItem
- Claude Desktop connects via MCP config in `~/.config/claude-desktop/config.json`
## Rules
- NEVER modify .pbxproj or .xcodeproj contents
- NEVER change the model schema without updating SampleData.swift
- NEVER use `ObservableObject` — SwiftData models are already Observable
- NEVER use `@StateObject` — use `@State` with `@Observable` classes
- NEVER use `NavigationView` — always `NavigationStack`
- NEVER add `@Observable` macro to `@Model` classes
- ALWAYS use `@Bindable` for form bindings to model properties
- ALWAYS test iCloud sync changes on two simulator instances
CLAUDE.md réel : Reps (app SwiftData minimale — 14 fichiers)
Pour les petits projets, le CLAUDE.md peut être concis. Voici le modèle pour Reps, un suivi d’entraînement de 14 fichiers. Remarquez que même un CLAUDE.md court couvre les six sections essentielles :
# Reps - Workout Tracking
**Bundle ID:** `com.941apps.Reps`
**Target:** iOS 26+
**Architecture:** SwiftUI + SwiftData
**Swift version:** 6.2
## File Structure
```
Reps/
├── RepsApp.swift # App entry, model container
├── Models/
│ ├── Workout.swift # @Model: workout with exercises, date, duration
│ ├── Exercise.swift # @Model: exercise with sets, reps, weight
│ └── ExerciseTemplate.swift # @Model: saved exercise definitions
├── Views/
│ ├── WorkoutListView.swift # Main list of workouts
│ ├── WorkoutDetailView.swift # Exercises within a workout
│ ├── ExerciseRow.swift # Single exercise with inline editing
│ ├── AddExerciseSheet.swift # Exercise selection from templates
│ ├── NewWorkoutView.swift # Start new workout flow
│ └── StatsView.swift # Progress charts and summaries
├── Managers/
│ └── WorkoutTimer.swift # Active workout timer
└── Extensions/
└── Date+Extensions.swift # Formatting helpers
```
## Build & Test
```bash
xcodebuild -scheme Reps -destination 'platform=iOS Simulator,name=iPhone 16 Pro' build
xcodebuild -scheme Reps -destination 'platform=iOS Simulator,name=iPhone 16 Pro' test
```
## SwiftData Relationships
- `Workout` has many `Exercise` (cascade delete)
- `Exercise` has optional `ExerciseTemplate`
- `ExerciseTemplate` standalone (nullify on exercise delete)
## Rules
- NEVER modify .pbxproj
- NEVER use ObservableObject — use @Observable
- NEVER use NavigationView — use NavigationStack
- @Model classes are already Observable — do not add @Observable macro
- Use @Bindable for form bindings to model properties
Cela fait 40 lignes de CLAUDE.md pour un projet de 14 fichiers. Il faut 10 minutes pour l’écrire, et cela économise des heures de confusion pour l’agent.
CLAUDE.md réel : Starfield Destroyer (SpriteKit + Metal — 32 fichiers)
Les projets de jeu exigent davantage de contexte propre aux frameworks. L’agent doit comprendre le graphe de scène, les catégories physiques et la machine à états du jeu :
# Starfield Destroyer - Space Shooter
**Bundle ID:** `com.941apps.StarfieldDestroyer`
**Target:** iOS 26+
**Architecture:** SpriteKit + Metal post-processing + Game Center
**Swift version:** 6.2
## Game Overview
99 levels across 3 galaxies. 8 unlockable ships with different stats.
Game Center leaderboards and achievements. Metal shader post-processing
for bloom and screen effects.
## File Structure
```
StarfieldDestroyer/
├── StarfieldDestroyerApp.swift # App entry, Game Center auth
├── GameScene.swift # Main game scene, update loop
├── MenuScene.swift # Title screen, ship selection
├── Entities/
│ ├── PlayerShip.swift # Player node with physics, weapons, shields
│ ├── EnemyShip.swift # Enemy base class with AI behaviors
│ ├── Bullet.swift # Bullet pool node
│ ├── PowerUp.swift # Collectible power-ups
│ └── Boss.swift # Boss enemies (levels 33, 66, 99)
├── Systems/
│ ├── LevelManager.swift # Level progression, wave spawning
│ ├── PhysicsCategory.swift # UInt32 bitmask categories
│ ├── CollisionHandler.swift # Contact delegate methods
│ ├── ScoreManager.swift # Score tracking, multipliers
│ ├── ParticleManager.swift # Explosion, trail, shield emitters
│ └── AudioManager.swift # Sound effects, background music
├── UI/
│ ├── HUDNode.swift # Score, health, level display
│ ├── ShipSelectView.swift # SwiftUI ship selection (UIHostingController)
│ ├── GameOverView.swift # Game over screen with score submission
│ └── PauseMenu.swift # Pause overlay
├── Metal/
│ ├── MetalRenderer.swift # Post-processing render pipeline
│ ├── BloomShader.metal # Bloom post-process effect
│ └── ShaderTypes.h # Shared uniforms (bridging header)
├── Data/
│ ├── ShipData.swift # 8 ship definitions (speed, damage, shields)
│ ├── LevelData.swift # 99 level configurations
│ └── AchievementData.swift # Game Center achievement definitions
└── GameCenterManager.swift # Leaderboard/achievement submission
```
## SpriteKit Scene Hierarchy
```
GameScene (SKScene)
├── backgroundLayer (zPosition: -100)
│ └── StarfieldNode (parallax scrolling, 3 layers)
├── gameLayer (zPosition: 0)
│ ├── playerShip (zPosition: 10)
│ ├── enemyContainer (zPosition: 5)
│ ├── bulletPool (zPosition: 8) — pre-allocated 50 bullets
│ └── powerUpContainer (zPosition: 3)
├── effectsLayer (zPosition: 50)
│ └── ParticleManager (explosion + trail emitters)
└── hudLayer (zPosition: 100)
├── scoreLabel (SKLabelNode)
├── healthBar (custom SKShapeNode)
└── levelLabel (SKLabelNode)
```
## Physics Categories
```swift
struct PhysicsCategory {
static let none: UInt32 = 0
static let player: UInt32 = 0b1 // 1
static let enemy: UInt32 = 0b10 // 2
static let bullet: UInt32 = 0b100 // 4
static let powerUp: UInt32 = 0b1000 // 8
static let shield: UInt32 = 0b10000 // 16
static let bossBullet:UInt32 = 0b100000 // 32
}
// Contact pairs:
// player + enemy → damage
// player + powerUp → collect
// bullet + enemy → destroy
// player + bossBullet → damage
```
## Game State Machine
```
.menu → .playing → .paused → .playing
→ .gameOver → .menu
→ .bossIntro → .playing
→ .levelComplete → .playing (next level)
```
## Metal Post-Processing
- Bloom shader: `BloomShader.metal` — multi-pass Gaussian blur + additive blend
- Uniforms: `PostProcessUniforms { float intensity; float threshold; float2 resolution; }`
- Applied after SpriteKit renders each frame via `SKView.presentScene(:transition:)`
- DO NOT modify Metal shaders without testing on device
## Build & Test
```bash
xcodebuild -scheme StarfieldDestroyer -destination 'platform=iOS Simulator,name=iPhone 16 Pro' build
xcodebuild -scheme StarfieldDestroyer -destination 'platform=iOS Simulator,name=iPhone 16 Pro' test
```
## Rules
- NEVER modify .pbxproj
- NEVER modify PhysicsCategory bitmasks (breaks all collision detection)
- NEVER change the scene hierarchy z-ordering without understanding render order
- NEVER modify ShaderTypes.h without updating both Swift and Metal references
- Add new enemies by subclassing EnemyShip, not by modifying it
- Bullet pooling: recycle via removeFromParent() + re-add, never allocate new
- Game Center: always check isAuthenticated before submitting scores
CLAUDE.md réel : amp97 (Metal + visualisation audio — 41 fichiers)
Les projets Metal exigent le plus de contexte propre aux frameworks, car les agents ne peuvent pas vérifier le rendu visuel :
# amp97 - Audio Visualizer
**Bundle ID:** `com.941apps.amp97`
**Target:** iOS 26+
**Architecture:** Metal render pipeline + AVAudioEngine analysis
**Swift version:** 6.2
## Architecture
```
Audio Input (microphone/file)
→ AVAudioEngine tap
→ FFT (vDSP)
→ Frequency/amplitude buffers
→ Metal compute shader (analysis)
→ Metal render pipeline (visualization)
→ CADisplayLink (60fps)
→ MTKView
```
## File Structure
```
amp97/
├── amp97App.swift # App entry
├── Audio/
│ ├── AudioEngine.swift # AVAudioEngine setup, tap installation
│ ├── FFTProcessor.swift # vDSP FFT, frequency bin extraction
│ ├── AudioBuffer.swift # Ring buffer for audio data
│ └── MicrophoneManager.swift # Microphone permission, session config
├── Rendering/
│ ├── MetalView.swift # MTKView wrapper for SwiftUI
│ ├── Renderer.swift # Main render loop, pipeline state
│ ├── ShaderLibrary.swift # Compiled shader management
│ ├── BufferManager.swift # Triple-buffered uniform updates
│ └── TextureManager.swift # Offscreen render targets
├── Shaders/
│ ├── Shaders.metal # Vertex + fragment shaders
│ ├── AudioCompute.metal # Audio analysis compute kernel
│ ├── PostProcess.metal # Bloom, color grading
│ └── ShaderTypes.h # Shared uniforms (bridging header)
├── Visualizations/
│ ├── WaveformViz.swift # Oscilloscope-style waveform
│ ├── SpectrumViz.swift # Frequency spectrum bars
│ ├── CircularViz.swift # Radial visualization
│ └── VizSelector.swift # Visualization switching
├── Views/
│ ├── MainView.swift # Full-screen viz with overlays
│ ├── ControlsOverlay.swift # Play/pause, viz selection, gain
│ └── SettingsView.swift # Audio source, sensitivity
└── Extensions/
├── SIMD+Extensions.swift # Vector math helpers
└── Color+Metal.swift # UIColor → float4 conversion
```
## Metal Pipeline
### Uniforms (ShaderTypes.h)
```c
typedef struct {
float time;
float2 resolution;
float audioLevel; // 0.0-1.0 RMS amplitude
float frequencyBins[64]; // FFT output, normalized
float4x4 transform;
} Uniforms;
```
### Render Pipeline
1. Compute pass: AudioCompute.metal processes FFT data → texture
2. Render pass: Shaders.metal reads texture + uniforms → visualization
3. Post-process pass: PostProcess.metal applies bloom → final output
### Buffer Management
- Triple buffering with DispatchSemaphore(value: 3)
- Uniforms updated per-frame on CPU, consumed by GPU 1-2 frames later
- Audio data ring buffer: 4096 samples, lock-free single producer/consumer
## Rules
- NEVER modify ShaderTypes.h without updating BOTH Swift and Metal sides
- NEVER exceed 64 frequency bins (fixed buffer size in shader)
- NEVER test Metal visual output in simulator — device only
- NEVER modify the audio engine tap format (48kHz, mono, float32)
- Triple buffer discipline: always signal semaphore in completion handler
- Audio session: .playAndRecord category with .defaultToSpeaker option
Adapter CLAUDE.md à la taille du projet
Le bon niveau de détail dépend du nombre de fichiers et de la complexité des frameworks :
| Taille du projet | Profondeur de CLAUDE.md | Exemple |
|---|---|---|
| Petit (< 20 fichiers) | Identité + liste des fichiers + règles | Reps (14 fichiers) : modèles SwiftData de base, commandes de build, interdictions |
| Moyen (20-40 fichiers) | + Contexte framework + modèles clés | TappyColor (30 fichiers) : hiérarchie de scène SpriteKit, catégories physiques, boucle de jeu |
| Grand (40+ fichiers) | + Diagrammes d’architecture + cartes de relations + informations multi-cibles | Return (63 fichiers) : architecture multiplateforme, diagramme de synchronisation des sessions, différences par plateforme |
| Spécialisé (Metal/GPU) | + Diagrammes de pipeline + définitions de types partagés + dispositions des buffers | amp97 (41 fichiers) : étapes du pipeline de rendu, struct uniforme, gestion des buffers |
Le coût d’une documentation trop détaillée est presque nul (l’agent ignore ce dont il n’a pas besoin). Le coût d’une documentation insuffisante est élevé (l’agent invente des modèles qui entrent en conflit avec votre codebase).
Checklist CLAUDE.md
Utilisez cette checklist lors de la création ou de l’audit d’un CLAUDE.md pour un projet iOS :
- [ ] Bundle ID et cible de déploiement spécifiés
- [ ] Version de Swift et modèle d’architecture nommés
- [ ] Structure des fichiers avec annotations d’intention en ligne
- [ ] Commande de build avec le bon scheme et la bonne destination
- [ ] Commande de test avec le bon scheme et la bonne destination
- [ ] Préférence MCP indiquée (« préférer build_sim à xcodebuild »)
- [ ] Règle @Observable (jamais ObservableObject)
- [ ] Règle NavigationStack (jamais NavigationView)
- [ ] Interdiction .pbxproj
- [ ] Contexte propre aux frameworks (permissions HealthKit, relations SwiftData, hiérarchie SpriteKit, pipeline Metal)
- [ ] Gardes de disponibilité des plateformes documentées (#if canImport, #if os)
- [ ] Singletons clés et modèles partagés documentés
- [ ] Limitations ou pièges connus signalés
Votre première session d’agent
Avec MCP configuré et un CLAUDE.md dans votre projet, voici le déroulé d’une première session efficace. Cet exemple utilise Claude Code CLI, mais le workflow s’applique à n’importe quel runtime.
Étape 1 : vérifier que l’agent voit votre projet
You: Summarize this project. What scheme should I build with?
Claude: [reads CLAUDE.md]
[calls discover_projs via MCP]
[calls list_schemes via MCP]
This is Return, a zen meditation timer for iOS 26+, watchOS, and tvOS.
Available schemes: Return, ReturnWatch, ReturnTV, ReturnTests.
Primary scheme for iOS: Return.
Si l’agent ne fait pas référence au contenu de votre CLAUDE.md, vérifiez que le fichier se trouve à la racine du projet (dans le même dossier que .xcodeproj ou Package.swift).
Étape 2 : lancer un build de contrôle
You: Build the Return scheme for iOS simulator and report results.
Claude: [calls list_sims — finds iPhone 16 Pro on iOS 26.2]
[calls boot_sim — boots the simulator]
[calls build_sim — builds the project]
Build succeeded. 63 source files compiled.
2 warnings:
- HomeView.swift:132 — UIScreen.main deprecated in iOS 26.0
- LogWaterIntent.swift:61 — Result of try? is unused
0 errors.
Étape 3 : lancer les tests
You: Run all tests and report pass/fail.
Claude: [calls test_sim]
12 tests executed:
✓ TimerManagerTests (5/5 passed)
✓ SettingsTests (4/4 passed)
✓ ConstantsTests (3/3 passed)
All tests passed.
Étape 4 : implémenter une fonctionnalité
You: Add a new "Rain" theme to the theme system. Follow the existing
pattern in Theme.swift and ThemeManager.swift. Include a rain
ambient sound. Build and test after implementation.
Claude: [reads Theme.swift — understands Theme struct pattern]
[reads ThemeManager.swift — understands theme registration]
[reads existing theme definitions]
[adds Rain theme to Theme.swift following existing pattern]
[registers Rain theme in ThemeManager.swift]
[calls build_sim — build succeeds]
[calls test_sim — all tests pass]
Added Rain theme:
- Theme.swift: new `static let rain` with video, cover, ambient
- ThemeManager.swift: added to `allThemes` array
- Build: success (0 errors, 2 existing warnings)
- Tests: 12/12 passed
Note: You'll need to add rain_ambient.wav to the project
and add the new Theme.swift changes to the Xcode target manually
(I did not modify .pbxproj).
La remarque de l’agent indiquant qu’il ne doit pas modifier .pbxproj vient des règles définies dans CLAUDE.md. Sans cette règle, l’agent essaierait de modifier le fichier de projet et risquerait fort de le corrompre.
Ce que les agents font bien dans iOS
Voici les tâches pour lesquelles les agents produisent régulièrement un résultat correct et prêt pour la production, avec un minimum de revue humaine.
Vues et modifiers SwiftUI
Les agents reconnaissent très bien les patterns de la syntaxe déclarative SwiftUI. Composition de vues, chaînes de modifiers, liaisons d’état et mise en page : ces éléments correspondent bien aux données d’entraînement de l’agent, car la surface API de SwiftUI est bien documentée et les patterns sont très cohérents.
Domaines où les agents excellent :
- Créer de nouvelles vues à partir d’une description (« créez une feuille de paramètres avec des toggles pour X, Y, Z »)
- Appliquer des chaînes de modifiers (.glassEffect(), .sensoryFeedback(), .navigationTitle())
- Convertir des patterns de mise en page (VStack vers LazyVGrid, List vers ScrollView)
- Implémenter des liaisons de formulaire @Bindable vers des modèles SwiftData
- Créer des preview providers avec des données d’exemple
Exemple de prompt qui produit d’excellents résultats :
Create a SettingsView that matches the existing pattern in SettingsSheet.swift.
Include toggles for:
- Enable haptic feedback (Settings.shared.hapticsEnabled)
- Enable HealthKit logging (Settings.shared.healthKitEnabled)
- Show session history (navigation link to SessionHistoryView)
Use Liquid Glass styling with .glassEffect() on section backgrounds.
Follow the @Observable pattern, not ObservableObject.
La précision compte. « Créez une vue de paramètres » produit un résultat générique. « Créez une SettingsView qui suit le pattern existant dans SettingsSheet.swift » produit un résultat cohérent avec votre codebase.
Modèles et queries SwiftData
Les agents gèrent de manière fiable la macro @Model de SwiftData, les relations et les patterns @Query. La nature déclarative du framework (similaire à Django ORM ou SQLAlchemy) correspond bien aux patterns que l’agent a vus dans de nombreux codebases.
Domaines où les agents excellent :
- Définir des classes @Model avec des relations
- Écrire des @Query avec des sort descriptors et des predicates
- Implémenter des opérations CRUD via modelContext
- Préparer des plans de migration entre versions de schéma
- Créer des données de preview et des fixtures de test
Domaines où les agents ont besoin d’indications :
- Expressions #Predicate complexes (le DSL de predicate de SwiftData a des limites que l’agent ne connaît pas toujours ; documentez les limites connues dans CLAUDE.md)
- Configuration de la synchronisation CloudKit (automatique via SwiftData, mais l’agent peut essayer d’implémenter une synchronisation manuelle)
Tests unitaires
Les tests unitaires écrits par les agents sont régulièrement de grande qualité pour les projets iOS. L’agent comprend les patterns XCTest, les méthodes de test async et le cycle de vie setup/teardown.
Write unit tests for TimerManager covering:
1. Initial state is .stopped
2. start() transitions to .running
3. pause() transitions to .paused
4. reset() returns to .stopped with original duration
5. Timer counts down correctly (test with 3-second duration)
L’agent produit des cas XCTest bien structurés avec setUp() et tearDown(), des assertions appropriées et une gestion async pour les tests basés sur des timers.
Refactoring et application de patterns
Les agents excellent dans le refactoring mécanique : extraction de vues en composants, conversion de ObservableObject vers @Observable, migration de NavigationView vers NavigationStack et application de patterns cohérents dans plusieurs fichiers.
Refactor all views in the Views/ directory to use @Observable instead of
ObservableObject. Update @StateObject to @State, @ObservedObject to direct
property access, and @Published to plain properties.
L’agent avance méthodiquement fichier par fichier, applique correctement la transformation et conserve les fonctionnalités existantes. C’est un travail à fort levier : un refactoring qui prendrait une heure d’édition manuelle se termine en quelques minutes avec une précision presque parfaite.
Diagnostic des erreurs de build via MCP
Avec une sortie MCP structurée, les agents diagnostiquent les erreurs de build plus vite que la plupart des développeurs. L’agent lit la JSON d’erreur, identifie le fichier et la ligne exacts, comprend le message d’erreur et applique le correctif, souvent en un seul tour.
Erreurs que les agents corrigent de manière autonome : - Imports manquants - Incompatibilités de types - Lacunes de conformance à des protocoles - Utilisation obsolète de API (avec remplacement) - Paramètres d’initializer requis manquants - Violations du contrôle d’accès
Erreurs pour lesquelles les agents ont besoin d’aide : - Résolution de type ambiguë (plusieurs modules définissent le même type) - Échecs complexes de contraintes génériques - Erreurs d’expansion de macros (l’agent ne peut pas voir la sortie des macros expansées)
Gestion du simulator
Les agents gèrent bien le cycle de vie du simulator via MCP :
Boot an iPhone 16 Pro simulator on iOS 26, install the app, and take a screenshot.
L’agent appelle list_sims pour trouver les runtimes disponibles, boot_sim pour démarrer le simulator, build_sim pour builder et installer, puis screenshot pour capturer l’écran, le tout via des appels MCP structurés.
Ce que les agents font mal dans iOS
Bilan honnête des situations où les agents échouent. Connaître ces limites évite frustration et tokens gaspillés.
Modifications du fichier .pbxproj — JAMAIS
C’est la règle la plus importante dans le développement iOS avec des agents. Le fichier .pbxproj est la configuration de projet de Xcode : un fichier texte structuré avec des références UUID, des listes de phases de build et l’appartenance aux targets. Il est théoriquement lisible par un humain, mais pratiquement impossible à analyser correctement pour des agents IA.
Pourquoi les agents échouent avec .pbxproj : - Le fichier utilise un format personnalisé (ni JSON, ni YAML, ni XML) où la position a une importance - Chaque entrée est référencée par UUID : ajouter un fichier exige de mettre à jour 3 à 5 sections différentes de manière cohérente - Un seul caractère mal placé corrompt tout le fichier de projet - La résolution des conflits de fusion de Xcode pour .pbxproj est déjà fragile : les modifications par agent aggravent le problème
Ce qui se passe quand un agent modifie .pbxproj : 1. La modification semble réussir (l’agent indique « file updated ») 2. Xcode refuse d’ouvrir le projet (« The project file is corrupted ») 3. Vous passez 15 à 60 minutes à récupérer depuis l’historique git 4. Vous apprenez à ajouter le hook PreToolUse (voir Hooks)
Le workflow : L’agent crée les fichiers Swift. Vous les ajoutez manuellement au projet Xcode (glisser-déposer dans Xcode, ou File > Add Files). Cela prend 5 secondes par fichier et évite des heures de récupération.
Pour les projets Swift Package Manager : Cette limite est moins sévère. Package.swift est un fichier Swift standard que les agents peuvent modifier de manière fiable. Si votre projet utilise exclusivement SPM (sans .xcodeproj), l’agent peut gérer toute la structure du projet.
Modifications complexes d’Interface Builder / Storyboard
Si votre projet utilise Interface Builder (fichiers .xib) ou des Storyboards (fichiers .storyboard), les agents ne peuvent pas les modifier utilement. Ce sont des fichiers XML avec des UUID générés automatiquement, des références de contraintes et des connexions d’outlets conçus pour une édition visuelle, pas textuelle.
La mitigation : Utilisez exclusivement SwiftUI pour les nouvelles vues. Si votre projet contient d’anciens fichiers Interface Builder, laissez-les tels quels et construisez la nouvelle UI en SwiftUI.
Optimisation des performances
Les agents écrivent du code correct, mais pas nécessairement performant. Ils ne peuvent pas profiler votre app, identifier les goulots d’étranglement ni mesurer les fréquences d’images. L’optimisation des performances exige :
- Un profilage avec Instruments (outil visuel, inaccessible aux agents)
- Une compréhension des caractéristiques GPU/CPU de l’appareil précis
- Des modifications itératives pilotées par la mesure
Où cela apparaît : - Optimisation de shaders Metal (l’agent écrit du Metal valide, mais ne peut pas mesurer le temps de frame GPU) - Complexité du body des vues SwiftUI (l’agent crée des vues profondément imbriquées qui entraînent un surcoût de redessin) - Optimisation des fetchs Core Data / SwiftData (l’agent écrit des requêtes correctes qui peuvent être lentes sur de grands jeux de données)
La mitigation : Utilisez les agents pour l’implémentation, profilez manuellement avec Instruments, puis demandez à l’agent d’appliquer les optimisations spécifiques que vous avez identifiées.
Signature de code et provisioning
Les agents ne peuvent pas déboguer les problèmes de signature de code au-delà de la lecture du message d’erreur. La gestion des profils de provisioning, la création de certificats, la configuration des entitlements et la soumission à l’App Store sont fondamentalement des workflows opérés par des humains, qui passent par le portail Apple Developer, Keychain Access et l’interface de signature de Xcode.
Ce que l’agent voit : « Signing for ‘Return’ requires a development team. »
Ce que l’agent ne peut pas voir : Si votre certificat a expiré, si le profil de provisioning inclut l’appareil, si le bundle ID correspond à l’App ID, ou si votre fichier d’entitlements est correct.
La mitigation : Gérez toute la signature dans l’onglet Signing & Capabilities de Xcode. Ne demandez pas aux agents de déboguer les échecs de signature.
Débogage complexe de shaders Metal
Les agents écrivent du Metal Shading Language (MSL) syntaxiquement correct, mais ne peuvent pas vérifier le rendu visuel ni déboguer les problèmes côté GPU. Les shaders Metal s’exécutent sur le GPU : l’agent ne dispose d’aucun mécanisme de retour pour savoir si le shader produit des résultats visuels corrects.
Ce que les agents peuvent faire avec Metal :
- Écrire des shaders vertex et fragment à partir de descriptions
- Configurer le pipeline de rendu Metal en Swift
- Créer des compute shaders pour des opérations parallèles sur les données
- Corriger les erreurs de compilation dans les fichiers .metal
Ce que les agents ne peuvent pas faire avec Metal : - Vérifier la justesse visuelle de la sortie du shader - Déboguer les performances GPU (temps de frame, occupancy, bande passante mémoire) - Diagnostiquer les artefacts visuels (banding, problèmes de précision, espace colorimétrique incorrect) - Tester sur différentes architectures GPU (différences de comportement entre A-series et M-series)
La mitigation : Testez les shaders Metal sur des appareils physiques. L’implémentation Metal du Simulator n’est pas représentative du comportement GPU des appareils. Utilisez GPU Frame Capture de Xcode pour le débogage visuel.
Vérification visuelle de la mise en page
Les agents ne peuvent pas voir l’UI de votre app. Ils écrivent du code de layout SwiftUI et peuvent vérifier qu’il compile, mais ils ne peuvent pas déterminer si l’écran obtenu a l’apparence attendue. Une vue rendue 10 pixels trop à gauche, utilisant la mauvaise graisse de police ou contenant des éléments qui se chevauchent ne produit aucune erreur de build et passe tous les tests logiques.
La mitigation : Relisez visuellement les modifications d’UI. Utilisez SwiftUI Previews dans Xcode (ou RenderPreview via Apple MCP pour un rendu headless) afin de vérifier la mise en page. Envisagez des snapshot tests avec des bibliothèques comme swift-snapshot-testing pour détecter automatiquement les régressions visuelles.
Hooks pour le développement iOS
Les hooks sont des commandes shell qui s’exécutent de manière déterministe à des points précis du workflow de l’agent. Ils constituent le mécanisme d’application des règles : la différence entre « veuillez ne pas modifier .pbxproj » (une suggestion que l’agent peut ignorer) et « vous ne pouvez pas modifier .pbxproj » (un blocage strict).
Pour le contexte sur le système de hooks, consultez le guide des hooks Claude Code. Cette section couvre les patterns de hooks propres à iOS.
PreToolUse : bloquer les écritures .pbxproj
Le hook le plus important dans tout projet iOS. Il empêche l’agent d’écrire dans les fichiers .pbxproj, les dossiers .xcodeproj/ et les autres fichiers gérés par Xcode :
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"command": "bash -c 'INPUT=$(cat); FP=$(echo \"$INPUT\" | jq -r \".tool_input.file_path // empty\"); if echo \"$FP\" | grep -qE \"\\.(pbxproj|xcworkspace|xib|storyboard)$|xcodeproj/|xcworkspace/\"; then echo \"BLOCKED: Do not modify Xcode project files. Create Swift files and add to Xcode manually.\" >&2; exit 2; fi'"
}
]
}
}
Placez-le dans .claude/settings.json à la racine du projet ou dans ~/.claude/settings.json pour une protection globale.
Fonctionnement : lorsque l’agent tente d’utiliser l’outil Edit ou Write sur un fichier correspondant au pattern, le hook s’exécute, détecte le chemin du fichier, affiche un avertissement dans stderr, puis quitte avec le code 2 (ce qui bloque l’utilisation de l’outil). L’agent reçoit le message d’erreur et adapte son approche.
Ce qu’il intercepte :
- Les modifications directes de .pbxproj
- Tout fichier situé dans les dossiers .xcodeproj/ ou .xcworkspace/
- Les fichiers Interface Builder (.xib, .storyboard)
PostToolUse : formatage à l’enregistrement avec SwiftFormat
Formatez automatiquement les fichiers Swift chaque fois que l’agent les écrit ou les modifie :
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"command": "bash -c 'INPUT=$(cat); FP=$(echo \"$INPUT\" | jq -r \".tool_input.file_path // empty\"); if echo \"$FP\" | grep -qE \"\\.swift$\"; then swiftformat \"$FP\" --quiet 2>/dev/null; fi'"
}
]
}
}
Prérequis : SwiftFormat doit être installé (brew install swiftformat).
Pourquoi c’est important : les agents produisent du Swift syntaxiquement correct, mais ne respectent pas systématiquement les conventions de formatage. SwiftFormat normalise l’indentation, le placement des accolades et l’ordre des imports. Le hook de formatage à l’enregistrement garantit que chaque fichier Swift touché par l’agent est automatiquement formaté avant que vous le voyiez.
Facultatif : ajoutez un fichier de configuration .swiftformat à la racine de votre projet pour personnaliser les règles de formatage :
# .swiftformat
--indent 4
--allman false
--stripunusedargs closure-only
--importgrouping testable-bottom
--header strip
PostToolUse : exécuter SwiftLint automatiquement
Si vous utilisez SwiftLint, exécutez-le après chaque modification d’un fichier Swift :
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"command": "bash -c 'INPUT=$(cat); FP=$(echo \"$INPUT\" | jq -r \".tool_input.file_path // empty\"); if echo \"$FP\" | grep -qE \"\\.swift$\"; then swiftlint lint --path \"$FP\" --quiet 2>/dev/null || true; fi'"
}
]
}
}
Le || true empêche les avertissements de lint de bloquer l’agent. Si vous voulez que les violations de lint bloquent, supprimez-le.
PostToolUse : build automatique après les modifications
Pour des boucles de feedback agressives, déclenchez un build après chaque modification de fichier Swift :
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"command": "bash -c 'INPUT=$(cat); FP=$(echo \"$INPUT\" | jq -r \".tool_input.file_path // empty\"); if echo \"$FP\" | grep -qE \"\\.swift$\"; then xcodebuild -scheme Return -destination \"platform=iOS Simulator,name=iPhone 16 Pro\" build 2>&1 | tail -5; fi'"
}
]
}
}
Avertissement : c’est coûteux. Chaque modification de fichier déclenche un build. À utiliser avec parcimonie : c’est surtout utile pendant les sessions de débogage où vous voulez un feedback de build immédiat. Pour le développement normal, laissez l’agent déclencher les builds manuellement via MCP lorsqu’il est prêt.
PreToolUse : bloquer les modifications d’entitlements
Protégez votre fichier d’entitlements contre les modifications accidentelles de l’agent :
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"command": "bash -c 'INPUT=$(cat); FP=$(echo \"$INPUT\" | jq -r \".tool_input.file_path // empty\"); if echo \"$FP\" | grep -qE \"\\.entitlements$\"; then echo \"BLOCKED: Do not modify entitlements files without explicit permission.\" >&2; exit 2; fi'"
}
]
}
}
Configuration combinée de hooks iOS
Voici le .claude/settings.json complet que j’utilise sur tous les projets iOS :
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"command": "bash -c 'INPUT=$(cat); FP=$(echo \"$INPUT\" | jq -r \".tool_input.file_path // empty\"); if echo \"$FP\" | grep -qE \"\\.(pbxproj|xcworkspace|xib|storyboard|entitlements)$|xcodeproj/|xcworkspace/\"; then echo \"BLOCKED: Do not modify Xcode-managed files. Create Swift files and add manually.\" >&2; exit 2; fi'"
}
],
"PostToolUse": [
{
"matcher": "Edit|Write",
"command": "bash -c 'INPUT=$(cat); FP=$(echo \"$INPUT\" | jq -r \".tool_input.file_path // empty\"); if echo \"$FP\" | grep -qE \"\\.swift$\"; then swiftformat \"$FP\" --quiet 2>/dev/null; fi'"
}
]
}
}
Cela vous donne deux garanties : 1. L’agent ne peut pas corrompre les fichiers de projet Xcode (blocage PreToolUse) 2. Chaque fichier Swift touché par l’agent est formaté automatiquement (formatage PostToolUse)
Modèles d’architecture compatibles avec les agents
Toutes les architectures Swift ne se prêtent pas aussi bien au travail avec des agents. Ces modèles donnent les meilleurs résultats parce qu’ils sont explicites, cohérents et bien représentés dans les données d’entraînement.
@Observable (jamais ObservableObject)
Les cibles iOS 26+ doivent utiliser exclusivement @Observable. C’est à la fois le modèle moderne et le modèle le plus compatible avec les agents :
// CORRECT — @Observable
@Observable
@MainActor
final class TimerManager {
var timeRemaining: TimeInterval = 0
var state: TimerState = .stopped
func start() {
state = .running
// ...
}
}
// In a view:
struct TimerView: View {
@State private var timer = TimerManager()
var body: some View {
Text(timer.timeRemaining, format: .number)
}
}
// WRONG — ObservableObject (deprecated pattern)
class TimerManager: ObservableObject {
@Published var timeRemaining: TimeInterval = 0
@Published var state: TimerState = .stopped
}
// WRONG — @StateObject (deprecated pattern)
struct TimerView: View {
@StateObject private var timer = TimerManager()
}
Pourquoi @Observable est compatible avec les agents : le modèle est plus simple (aucune annotation @Published nécessaire), le modèle de propriété est plus clair (@State au lieu de @StateObject vs. @ObservedObject) et les agents produisent moins de bugs avec lui, car il comporte moins d’éléments mobiles.
Documentez-le dans CLAUDE.md : même avec iOS 26 comme cible, les agents reviennent parfois à des modèles ObservableObject issus de leurs données d’entraînement. Une interdiction explicite évite cela.
NavigationStack (jamais NavigationView)
// CORRECT
NavigationStack {
List(items) { item in
NavigationLink(value: item) {
ItemRow(item: item)
}
}
.navigationDestination(for: Item.self) { item in
ItemDetailView(item: item)
}
}
// WRONG
NavigationView {
List(items) { item in
NavigationLink(destination: ItemDetailView(item: item)) {
ItemRow(item: item)
}
}
}
NavigationStack est disponible depuis iOS 16+ et constitue le seul modèle de navigation à utiliser pour du nouveau code. Le modèle typé navigationDestination(for:) empêche l’agent de créer des liens de navigation incorrects.
SwiftData pour la persistance
Les modèles SwiftData constituent le modèle de persistance le plus clair pour le développement assisté par agents :
@Model
final class GroceryItem {
var name: String
var quantity: Int
var isCompleted: Bool
var category: Category?
var list: GroceryList?
init(name: String, quantity: Int = 1) {
self.name = name
self.quantity = quantity
self.isCompleted = false
}
}
Règles clés pour les agents travaillant avec SwiftData :
1. Les classes @Model sont automatiquement Observable — n’ajoutez pas @Observable
2. Utilisez @Bindable pour les liaisons de formulaire : @Bindable var item: GroceryItem
3. Utilisez @Query dans les vues pour les données réactives : @Query var items: [GroceryItem]
4. Utilisez modelContext.fetch() dans le code qui n’est pas lié aux vues
5. Les suppressions de relations nécessitent des règles explicites : .cascade, .nullify, .deny
Concurrence Swift 6.2
Ciblez la concurrence stricte de Swift 6.2 pour les nouveaux projets :
// Actor isolation for shared mutable state
@MainActor
@Observable
final class DataManager {
var items: [Item] = []
func loadItems() async throws {
let fetched = try await api.fetchItems()
items = fetched // Safe: @MainActor isolated
}
}
// Sendable conformance for cross-actor transfers
struct Item: Sendable, Identifiable {
let id: UUID
let name: String
let createdAt: Date
}
Consignes de concurrence pour les agents :
- Marquez tous les modèles de vue avec @MainActor (évite les avertissements de data race)
- Utilisez async/await pour tout le travail asynchrone (pas de completion handlers)
- Rendez les types valeur Sendable pour les transferts entre acteurs
- Utilisez Task { } dans les vues pour l’initialisation asynchrone
- Utilisez nonisolated uniquement lorsque vous avez mesuré un besoin de performance
Système de design Liquid Glass (iOS 26+)
iOS 26 a introduit le système de design Liquid Glass. Les agents le gèrent bien lorsqu’ils reçoivent des consignes explicites :
// Glass effect on containers
VStack {
// content
}
.glassEffect()
// Glass effect with tint
Button("Action") { }
.glassEffect(.regular.tint(.blue))
// Glass effect on navigation bars (automatic in iOS 26)
NavigationStack {
// content
}
// Navigation bar automatically uses glass material
// Custom glass shapes
RoundedRectangle(cornerRadius: 16)
.fill(.ultraThinMaterial)
.glassEffect()
À inclure dans CLAUDE.md : « Utilisez .glassEffect() sur les arrière-plans de section et les conteneurs de cartes. Les barres de navigation adoptent automatiquement le matériau glass dans iOS 26. Ne recréez pas manuellement les effets de verre avec des matériaux personnalisés : utilisez le modificateur système. »
Contexte propre à chaque framework
Chaque framework Apple a des considérations spécifiques aux agents. Cette section couvre les frameworks utilisés dans les 8 apps.
HealthKit
Apps qui l’utilisent : Return, Water
HealthKit exige une gestion prudente des permissions et des gardes de plateforme :
// Always check availability and authorization
import HealthKit
@MainActor
@Observable
final class HealthKitManager {
private let store = HKHealthStore()
var isAuthorized = false
func requestAuthorization() async {
guard HKHealthStore.isHealthDataAvailable() else { return }
let types: Set<HKSampleType> = [
HKQuantityType(.dietaryWater),
HKCategoryType(.mindfulSession)
]
do {
try await store.requestAuthorization(toShare: types, read: types)
isAuthorized = true
} catch {
// User denied — do not retry automatically
}
}
}
Règles pour les agents avec HealthKit :
- Protégez toujours avec HKHealthStore.isHealthDataAvailable()
- Ne supposez jamais que l’autorisation est acquise — vérifiez-la à chaque écriture
- Utilisez #if canImport(HealthKit) pour le code multiplateforme (HealthKit n’est pas disponible sur tvOS)
- Ne stockez jamais localement de données de santé au-delà de ce que fournit HealthKit
- Incluez NSHealthShareUsageDescription et NSHealthUpdateUsageDescription dans Info.plist
SpriteKit
Apps qui l’utilisent : TappyColor, Starfield Destroyer
Le modèle de graphe de scène de SpriteKit nécessite des consignes explicites pour les agents :
## SpriteKit Rules
- Scene hierarchy is a tree of SKNodes with zPosition ordering
- Physics bodies use category bitmasks (UInt32) for collision detection
- Node pooling: pre-allocate reusable nodes (bullets, particles)
- Never add nodes directly to the scene — use layer nodes for organization
- Update loop: `update(_ currentTime:)` runs every frame — keep it fast
- Actions: use SKAction sequences for animations, not manual property updates
- Textures: use texture atlases for performance (.atlas directories)
Points forts des agents avec SpriteKit : - Création de séquences et de groupes SKAction - Configuration de corps physiques et de la détection de contacts - Implémentation de machines à états de jeu - Construction de superpositions HUD
Faiblesses des agents avec SpriteKit : - Boucles de jeu sensibles aux performances (l’agent ajoute du travail inutile à chaque frame) - Simulations physiques complexes (une physique personnalisée surpasse SKPhysicsBody pour la précision) - Réglage des effets de particules (visuel, nécessite des itérations)
Metal
Apps qui l’utilisent : amp97, Water, Starfield Destroyer
Metal est le framework avec lequel les agents rencontrent le plus de difficultés. Le modèle de programmation GPU est fondamentalement différent du Swift côté CPU, et les agents ne peuvent pas vérifier le rendu visuel.
## Metal Rules
- Shared types between Swift and Metal go in a bridging header (ShaderTypes.h)
- Triple buffer in-flight frames (semaphore with value 3)
- Test shaders on DEVICE, not simulator (Metal behavior differs)
- Compute shaders: threadgroup size must divide evenly into grid size
- Fragment shaders: output color must be in correct color space (sRGB or linear)
- DO NOT optimize shaders without Instruments GPU profiling data
Ce qu’il faut inclure dans CLAUDE.md pour les projets Metal : - La définition de la struct Uniforms (partagée entre Swift et MSL) - Le modèle de configuration de l’état du render pipeline - Les indices de buffers et leur rôle - Les shaders existants et le rôle de chacun - Les problèmes de précision connus (half vs. float)
Live Activities
Apps qui l’utilisent : Return
Les Live Activities nécessitent une configuration spécifique que les agents gèrent bien une fois documentée :
## Live Activities
- ActivityAttributes defined in `TimerActivityAttributes.swift`
- ActivityKit framework: `import ActivityKit`
- Widget extension: `ReturnWidgets/ReturnLiveActivity.swift`
- Start: `Activity<TimerActivityAttributes>.request(attributes:content:)`
- Update: `activity.update(ActivityContent(state:staleDate:))`
- End: `activity.end(ActivityContent(state:staleDate:), dismissalPolicy:)`
- Push token: register for updates via `activity.pushTokenUpdates`
Game Center
Apps qui l’utilisent : Starfield Destroyer
## Game Center
- Authentication: `GKLocalPlayer.local.authenticateHandler`
- Leaderboards: `GKLeaderboard.submitScore(_:context:player:leaderboardIDs:completionHandler:)`
- Achievements: `GKAchievement.report(_:withCompletionHandler:)` (takes `[GKAchievement]` array)
- Always check `GKLocalPlayer.local.isAuthenticated` before submitting
- Handle authentication failure gracefully (offline play must work)
Patterns multi-plateformes
Return couvre iOS, watchOS et tvOS. Le développement multi-plateformes avec des agents exige une documentation explicite des frontières entre plateformes.
Organisation du code partagé
Shared/
├── MeditationSession.swift # Data model (all platforms)
├── SessionStore.swift # iCloud sync (all platforms)
└── SessionHistoryView.swift # UI (adapts per platform)
Return/ # iOS-specific
ReturnWatch Watch App/ # watchOS-specific
ReturnTV/ # tvOS-specific
Règle pour les agents : « Si un fichier se trouve dans Shared/, les changements affectent toutes les plateformes. Si un fichier se trouve dans un dossier de plateforme, les changements sont isolés. Vérifiez toujours dans quel dossier se trouve un fichier avant de le modifier. »
Gardes de disponibilité par plateforme
// HealthKit: available on iOS and watchOS, not tvOS
#if canImport(HealthKit)
import HealthKit
// HealthKit code here
#endif
// ActivityKit: available on iOS only
#if canImport(ActivityKit)
import ActivityKit
// Live Activity code here
#endif
// WatchKit: available on watchOS only
#if os(watchOS)
import WatchKit
// Watch-specific code here
#endif
Consigne pour l’agent : « Utilisez toujours des gardes #if canImport() ou #if os() lorsque vous utilisez des frameworks propres à une plateforme. Ne supposez pas qu’un framework est disponible sur toutes les cibles. »
Adaptation de l’interface par plateforme
struct SessionHistoryView: View {
@Query var sessions: [MeditationSession]
var body: some View {
List(sessions) { session in
SessionRow(session: session)
}
#if os(tvOS)
.focusable()
#endif
#if os(iOS)
.swipeActions {
Button("Delete", role: .destructive) {
// delete
}
}
#endif
}
}
Workflows avancés
Boucles autonomes compilation-test-correction
Le pattern le plus puissant : donnez à l’agent une spécification de fonctionnalité et laissez-le itérer de manière autonome à travers des cycles compilation-test-correction.
Implement a countdown timer that:
1. Starts from a user-selected duration (10, 20, or 30 minutes)
2. Shows remaining time with a circular progress indicator
3. Plays a bell sound on completion
4. Logs the session to HealthKit as mindful minutes
Build after each change. Fix all errors. Run tests when the build succeeds.
Continue until all tests pass and the build is clean.
L’agent écrit le code, compile via MCP, lit les erreurs structurées, les corrige, puis recommence. Une fonctionnalité qui nécessiterait 5 à 10 cycles humains compilation-erreur-correction se termine en une seule boucle autonome.
Quand cela fonctionne : fonctionnalités bien définies, avec des critères d’acceptation clairs.
Quand cela échoue : fonctionnalités ouvertes (« rendez ça plus joli »), code sensible aux performances ou tout élément nécessitant une vérification visuelle.
Délégation à des subagents pour iOS
Le système de subagents de Claude Code fonctionne pour les projets iOS :
Use a subagent to research the best approach for implementing
iCloud key-value store sync for meditation sessions across iOS,
watchOS, and tvOS. Report back with the recommended pattern.
Le subagent explore la documentation et les patterns de code dans une fenêtre de contexte séparée, renvoie un résumé, puis la session principale implémente la recommandation. Cela évite que la recherche consomme votre contexte principal.
Application de patterns entre apps
Lorsque vous maintenez plusieurs apps iOS avec des patterns cohérents, les agents peuvent appliquer des patterns d’une app à une autre :
Look at how Settings.swift works in the Return project
(centralized singleton with validation). Apply the same pattern
to create a Settings.swift for the Water project.
L’agent lit le pattern source, comprend la structure et crée une implémentation cohérente dans le projet cible.
Revue à deux agents (Claude + Codex)
Pour les changements critiques, utilisez deux agents issus de familles de modèles différentes :
- Claude Code écrit l’implémentation
- Codex CLI la relit dans une passe séparée
# After Claude implements the feature:
codex "Review the changes in the last commit. Focus on Swift 6.2
concurrency correctness, SwiftData relationship integrity,
and potential retain cycles. Report issues only — no praise."
Des familles de modèles différentes détectent des classes d’erreurs différentes. C’est particulièrement précieux pour les shaders Metal et les patterns de concurrence, où des bugs subtils sont faciles à introduire.
Ce que la double revue détecte et qu’une revue unique manque :
| Type de problème | Force de Claude | Force de Codex |
|---|---|---|
| Cycles de relations SwiftData | Moyenne | Forte (GPT-4o) |
| Lacunes d’isolation @MainActor | Forte | Moyenne |
| Alignement des buffers Metal | Moyenne | Moyenne |
| Détection des cycles de rétention | Forte (Opus) | Forte (o3) |
| Conscience des dépréciations API | Forte (données d’entraînement plus récentes) | Moyenne |
| Conditions de concurrence | Forte | Forte (patterns différents détectés) |
La double revue ne sert pas à trouver plus de bugs : elle sert à trouver des bugs différents. Chaque famille de modèles a ses propres modes d’échec dans sa reconnaissance des patterns.
Opérations par lot sur plusieurs apps
Lorsqu’un changement de framework ou de pattern affecte plusieurs apps :
# Update @Observable pattern across all projects
for project in BananaList Return Water Reps; do
cd ~/Projects/$project
claude -p "Audit all files for any remaining ObservableObject usage.
Convert to @Observable following the pattern in CLAUDE.md.
Build and test after changes." --dangerously-skip-permissions
done
À utiliser avec prudence. Le flag --dangerously-skip-permissions est requis pour le mode non interactif, mais il contourne toutes les vérifications de sécurité. Assurez-vous que vos hooks PreToolUse sont en place pour protéger les fichiers .pbxproj.
Apps qui utilisent LLM on-device d’Apple
Si votre app appelle le framework Foundation Models d’Apple (par exemple pour la synthèse hors ligne, la classification ou la génération de sortie structurée), les agents doivent connaître le budget de prompt. iOS 26.4 a ajouté deux APIs à SystemLanguageModel, qui remplacent l’ancienne estimation à 4096 tokens : contextSize (nombre maximal de tokens que le modèle accepte dans une seule conversation) et tokenCount(for:) (async throws, renvoie combien de tokens un prompt donné coûte réellement).17 Les deux sont @backDeployed(before: iOS 26.4), ils sont donc disponibles sur toutes les versions d’OS compatibles avec FM sans enchaînement #available.
Le pattern qu’un agent doit suivre lorsqu’il génère du code de construction de prompt :
import FoundationModels
func budgetFor(prompt: String, reservedReply: Int = 256) async throws -> Int {
let model = SystemLanguageModel.default
let promptCost = try await model.tokenCount(for: prompt)
let budget = model.contextSize - promptCost - reservedReply
guard budget > 0 else { throw ContextError.promptTooLong }
return budget
}
Ajoutez ce pattern à votre CLAUDE.md si l’app touche à SystemLanguageModel. Sans cela, les agents reviennent à l’ancien codage en dur à 4096 et tronquent silencieusement les prompts sur les appareils livrés avec des fenêtres de contexte plus grandes. La signature async throws de tokenCount(for:) est indispensable : les agents qui collent une version synchrone échoueront à la compilation.
Études de cas concrets
Les conseils abstraits sont faciles. Voici des scénarios précis tirés des 8 apps qui montrent comment le développement iOS assisté par agents fonctionne en pratique — échecs compris.
Étude de cas 1 : ajouter une app TV à Return (réussite)
La tâche : ajouter une cible tvOS à Return, un minuteur de méditation qui disposait déjà de versions iOS et watchOS. L’app TV devait prendre en charge la navigation avec Siri Remote, une UI grand écran et la synchronisation des paramètres avec l’app iOS.
Ce que l’agent a bien fait :
- Il a lu le TimerManager iOS existant et créé un TVTimerManager qui omettait Live Activities et HealthKit (indisponibles sur tvOS)
- Il a créé des styles de boutons personnalisés pour la navigation au focus avec Siri Remote (TVCapsuleButtonStyle, TVCircleButtonStyle)
- Il a construit un composant TVStepper qui remplace les sélecteurs à roue (inutilisables avec Siri Remote) par des boutons +/-
- Il a implémenté la synchronisation des paramètres via App Groups (group.com.941apps.Return)
- Il a ajouté des gardes #if os(tvOS) dans tout le code partagé
- Il a compilé et testé via MCP avec platform=tvOS Simulator,name=Apple TV
Ce que j’ai dû faire manuellement : - Créer la cible tvOS dans Xcode (File > New > Target > tvOS App) - Ajouter la nouvelle cible au projet Xcode (modifications du .pbxproj) - Configurer l’autorisation App Groups pour la cible TV - Ajouter la cible TV au schéma existant ou en créer un nouveau - Ajouter manuellement tous les fichiers Swift créés par l’agent à la cible TV - Tester la navigation Siri Remote à la main (l’agent ne peut pas évaluer le comportement du focus)
Résultat : 15 nouveaux fichiers Swift, une app TV entièrement fonctionnelle, en environ 3 heures de travail assisté par agent. D’après mon estimation, l’agent a géré environ 80 % du travail d’implémentation ; je me suis occupé des parties qui nécessitaient une interaction avec l’UI de Xcode (autorisations, configuration de cible, indicateurs de capacité) et des tests manuels du focus sur une vraie Apple TV. Un travail solo équivalent dans cette base de code — d’après des fonctionnalités similaires que j’ai livrées sans agents — aurait pris plusieurs jours.
Étude de cas 2 : débogage d’un shader Metal dans amp97 (échec partiel)
La tâche : ajouter un système d’intensité basé sur l’énergie au shader d’oscilloscope. La visualisation devait pulser avec l’énergie audio.
Ce qui s’est passé :
1. L’agent a écrit une modification valide du shader Metal en ajoutant un uniforme uEnergy et du tonemapping HDR
2. Le code s’est compilé sans erreur
3. Sur appareil, la visualisation était entièrement blanche — le coefficient d’intensité était 10 fois trop élevé (3.5 au lieu de 0.30)
4. L’agent ne pouvait pas voir l’écran blanc, il n’avait donc aucun signal de retour
5. J’ai identifié le problème visuellement et demandé à l’agent de réduire le coefficient
6. L’agent l’a réduit, mais la machine à états globale de l’énergie était trop complexe et a cassé le visualiseur autrement
7. Retour arrière complet — deux commits (67959ed et cda4830) annulés dans 869d914
La leçon : les shaders Metal sont le domaine le plus difficile pour le développement assisté par agents, car la boucle de retour est rompue. L’agent peut vérifier la syntaxe (ça compile) et la sémantique (types corrects), mais pas la sortie (l’aspect visuel est correct). Toute modification de shader qui change le comportement visuel nécessite une vérification humaine sur appareil.
Ce que j’ai ajouté à CLAUDE.md ensuite : « DO NOT attempt energy state modifications to the oscilloscope shader without extremely careful coefficient testing. Previous attempt broke the visualizer with coefficients 10x too high. »
Étude de cas 3 : migration SwiftData dans Banana List (réussite)
La tâche : migrer le modèle de données de V1 vers V2, en ajoutant un champ quantity à GroceryItem et un nouveau modèle Category avec des relations.
Ce que l’agent a fait :
1. Il a lu les définitions existantes du modèle V1
2. Il a créé les définitions du modèle V2 avec les nouveaux champs et les nouvelles relations
3. Il a écrit un GroceryMigrationPlan conforme au protocole SchemaMigrationPlan
4. Il a implémenté l’étape de migration V1toV2 : ajout de quantity: 1 par défaut et de category: nil
5. Il a mis à jour toutes les vues pour prendre en charge les nouveaux champs
6. Il a mis à jour SampleData.swift pour les aperçus
7. Il a compilé et exécuté les tests via MCP — tout est passé
8. Il a créé des tests unitaires spécifiques à la migration
Le point clé : l’agent a réussi parce que les migrations SwiftData suivent un modèle de protocole bien défini, largement représenté dans la documentation Apple et les données d’entraînement. Le CLAUDE.md documentait explicitement le modèle V1, l’agent comprenait donc depuis quoi il migrait.
Étude de cas 4 : synchronisation de sessions iCloud dans Return (réussite avec complexité)
La tâche : implémenter la journalisation de sessions de méditation entre appareils. Les sessions terminées sur Apple TV ou Mac devaient se synchroniser vers l’iPhone pour la journalisation HealthKit.
Ce que l’agent a produit :
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ tvOS │ │ Mac │ │ Watch │
│ TVTimerMgr │ │ TimerMgr │ │ WatchTimer │
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
│ │ │
└───────────────────┼───────────────────┘
│
▼
┌────────────────────────┐
│ SessionStore │
│ (iCloud Key-Value) │
└───────────┬────────────┘
│
▼
┌────────────────────────┐
│ iPhone (on foreground)│
│ → Write to HealthKit │
└────────────────────────┘
L’agent :
1. A créé le modèle de données MeditationSession avec UUID, dates, durée, appareil source et statut de synchronisation HealthKit
2. A construit le singleton SessionStore qui gère NSUbiquitousKeyValueStore pour la synchronisation iCloud
3. A implémenté la résolution des conflits de fusion (déduplication basée sur l’UUID)
4. A ajouté SessionHistoryView avec des adaptations propres à chaque plateforme (balayer pour supprimer sur iOS, focus sur tvOS)
5. A câblé la synchronisation HealthKit côté iPhone pour les sessions provenant d’autres appareils
Ce qui a nécessité des itérations : l’implémentation initiale ne gérait pas le cas où l’app iPhone se lance en arrière-plan (pas de notification au premier plan pour la synchronisation). L’agent avait besoin d’une consigne précise : « Use NSUbiquitousKeyValueStore.didChangeExternallyNotification to trigger sync on background KV changes. » Après cet indice, l’implémentation était correcte.
La leçon : les agents gèrent bien les modèles d’architecture multiplateformes lorsque l’architecture est clairement décrite. Le modèle de synchronisation iCloud n’est pas trivial, mais il suit un schéma Apple documenté que l’agent a compris. Le cas limite (synchronisation en arrière-plan) a nécessité une connaissance humaine du domaine, car il est mal documenté.
Étude de cas 5 : intégration Game Center dans Starfield Destroyer (réussite)
La tâche : ajouter des classements et des succès Game Center au jeu de tir spatial.
Ce que l’agent a bien fait :
- Il a implémenté GKLocalPlayer.local.authenticateHandler au point d’entrée de l’app
- Il a créé un GameCenterManager avec des méthodes de soumission de score et de signalement des succès
- Il a ajouté une vérification de l’état d’authentification avant toutes les opérations Game Center
- Il a géré proprement le cas hors ligne (le jeu fonctionne sans Game Center et soumet les scores à la reconnexion)
- Il a créé des définitions de succès correspondant au système de progression à 8 vaisseaux
Ce qui a nécessité un travail manuel : - Créer les classements et les succès dans App Store Connect (portail web, inaccessible à l’agent) - Configurer l’autorisation Game Center dans Xcode - Tester avec un compte Game Center sandbox (nécessite une connexion manuelle sur l’appareil)
Cycle de vie du projet avec des agents
Démarrer un nouveau projet iOS
Le workflow optimal pour démarrer un nouveau projet avec l’aide d’un agent :
Phase 1 : configuration humaine (15 à 30 minutes) 1. Créez le projet Xcode (Fichier > Nouveau > Projet) 2. Configurez la signature et les capacités 3. Définissez la cible de déploiement et les destinations prises en charge 4. Ajoutez les entitlements requis (HealthKit, Game Center, etc.) 5. Créez le CLAUDE.md initial avec l’identité et les règles du projet
Phase 2 : implémentation par l’agent (de quelques heures à quelques jours) 1. L’agent crée le modèle de données (SwiftData, Core Data ou structs simples) 2. L’agent construit les vues en suivant vos patterns documentés 3. L’agent implémente la logique métier dans des classes manager/service 4. L’agent écrit les tests unitaires 5. Boucle build-test-fix via MCP (autonome)
Phase 3 : intégration humaine (30 à 60 minutes) 1. Ajoutez les fichiers créés par l’agent aux targets Xcode 2. Vérifiez la signature et les entitlements 3. Testez sur un appareil physique 4. Relisez la mise en page visuelle et l’UX 5. Soumettez à App Store Connect
Maintenir un projet existant
Pour le développement continu d’apps établies :
You: Here's the next feature for Return: add a "Focus Score" that
calculates from session duration and consistency. Show it on
the main timer view. Build and test.
Claude: [reads CLAUDE.md, understands patterns]
[reads TimerManager.swift, Settings.swift]
[creates FocusScore.swift — model with calculation logic]
[creates FocusScoreView.swift — display component]
[integrates into ContentView.swift]
[calls build_sim — 1 error: missing import]
[fixes import]
[calls build_sim — success]
[writes FocusScoreTests.swift]
[calls test_sim — all pass]
L’efficacité de l’agent augmente avec la qualité avec laquelle votre CLAUDE.md reflète l’état actuel du projet. Mettez à jour votre CLAUDE.md lorsque vous ajoutez de nouvelles fonctionnalités importantes, modifiez des patterns d’architecture ou introduisez de nouveaux frameworks.
Quand impliquer l’agent, ou non
| Tâche | Agent ? | Pourquoi |
|---|---|---|
| Nouvelle vue SwiftUI | Oui | Les agents excellent dans l’UI déclarative |
| Modifications de modèle SwiftData | Oui | Bien défini, testable |
| Tests unitaires | Oui | Mécanique, fondé sur des patterns |
| Refactoring | Oui | Systématique, multi-fichier |
| Diagnostic d’erreur de build | Oui (via MCP) | Boucle de feedback structurée |
| Nouveau target Xcode | Non | Nécessite l’UI Xcode, modifications de .pbxproj |
| Signature et provisionnement | Non | Basé sur un portail, inaccessible à l’agent |
| Finition visuelle | Non | Nécessite un jugement esthétique humain |
| Ajustement de shader Metal | Non | Nécessite des tests GPU sur appareil |
| Soumission à l’App Store | Non | Portail et Xcode Organizer |
| Profilage des performances | Non | Nécessite Instruments |
| Audit d’accessibilité | Partiel | L’agent peut ajouter des labels, l’humain vérifie VoiceOver |
Configurer les définitions d’agents
Si vous utilisez le système de définition d’agents de Claude Code (.claude/agents/), créez un agent spécifique à iOS :
---
name: ios-developer
description: iOS development agent with MCP build tools and SwiftUI expertise
tools:
- XcodeBuildMCP
- xcode
---
# iOS Developer Agent
You are an iOS development agent for apps targeting iOS 26+ with SwiftUI.
## Architecture Rules
- @Observable for all view models (NEVER ObservableObject)
- NavigationStack for all navigation (NEVER NavigationView)
- SwiftData for persistence
- Swift 6.2 strict concurrency
- @MainActor on all Observable classes
## Build & Test — Always Use MCP
Prefer MCP tools over raw shell commands for ALL build operations:
- **Build**: `build_sim` / `build_device` (NOT `xcodebuild` via Bash)
- **Test**: `test_sim` / `test_device` (NOT `xcodebuild test` via Bash)
- **Simulators**: `list_sims`, `boot_sim`, `open_sim`
- **Debug**: `debug_attach_sim`, `debug_stack`, `debug_variables`
- **Apple docs**: `DocumentationSearch` (NOT WebSearch for Apple APIs)
- **Swift verification**: `ExecuteSnippet` (NOT `swift` via Bash)
MCP returns structured JSON. Bash returns unstructured text.
## File Management Rules
- NEVER modify .pbxproj, .xcodeproj/, .xcworkspace/, .xib, .storyboard
- Create Swift files in the correct directory
- Report files that need manual addition to Xcode targets
## SwiftData Rules
- @Model classes are automatically Observable — do not add @Observable
- Use @Bindable for form bindings to model properties
- Use @Query in views, modelContext.fetch() elsewhere
- Document relationship delete rules
## When You Get Stuck
- Build errors: use `build_sim` via MCP for structured output
- API questions: use `DocumentationSearch` via Apple MCP
- Swift verification: use `ExecuteSnippet` via Apple MCP
- Never guess — verify with tools
Référencez cet agent avec @ios-developer dans les sessions Claude Code.
Patterns de test pour iOS assisté par agent
Les agents écrivent d’excellents tests unitaires lorsqu’ils reçoivent des consignes claires. Voici les patterns qui produisent les meilleurs résultats.
Organisation des fichiers de test
# In CLAUDE.md:
## Test Structure
Tests mirror source structure:
- `ReturnTests/TimerManagerTests.swift` tests `TimerManager.swift`
- `ReturnTests/SettingsTests.swift` tests `Settings.swift`
- `ReturnTests/ConstantsTests.swift` tests `Constants.swift`
Test naming: `test_<what>_<condition>_<expected>`
Example: `test_start_whenStopped_transitionsToRunning`
Prompts pour les tests
Prompt de test efficace :
Write unit tests for TimerManager covering:
1. Initial state is .stopped with timeRemaining == selectedDuration
2. start() transitions state to .running
3. pause() from .running transitions to .paused
4. reset() from any state returns to .stopped with original duration
5. start() from .paused resumes (state becomes .running)
6. Edge case: reset() when already stopped is a no-op
7. Edge case: pause() when already paused is a no-op
Follow the existing test pattern in SettingsTests.swift.
Use setUp() to create a fresh TimerManager for each test.
Pourquoi cela fonctionne : les critères d’acceptation numérotés donnent une checklist à l’agent. La référence à un fichier de test existant établit le pattern. La mention de l’utilisation de setUp() empêche l’agent de créer un état de test enchevêtré.
Prompt de test inefficace :
Write tests for TimerManager.
Cela produit des tests génériques et superficiels qui ratent les cas limites et peuvent ne pas suivre les patterns de votre projet.
Patterns de test async
Pour tester du code async et basé sur des timers :
// Agent produces this pattern when guided correctly:
final class TimerManagerTests: XCTestCase {
var sut: TimerManager!
@MainActor
override func setUp() {
super.setUp()
sut = TimerManager()
}
@MainActor
func test_start_whenStopped_transitionsToRunning() {
// Given
XCTAssertEqual(sut.state, .stopped)
// When
sut.start()
// Then
XCTAssertEqual(sut.state, .running)
}
@MainActor
func test_timerCountsDown_afterOneSecond() async throws {
// Given
sut.selectedDuration = 10
sut.reset()
sut.start()
// When
try await Task.sleep(for: .seconds(1.1))
// Then
XCTAssertLessThanOrEqual(sut.timeRemaining, 9.0)
}
}
Patterns clés à rappeler aux agents :
- @MainActor sur les méthodes de test qui testent des classes @MainActor
- async throws pour les tests qui utilisent Task.sleep ou des opérations async
- Une tolérance dans les assertions basées sur le temps (1,1 seconde, pas exactement 1,0)
- setUp() / tearDown() propres pour isoler les tests
Snapshot Testing
Pour détecter les régressions visuelles, envisagez d’ajouter swift-snapshot-testing :
Add snapshot tests for the main timer view in three states:
1. Stopped (showing full duration)
2. Running (showing countdown)
3. Completed (showing 00:00 with completion state)
Use SnapshotTesting library. Create reference images on first run.
Les agents configurent correctement les snapshot tests, mais ne peuvent pas examiner les images de référence. Vous relisez les snapshots initiaux, puis les tests de l’agent détectent les régressions visuelles lors des changements futurs.
Gestion de la fenêtre de contexte pour les projets iOS
La fenêtre de contexte de 1M (Opus 4.6) est grande, mais pas infinie. Les projets iOS ont des contraintes spécifiques de gestion du contexte.
Coût en tokens des fichiers iOS
| Type de fichier | Taille typique | Tokens approximatifs |
|---|---|---|
| Vue SwiftUI (simple) | 50-100 lignes | 500-1,000 |
| Vue SwiftUI (complexe) | 200-400 lignes | 2,000-4,000 |
| Modèle SwiftData | 30-80 lignes | 300-800 |
| Classe de gestion/service | 100-300 lignes | 1,000-3,000 |
| Shader Metal (.metal) | 50-200 lignes | 500-2,000 |
| Fichier de tests unitaires | 50-200 lignes | 500-2,000 |
| CLAUDE.md | 100-300 lignes | 1,000-3,000 |
| Réponse MCP (build) | variable | 200-2,000 |
| Réponse MCP (test) | variable | 500-5,000 |
Pour un projet de 50 fichiers : lire tous les fichiers consomme environ 50,000-100,000 tokens — bien en dessous de la fenêtre de 1M. L’agent peut garder tout le projet en contexte.
Pour un projet de plus de 100 fichiers : une lecture sélective devient nécessaire. L’agent lit d’abord CLAUDE.md (pour les annotations de structure des fichiers), puis lit les fichiers spécifiques selon les besoins. C’est pourquoi les annotations de fichiers dans CLAUDE.md sont cruciales : elles guident l’agent vers les bons fichiers sans tout lire.
Stratégies pour les grands projets
- Annotations détaillées des fichiers dans CLAUDE.md — L’agent lit la carte des fichiers et navigue directement vers les fichiers pertinents
- Délégation à des subagents — Confiez l’exploration et la recherche à des subagents (contexte propre, retours sous forme de résumés)
- Prompts ciblés — « Modifier SettingsView.swift pour ajouter un nouveau toggle » vaut mieux que « mettre à jour les paramètres »
- Limites de session — Démarrez de nouvelles sessions pour les fonctionnalités sans lien plutôt que d’allonger une longue session
- Utiliser
/compact— La commande de compactage de Claude Code résume la conversation et libère du contexte
Efficacité en tokens de MCP
L’un des arguments les plus solides en faveur de MCP : les réponses JSON structurées consomment beaucoup moins de tokens que la sortie brute de xcodebuild.
| Scénario | Tokens Bash bruts | Tokens MCP | Économies |
|---|---|---|---|
| Build réussi | 3,000-10,000 | 200-500 | 85-95% |
| Build échoué (1 erreur) | 3,000-10,000 | 300-800 | 90-92% |
| Résultats de tests (20 tests) | 2,000-5,000 | 500-1,000 | 75-80% |
| Liste des simulateurs | 500-2,000 | 200-400 | 60-80% |
Sur une session de développement typique avec 10-20 cycles de build, MCP économise 30,000-150,000 tokens par rapport à xcodebuild brut — des tokens qui restent disponibles pour le raisonnement réel sur le code.
Dépannage
« build_sim failed — scheme not found »
L’agent devine le nom du scheme. Correctif :
Use discover_projs and list_schemes to find the correct scheme name
for this project before building.
Ou ajoutez explicitement le nom du scheme à votre CLAUDE.md :
## Build
Primary scheme: `Return` (iOS)
Watch scheme: `ReturnWatch` (watchOS)
TV scheme: `ReturnTV` (tvOS)
« xcrun mcpbridge — command not found »
Vous avez besoin de Xcode 26.3 ou d’une version ultérieure. Vérifiez avec xcodebuild -version. Si vous avez Xcode 26.3+ mais que la commande échoue toujours :
# Ensure Xcode command line tools are selected
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
# Verify
xcrun mcpbridge --help
« Les outils MCP n’apparaissent pas dans Claude Code »
Les outils MCP enregistrés en cours de session peuvent ne pas apparaître avant un redémarrage. Quittez Claude Code et démarrez une nouvelle session :
# Exit current session (Ctrl+C or /exit)
# Start fresh
claude
Puis vérifiez :
You: List all available MCP tools from XcodeBuildMCP.
« L’agent continue d’utiliser xcodebuild via Bash au lieu de MCP »
L’agent ne découvre pas les outils MCP via Tool Search. Deux correctifs :
- Ajoutez des consignes explicites à CLAUDE.md (voir Apprendre à l’agent à utiliser MCP)
- Donnez une consigne directe : « Utilisez l’outil MCP build_sim, pas xcodebuild via Bash »
« Le build réussit, mais l’agent signale un échec »
XcodeBuildMCP analyse la sortie de xcodebuild. Si le build produit des warnings qui ressemblent à des erreurs (fréquent avec les avertissements de dépréciation), l’agent peut mal interpréter le résultat. Vérifiez le champ de statut réel dans la réponse MCP.
« Le simulateur se bloque pendant le démarrage »
Tuez tous les simulateurs et redémarrez :
xcrun simctl shutdown all
xcrun simctl boot "iPhone 16 Pro"
Ou demandez à l’agent :
Shut down all simulators, then boot a fresh iPhone 16 Pro.
« L’agent a essayé de modifier .pbxproj malgré les règles de CLAUDE.md »
Les règles de CLAUDE.md sont des suggestions. Les hooks sont des mécanismes d’application. Si vous n’avez pas le hook PreToolUse qui bloque les écritures dans .pbxproj, l’agent finira par essayer. Installez le hook :
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"command": "bash -c 'INPUT=$(cat); FP=$(echo \"$INPUT\" | jq -r \".tool_input.file_path // empty\"); if echo \"$FP\" | grep -qE \"\\.(pbxproj|xcworkspace|xib|storyboard)$|xcodeproj/|xcworkspace/\"; then echo \"BLOCKED: Do not modify Xcode project files.\" >&2; exit 2; fi'"
}
]
}
}
Les règles disent « s’il vous plaît, ne le faites pas ». Les hooks disent « vous ne pouvez pas ».
FAQ
Avec quel runtime d’agent dois-je commencer ?
Claude Code CLI avec XcodeBuildMCP. Il offre l’intégration MCP la plus poussée, le système de hooks le plus mature et la fenêtre de contexte de 1M (Opus 4.6), capable de garder des projets iOS entiers en mémoire de travail. Commencez par là, puis ajoutez Codex pour les revues et les agents natifs Xcode pour les modifications inline rapides à mesure que votre workflow gagne en maturité.
Ai-je besoin des deux serveurs MCP ?
Pour la plupart des développeurs, XcodeBuildMCP couvre à lui seul 90 % des besoins (builds, tests, simulateurs, débogage). Ajoutez le MCP Xcode d’Apple si vous souhaitez rechercher dans la documentation, vérifier du code dans le REPL Swift ou rendre des previews SwiftUI. Vous pouvez toujours l’ajouter plus tard : les deux serveurs sont indépendants.
Les agents peuvent-ils créer un nouveau projet Xcode from scratch ?
XcodeBuildMCP inclut un outil create_project qui génère la structure initiale de nouveaux projets Xcode. Toutefois, pour les apps de production, je recommande de créer le projet dans Xcode (afin de configurer correctement la signature, les capabilities et les targets), puis d’utiliser les agents pour toute l’implémentation du code. Les 5 minutes passées dans l’assistant de nouveau projet de Xcode vous évitent des heures de problèmes de configuration de projet générés par agent.
Comment les agents gèrent-ils les dépendances Swift Package Manager ?
Bien. Package.swift est un fichier Swift standard que les agents peuvent lire et modifier de manière fiable. L’ajout de dépendances, la mise à jour des plages de versions et la configuration des targets fonctionnent tous correctement. La limite concerne la gestion des dépendances basée sur .xcodeproj (l’interface de résolution de packages de Xcode) : elle est gérée par Xcode et ne doit pas être modifiée par un agent.
Les agents peuvent-ils soumettre une app à l’App Store ?
Non. La soumission à l’App Store implique l’Organizer de Xcode, les profils de provisioning, les captures d’écran, les métadonnées et le portail App Store Connect. Aucun de ces éléments n’est accessible via MCP ou des outils en ligne de commande de façon exploitable par des agents. Les agents gèrent tout jusqu’à l’archive : implémentation, tests, correction de bugs et documentation. Le dernier kilomètre de la soumission reste opéré par un humain.
En revanche, les agents peuvent vous aider avec les métadonnées de l’App Store. Demandez à l’agent de rédiger la description de l’app, les mots-clés et le texte des nouveautés à partir des derniers changements. C’est un travail de génération de texte dans lequel les agents excellent.
Comment gérer les secrets et les clés API dans le développement iOS assisté par agents ?
Ne commettez jamais de secrets. Pour les apps iOS qui se connectent à des APIs backend :
- Utilisez des fichiers
.xcconfigpour la configuration propre à chaque environnement - Ajoutez les fichiers
.xcconfigà.gitignore - Référencez les valeurs de configuration via les build settings de
Info.plist - Documentez les secrets requis dans CLAUDE.md sans inclure les valeurs réelles
## Configuration
API base URL and keys are in `Config.xcconfig` (not committed).
Required keys:
- `API_BASE_URL` — Backend server URL
- `API_KEY` — Authentication token
Create `Config.xcconfig` from `Config.xcconfig.template`.
L’agent sait que les clés existent et où elles sont utilisées, mais il ne voit jamais les valeurs réelles.
Qu’en est-il des animations SwiftUI : les agents peuvent-ils les écrire ?
Les agents écrivent correctement le code d’animation sur le plan syntaxique, mais ne peuvent pas vérifier le résultat visuellement. Les animations simples (.animation(.spring()), .transition(.slide), withAnimation { }) produisent des résultats corrects. Les animations complexes, en plusieurs étapes, avec un timing précis nécessitent une itération visuelle que les agents ne peuvent pas effectuer.
Efficace : « Ajoutez une animation spring lorsque le minuteur passe d’un état à l’autre. »
Inefficace : « Rendez l’animation du minuteur satisfaisante. » (Subjectif, nécessite un ajustement visuel.)
Comment les agents gèrent-ils les patterns de gestion d’erreurs ?
Très bien. Les agents comprennent les patterns Swift do/catch, Result et async throws :
Implement error handling for the HealthKit authorization flow:
1. Check HKHealthStore.isHealthDataAvailable() — show alert if not
2. Request authorization — handle denial gracefully
3. On write failure — retry once, then show error
4. All errors should be user-facing with localized descriptions
Les agents produisent une gestion d’erreurs structurée avec des messages appropriés pour l’utilisateur. Ils ont parfois tendance à sur-gérer les erreurs (en capturant des exceptions qui devraient se propager), donc relisez les blocs catch.
Puis-je utiliser des agents pour implémenter l’accessibilité ?
Partiellement. Les agents ajoutent correctement les labels, hints et traits d’accessibilité :
Add accessibility labels to all interactive elements in TimerView:
- Timer display: current time remaining
- Start/Pause button: current state and action
- Reset button: "Reset timer"
- Duration picker: selected duration
Ce que les agents ne peuvent pas faire : vérifier que l’ordre de navigation VoiceOver est correct, tester la mise à l’échelle Dynamic Type ou évaluer les ratios de contraste des couleurs. Utilisez l’Accessibility Inspector de Xcode pour la vérification.
Comment les agents gèrent-ils les migrations Core Data (si vous n’utilisez pas SwiftData) ?
Les agents écrivent les mappings de migration Core Data et les versions de modèle, mais les étapes manuelles dans Xcode (création de nouvelles versions de modèle, sélection de la version actuelle) ne peuvent pas être automatisées. Si vous êtes encore sur Core Data plutôt que SwiftData, documentez l’historique des versions de modèle dans CLAUDE.md :
## Core Data Model Versions
- V1: Initial (GroceryList, GroceryItem)
- V2: Added Category model (current)
- Migration: Lightweight automatic for V1→V2
Comment les agents gèrent-ils les previews SwiftUI ?
De deux façons :
1. L’outil RenderPreview du MCP Xcode d’Apple rend les previews headlessly et renvoie le résultat. L’agent peut vérifier qu’une preview compile et se rend sans erreur, mais il ne peut pas évaluer sa justesse visuelle.
2. La vérification basée sur le build via build_sim confirme que les preview providers compilent. Si une preview plante à l’exécution, le build réussit quand même : le crash ne se manifeste que lorsque Xcode tente de rendre la preview.
Pour la vérification visuelle des previews, vous avez toujours besoin d’ouvrir Xcode.
Qu’en est-il de visionOS et d’Apple Vision Pro ?
Les mêmes patterns s’appliquent. XcodeBuildMCP prend en charge les simulateurs visionOS, et les patterns architecturaux (@Observable, NavigationStack, SwiftData) sont identiques. Le code propre à RealityKit (contenu 3D, espaces immersifs, suivi des mains) présente les mêmes limites que Metal : les agents peuvent écrire du code correct, mais ils ne peuvent pas vérifier le rendu spatial.
Quelle taille un projet peut-il atteindre avant que les agents commencent à peiner ?
La taille de la fenêtre de contexte est le facteur limitant. Avec la fenêtre de 1M tokens d’Opus 4.6, Claude Code peut garder simultanément environ 50 à 70 fichiers Swift en mémoire de travail active. Pour les projets plus volumineux, l’agent utilise la recherche de fichiers et la lecture sélective pour travailler sur des sous-ensembles de la codebase. Les projets de plus de 100 fichiers fonctionnent bien : l’agent lit simplement les fichiers à la demande au lieu de tout conserver en contexte.
La limite pratique n’est pas le nombre de fichiers, mais la cohérence de la codebase. Un projet bien documenté de 200 fichiers avec un CLAUDE.md détaillé produit de meilleurs résultats qu’un projet non documenté de 30 fichiers.
Dois-je connaître Swift pour utiliser des agents dans le développement iOS ?
Vous devez pouvoir relire la sortie de l’agent et prendre des décisions architecturales. Vous n’avez pas besoin d’écrire chaque ligne vous-même, mais vous devez comprendre Swift suffisamment pour détecter les mauvais choix de l’agent, en particulier autour de la concurrence, de la gestion de la mémoire et des patterns propres aux frameworks. Un agent est un amplificateur 10x de votre compétence existante, pas un substitut.
Comment les agents gèrent-ils les conflits de merge dans les fichiers Swift ?
Les agents résolvent de manière fiable les conflits de merge dans les fichiers source Swift. Les marqueurs de conflit standard (<<<<<<<, =======, >>>>>>>) sont bien compris par tous les runtimes d’agents. Toutefois, les conflits de merge dans les fichiers .pbxproj restent une tâche de résolution manuelle : ne demandez pas aux agents de résoudre des conflits .pbxproj.
Quel est le coût d’utilisation des agents pour le développement iOS ?
Avec le plan Max de Anthropic (Opus 4.6, contexte 1M), une session typique de développement iOS dure 30 à 120 minutes et traite 200K à 800K tokens. Les appels d’outils MCP ajoutent une surcharge minimale (les réponses JSON structurées sont économes en tokens par rapport à une sortie de build brute). Le coût est comparable à l’utilisation de Claude Code sur n’importe quelle autre codebase : le développement iOS n’est pas sensiblement plus ou moins coûteux que le développement web.
Puis-je utiliser des agents avec des projets UIKit ?
Oui, mais les agents sont plus efficaces avec SwiftUI. UIKit exige davantage de boilerplate, présente une structure moins déclarative et implique souvent des fichiers Interface Builder que les agents ne peuvent pas modifier. Si vous avez un projet UIKit, envisagez d’utiliser les agents pour la couche modèle et la logique métier tout en gérant l’UI manuellement, ou en migrant progressivement des vues vers SwiftUI.
Comment les agents gèrent-ils la localisation ?
Les agents créent et modifient efficacement les fichiers .xcstrings (catalogue de chaînes Xcode). Ils peuvent ajouter de nouvelles clés de localisation, fournir des traductions et maintenir la cohérence entre les langues. Le format JSON structuré des fichiers .xcstrings est adapté aux agents. Pour les fichiers .strings (format legacy), les agents s’en sortent aussi bien : le format clé-valeur est simple.
Erreurs courantes des agents en iOS (et comment les éviter)
Voici les erreurs récurrentes que j’ai observées dans des milliers d’interactions avec des agents sur 8 projets iOS. Chacune a une stratégie de prévention.
Erreur 1 : mélanger les modèles Observable
Ce qui se passe : l’agent utilise @Observable dans un fichier et ObservableObject dans un autre, ou ajoute @Observable à une classe @Model (qui est déjà Observable).
Prévention : règles explicites dans CLAUDE.md :
- NEVER use ObservableObject — use @Observable
- NEVER add @Observable to @Model classes (already Observable)
- NEVER use @StateObject — use @State with @Observable
- NEVER use @ObservedObject — access @Observable properties directly
Erreur 2 : créer des cycles de rétention dans les closures
Ce qui se passe : l’agent crée des closures qui capturent fortement self, surtout dans Timer.publish, NotificationCenter et les gestionnaires de complétion.
Prévention : inclure un modèle de closure dans CLAUDE.md :
## Closure Pattern
- Timer callbacks: use `[weak self]` and guard
- NotificationCenter observers: store in `Set<AnyCancellable>` and use `[weak self]`
- Completion handlers: use `[weak self]` for any closure stored beyond the call site
Erreur 3 : ignorer les exigences @MainActor
Ce qui se passe : l’agent crée des classes @Observable sans isolation @MainActor, ce qui provoque des avertissements de concurrence Swift 6.2 ou des plantages à l’exécution lorsque les mises à jour de l’UI se produisent hors du thread principal.
Prévention :
## Concurrency Rule
ALL @Observable classes MUST be @MainActor:
```swift
@Observable
@MainActor
final class SomeManager { }
```
Erreur 4 : utiliser NavigationLink avec une closure de destination
Ce qui se passe : l’agent utilise le NavigationLink(destination:label:) obsolète au lieu du modèle typé sûr NavigationLink(value:) + .navigationDestination(for:).
Prévention :
## Navigation Pattern
ALWAYS use value-based navigation:
```swift
NavigationLink(value: item) { ItemRow(item: item) }
.navigationDestination(for: Item.self) { ItemDetailView(item: $0) }
```
NEVER use: `NavigationLink(destination: ItemDetailView(item: item)) { }`
Erreur 5 : coder en dur les noms de simulateurs
Ce qui se passe : l’agent écrit des commandes de build avec des noms de simulateurs précis (« iPhone 16 Pro ») qui peuvent ne pas exister sur votre système.
Prévention : MCP gère cela : list_sims découvre les simulateurs disponibles. Dans CLAUDE.md :
## Simulators
Do NOT hardcode simulator names. Use `list_sims` MCP tool to discover
available devices, then `boot_sim` with the discovered device ID.
Erreur 6 : créer des fichiers dans les mauvais dossiers
Ce qui se passe : l’agent crée un nouveau fichier de vue à la racine du projet au lieu du sous-dossier Views/, ou place un modèle dans le mauvais groupe.
Prévention : les annotations de structure de fichiers dans CLAUDE.md guident le placement. En outre :
## File Placement Rules
- Views → `AppName/Views/`
- Models → `AppName/Models/`
- Managers → `AppName/Managers/`
- Extensions → `AppName/Extensions/`
- Tests → `AppNameTests/`
Erreur 7 : ne pas gérer la disponibilité des plateformes
Ce qui se passe : l’agent utilise HealthKit dans du code partagé qui compile pour tvOS (où HealthKit n’est pas disponible), ou utilise ActivityKit dans du code watchOS.
Prévention :
## Platform Guards
- HealthKit: `#if canImport(HealthKit)` (unavailable on tvOS)
- ActivityKit: `#if canImport(ActivityKit)` (iOS only)
- WatchKit: `#if os(watchOS)`
- UIKit haptics: `#if os(iOS)` (unavailable on tvOS, watchOS uses WKHaptic)
Erreur 8 : surconcevoir des fonctionnalités simples
Ce qui se passe : l’agent crée un protocole, une extension de protocole, une implémentation concrète, une factory et un conteneur d’injection de dépendances pour ce qui devrait être une fonction utilitaire de 20 lignes.
Prévention : inclure un principe de simplicité :
## Architecture Principle
Prefer the simplest solution that handles the requirements.
- Direct implementation over protocol abstraction (unless you have 2+ conforming types)
- Concrete types over generics (unless reuse is proven)
- Extensions on existing types over new wrapper types
L’évaluation honnête
Après avoir livré 8 apps iOS avec des agents IA, voici le bilan :
Ce que les agents ont transformé : la vitesse d’implémentation. Ce qui prenait des jours prend des heures. Vues SwiftUI, modèles SwiftData, tests unitaires, refactoring : tout cela est désormais principalement produit par des agents et revu par des humains.
Ce que les agents n’ont pas transformé : les décisions d’architecture, le design visuel, l’optimisation des performances ou la soumission à l’App Store. Ces sujets restent pilotés par les humains.
Le multiplicateur est réel, mais limité. Mon estimation subjective sur le portefeuille de 8 apps : une amélioration de 3 à 5x du délai de mise en œuvre d’une fonctionnalité sur des projets bien documentés, avec une configuration correcte de MCP et des hooks. Cette estimation n’est pas mesurée face à un groupe de contrôle ; c’est une comparaison en temps réel entre des fonctionnalités assistées par agent et un travail solo équivalent dans les mêmes bases de code. Les projets non documentés, sans hooks, voient peut-être une amélioration de 1,5 à 2x : l’agent passe trop de temps à deviner au lieu de construire.19
L’investissement qui rapporte : le temps consacré à CLAUDE.md, aux hooks et à la configuration de MCP. Chaque heure de préparation économise de nombreuses heures de correction des erreurs de l’agent. La configuration est le produit ; l’agent est le moteur d’exécution.
Ce qui m’a surpris : à quel point les serveurs MCP ont changé la dynamique. Avant MCP, les agents étaient des éditeurs de texte sophistiqués qui comprenaient Swift. Après MCP, ce sont des partenaires de développement qui écrivent, buildent, testent, déboguent et itèrent. La boucle de feedback structurée fait la différence entre un agent qui écrit du code et un agent qui livre du code.
Ce que je dirais à mon moi du passé : commencez par la plus petite app (Reps, 14 fichiers), configurez correctement MCP et les hooks, rédigez un CLAUDE.md complet, puis étendez ces modèles aux projets plus grands. Ne commencez pas par l’app multiplateforme de 63 fichiers. L’investissement d’infrastructure est le même quelle que soit la taille du projet : faites-le une fois sur un petit projet, puis copiez-le partout ailleurs.
L’avenir : l’intégration native des agents dans Xcode 26.3 est un début, pas une fin. Le fait qu’Apple livre la prise en charge de MCP signifie que la toolchain évolue vers un développement centré sur les agents. Les développeurs qui investissent dès maintenant dans des structures de projet compatibles avec les agents — fichiers CLAUDE.md propres, architectures testables, hooks automatisés — amplifieront cet investissement à mesure que les outils progresseront.
Carte de référence rapide
Installation (configuration unique)
# XcodeBuildMCP (59 tools)
claude mcp add XcodeBuildMCP -s user \
-e XCODEBUILDMCP_SENTRY_DISABLED=true \
-- npx -y xcodebuildmcp@latest mcp
# Apple Xcode MCP (20 tools)
claude mcp add --transport stdio xcode -s user -- xcrun mcpbridge
# Codex MCP setup
codex mcp add xcode -- xcrun mcpbridge
# Verify
claude mcp list
Sections essentielles de CLAUDE.md
1. Project identity (bundle ID, target OS, architecture)
2. File structure with annotations
3. Build and test commands
4. Key patterns and rules
5. Prohibitions (NEVER touch .pbxproj)
6. Framework-specific context
Hooks essentiels
{
"PreToolUse": [{ "matcher": "Edit|Write", "command": "block .pbxproj" }],
"PostToolUse": [{ "matcher": "Edit|Write", "command": "swiftformat" }]
}
Règles d’architecture
@Observable (not ObservableObject)
NavigationStack (not NavigationView)
@State (not @StateObject)
SwiftData @Model (not Core Data)
async/await (not completion handlers)
@MainActor (on all Observable classes)
.glassEffect() (Liquid Glass, iOS 26+)
Priorités des outils MCP
Build: build_sim (not xcodebuild via Bash)
Test: test_sim (not xcodebuild test via Bash)
Sim: list_sims/boot_sim (not xcrun simctl via Bash)
Docs: DocumentationSearch (not WebSearch)
REPL: ExecuteSnippet (not swift via Bash)
Journal des modifications
| Date | Modifications |
|---|---|
| 2026-05-24 | Correction de la date de sortie stable de Xcode 26.5 en 2026-05-11 et épinglage du build à 17F42 d’après la page des versions d’Apple. Vérification locale lors de cette passe : xcodebuild -version a renvoyé Xcode 26.5 / Build version 17F42 ; la dernière version npm de xcodebuildmcp a renvoyé 2.5.2 avec time.modified 2026-05-12T07:40:41.737Z.13 |
| 2026-05-16 | Passage de la recommandation Xcode à 26.5+ (publié le 2026-05-11). Deux nouvelles fonctionnalités Coding Intelligence comptent pour les workflows d’agents : les messages peuvent désormais être mis en file d’attente dans l’assistant de codage, ce qui évite d’attendre une réponse avant de préparer la demande suivante, et les agents peuvent poser des questions de clarification avant de poursuivre — les deux réduisent la friction lorsque vous exécutez les agents natifs de Xcode en parallèle avec des sessions Claude Code ou Codex.13 Vérification de l’actualité de XcodeBuildMCP : v2.5.2 (2026-05-12) est la dernière version, avec AXe 1.7.0 intégré et un correctif pour un problème de validation de filtre de capture de logs ; le flux xcodebuildmcp init depuis v2.1.0+ reste le chemin d’installation recommandé. |
| 2026-04-28 | Passage de la recommandation Xcode à 26.4+ pour les workflows d’agents (26.4.1, 2026-04-16, build 17E202 est la dernière version stable, uniquement corrective). Citation des fonctionnalités Xcode 26.4 (2026-03-24, build 17E192) utiles pour les tests et la localisation écrits par des agents : pièces jointes d’images Swift Testing, gravité sur Issue.record, avertissements de crash en tests UI avec crashlogs joints (spécifiquement pour les apps XCUIApplication(bundleIdentifier:) / XCUIApplication(url:)), améliorations de l’éditeur String Catalog. Ajout de l’installateur automatique xcodebuildmcp init (v2.1.0+, 2026-02-23) comme alternative à la configuration manuelle de MCP. |
| 2026-04-27 | App Store Connect : soumissions Xcode 26+ obligatoires à partir du 2026-04-28. Foundation Models a ajouté les APIs SystemLanguageModel.contextSize et tokenCount(for:) (rétro-déployés vers iOS 26.4) — ajout d’un modèle pour du code de budget de prompts FM généré par agent. iOS 26.4.2 (22 avril) et iOS 26.5 bêta 3 (20 avril) ont été livrés sans changements affectant la chaîne d’outils des agents. |
| 2026-04-13 | Publication initiale. 8 apps, 3 runtimes, configuration MCP, modèles CLAUDE.md, hooks, études de cas. |
Références
-
XcodeBuildMCP inclut la télémétrie Sentry par défaut. La documentation de confidentialité du projet détaille ce qui est envoyé : messages d’erreur, traces de pile et, dans certains cas, chemins de fichiers. La variable d’environnement
XCODEBUILDMCP_SENTRY_DISABLED=truedésactive entièrement cette télémétrie. ↩ -
Anthropic, « Spécification Model Context Protocol », modelcontextprotocol.io/specification. La spécification MCP définit le transport JSON-RPC, la découverte d’outils et le protocole de ressources qu’implémentent à la fois XcodeBuildMCP et le MCP Xcode d’Apple. ↩
-
XcodeBuildMCP, github.com/getsentry/XcodeBuildMCP. Open source, maintenu par Sentry. 59 outils couvrant les workflows de simulateur, d’appareil, de débogage et d’automatisation UI. Versionnement sémantique avec journaux de modifications. ↩
-
Apple a introduit le serveur Xcode MCP dans le cadre de l’initiative d’outils développeur intelligents de Xcode 26.3, en positionnant MCP comme couche d’interface entre les assistants de codage IA et la chaîne d’outils Xcode. Consultez les notes de version Xcode pour la documentation officielle. ↩
-
Rudrank Riyam, « Explorer Xcode avec les outils MCP », rudrank.com/exploring-xcode-using-mcp-tools-cursor-external-clients, 2026. Confirmation indépendante du nombre d’outils MCP d’Apple, de la dépendance XPC et des capacités de recherche dans la documentation. ↩
-
Jimenez, C.E., Yang, J., Wettig, A., et al., « SWE-bench : les modèles de langage peuvent-ils résoudre de vrais problèmes GitHub ? » ICLR 2024. arxiv.org/abs/2310.06770. Les agents disposant d’un accès structuré aux outils ont nettement surpassé les agents limités à des commandes shell non structurées. Ce résultat valide les interfaces MCP structurées pour l’efficacité des agents. ↩
-
Documentation Claude Code CLI, code.claude.com. Système de hooks, configuration MCP, délégation à des sous-agents et définitions d’agents. ↩
-
SwiftFormat, github.com/nicklockwood/SwiftFormat. L’outil de formatage Swift utilisé dans les hooks PostToolUse pour un style de code cohérent. ↩
-
Site officiel XcodeBuildMCP, xcodebuildmcp.com. Confirme 59 outils MCP via un exemple de sortie CLI. Catégories d’outils : simulateur, appareil, débogage et automatisation UI. Installation via Homebrew ou npx. ↩
-
Swiftjective-C, « Codage agentique dans Xcode 26.3 avec Claude Code et Codex », swiftjectivec.com, février 2026. Confirme que Xcode 26.3 est livré avec l’Agent Claude natif et la prise en charge du runtime Codex via Settings > Intelligence. 20 outils MCP exposés via
xcrun mcpbridge. ↩ -
Blake Crosley, « Deux serveurs MCP ont transformé Claude Code en système de build iOS », blakecrosley.com/blog/xcode-mcp-claude-code, février 2026. Guide de configuration et résultats réels issus du workflow de développement iOS du même auteur. ↩
-
Apple Developer News, « Exigences à venir ». Entrée du 2026-04-28 : « Apps uploaded to App Store Connect must be built with Xcode 26 or later using an SDK for iOS 26, iPadOS 26, tvOS 26, visionOS 26, or watchOS 26. » macOS ne figure pas dans l’ensemble de plateformes listé pour cette exigence. ↩
-
Apple, « Notes de version Xcode 26.5 » et « Xcode 26.5 (17F42) - Versions ». Xcode 26.5 a été listé par Apple le 2026-05-11 avec le build 17F42. Deux fonctionnalités Coding Intelligence citées depuis les notes de version : les messages peuvent être mis en file d’attente dans l’assistant de codage sans attendre la fin de la réponse en cours (174563016), et les agents peuvent poser des questions de clarification pour recueillir du contexte avant de poursuivre (175182375). Inclut aussi la prise en charge StoreKit Testing des abonnements mensuels avec engagement de 12 mois (modèle
PricingTerms,billingPlanTypePurchaseOption,CommitmentInfosurTransactionetSubscriptionRenewalInfo) et un correctif du débogueur Swift pour l’exécution pas à pas dans des Swift Tasks qui migrent entre threads pendant des opérations async/await. Vérification de la session en cours le 2026-05-24 :xcodebuild -versiona renvoyéXcode 26.5etBuild version 17F42;npm view xcodebuildmcp version dist-tags.latest time.modified --jsona renvoyé la dernière version2.5.2avectime.modified2026-05-12T07:40:41.737Z. Voir aussi : 9to5Mac, « Xcode 26.5 ajoute deux fonctionnalités qui rendent le codage agentique plus utile », 2026-05-12. ↩↩↩ -
Apple, « Notes de version Xcode 26.4 ». Xcode 26.4 (2026-03-24, build 17E192). Fonctionnalités citées depuis les notes de version : Swift Testing prend désormais en charge les pièces jointes d’images via
CGImage,NSImage,UIImageetCIImage;Issue.recordaccepte des niveaux de gravité ; certains crashs d’apps en tests UI — spécifiquement les apps manipulées viaXCUIApplication(bundleIdentifier:)ouXCUIApplication(url:)— sont signalés comme avertissements avec crashlogs joints plutôt que de faire échouer le test ; l’éditeur String Catalog ajoute le couper/copier/coller d’entrées, la suppression de langues et le préremplissage de traductions depuis une langue existante, ainsi que le paramètreBUILD_ONLY_KNOWN_LOCALIZATIONS. ↩ -
Apple Developer News, « Xcode 26.4.1 (Build 17E202) désormais disponible », 2026-04-16. Version corrective mineure uniquement — corrige un crash MetricKit dû à des symboles manquants sur iOS / macOS / visionOS pré-26.4, et un bug d’allocation de pile Swift async (« freed pointer was not the last allocation » dans
swift_asyncLet_finish). ↩ -
getsentry/XcodeBuildMCP version v2.1.0, 2026-02-23. Ajout de la commande CLI
xcodebuildmcp initpour installer en une seule étape les compétences d’agent + la configuration MCP, en remplacement du script autonomeinstall-skill.sh. Détecte automatiquement Claude Code, Cursor et Codex ; prend en charge--print(écriture de la configuration vers stdout pour les clients non pris en charge) et--uninstall(suppression). ↩ -
InfoQ, « Apple ajoute la gestion de fenêtre de contexte à Foundation Models », mars 2026. Documente les nouveaux APIs
SystemLanguageModel.contextSizeettokenCount(for:)et confirme les annotations@backDeployed(before: iOS 26.4). Remplace l’ancienne estimation communautaire d’un codage en dur à 4096 tokens. ↩ -
Nombre de fichiers dérivé de
find . -name '*.swift' -not -path '*/Tests/*' | wc -l, exécuté sur chacun des huit dépôts d’apps privés le 2026-04-27. Fichiers de test exclus. Le total est cohérent en interne avec le tableau de ventilation par app dans §The Portfolio. ↩ -
Estimation subjective du temps écoulé, pas une mesure face à un groupe témoin. Le chiffre 3-5x correspond au souvenir de l’auteur concernant des comparaisons de délai jusqu’à fonctionnalité entre des fonctionnalités assistées par agent en 2026 et des fonctionnalités solo équivalentes livrées dans les mêmes bases de code avant le workflow d’agents. Traitez-le comme une heuristique de ce à quoi vous attendre après la configuration MCP + hooks, pas comme un benchmark. ↩