Compétence Expert SwiftUI
Règles de fonctionnement
- Traiter chaque type
Viewcomme une frontière d'invalidation : ne lui donner que les données qu'elle lit et maintenir les dépendances qui changent fréquemment proches de la plus petite sous-arborescence affectée. - Rechercher
references/latest-apis.mdlors de l'écriture, de la révision ou de la migration d'API ; ne consulter que les API pertinentes pour la tâche. - Remplacer les API définitivement dépréciées par des équivalents modernes. Pendant le développement de fonctionnalités, signaler les API mollement dépréciées sans les modifier (voir
references/soft-deprecation.md). - Privilégier les API SwiftUI natives à l'interfaçage UIKit/AppKit, sauf si l'interfaçage est nécessaire.
- Se concentrer sur la correction et les performances ; ne pas imposer d'architectures spécifiques (MVVM, VIPER, etc.).
- Encourager la séparation de la logique métier des vues pour la testabilité sans imposer de méthode.
- Suivre les directives d'interface humaine d'Apple et les patrons de conception d'API.
- N'adopter Liquid Glass que lorsque l'utilisateur le demande explicitement (voir
references/liquid-glass.md). - Présenter les optimisations de performance comme des suggestions, pas des exigences.
- Utiliser le filtrage
#availableavec des solutions de repli pertinentes pour les API spécifiques à une version. - Pour les entrées de mise en page et de rendu, lire la valeur la plus proche de la vue SwiftUI qui la consomme ; ne pas substituer l'état d'écran global du processus.
Flux de travail pour les tâches
Réviser du code SwiftUI existant
- Lire le code en cours de révision et identifier les sujets applicables.
- Signaler les API dépréciées (comparer avec
references/latest-apis.md) ; remplacer les API définitivement dépréciées, et signaler les API mollement dépréciées sans les réécrire sauf si l'utilisateur a demandé une migration. - Exécuter le routeur thématique ci-dessous pour chaque sujet pertinent.
- Valider le filtrage
#availableet les chemins de repli pour les fonctionnalités spécifiques à une version. - Pour les révisions de code à grande échelle, identifier d'abord des zones d'intérêt plus petites et les présenter une par une ; si l'utilisateur demande une révision de l'ensemble du code, diviser cela en une liste de tâches.
Améliorer du code SwiftUI existant
- Auditer l'implémentation actuelle par rapport aux sujets du routeur thématique.
- Remplacer les API définitivement dépréciées par des équivalents modernes de
references/latest-apis.md; signaler les API mollement dépréciées sans les réécrire pendant le développement de fonctionnalités. - Refactoriser les chemins chauds pour réduire les mises à jour d'état inutiles.
- Extraire les corps de vues complexes en sous-vues séparées.
- Suggérer le sous-échantillonnage d'image lorsque
UIImage(data:)est rencontré (optimisation optionnelle, voirreferences/image-optimization.md).
Implémenter une nouvelle fonctionnalité SwiftUI
- Concevoir d'abord le flux de données : identifier l'état possédé par rapport à l'état injecté.
- Structurer les vues pour un diffing optimal (extraire les sous-vues tôt).
- Appliquer les patrons d'animation corrects (implicite vs explicite, transitions).
- Utiliser
Buttonpour tous les éléments cliquables ; ajouter un groupement d'accessibilité et des labels. - Filtrer les API spécifiques à une version avec
#availableet fournir des solutions de repli.
Enregistrer une nouvelle trace Instruments
Déclencher lorsque l'utilisateur demande "d'enregistrer une trace", "de profiler l'application", "de capturer une session", etc. Référence complète : references/trace-recording.md.
- Confirmer la cible — attacher à une application en cours d'exécution, lancer une application, ou enregistrer tous les processus ? Si l'utilisateur n'a pas précisé, demander. Lister les appareils connectés si utile :
python3 "${SKILL_DIR}/scripts/record_trace.py" --list-devices - Choisir un modèle en fonction du type de cible — Le modèle
SwiftUIremplit la voie SwiftUI sur tout appareil réel : un appareil iOS/iPadOS physique ou le Mac hôte. La seule exception est le simulateur iOS, où la voie SwiftUI revient vide — dans ce cas, utiliser--template "Time Profiler"(donne le profileur temporel + blocages, mais pas d'accrocs d'animation). Toujours vérifier--list-devices: typesimulators→Time Profiler; typedevices(appareils réels et le Mac hôte) → par défautSwiftUI. Table de décision complète dansreferences/trace-recording.md. - Démarrer l'enregistrement. Pour les sessions pilotées par agent où l'utilisateur dit "Je te dirai quand j'aurai fini", démarrer en arrière-plan et utiliser un fichier d'arrêt :
Pour les sessions interactives, simplement dire à l'utilisateur d'appuyer sur Ctrl+C quand il a terminé.python3 "${SKILL_DIR}/scripts/record_trace.py" \ --device "<nom|udid>" --attach "<NomApp>" \ --stop-file /tmp/stop-trace --output ~/Desktop/session.trace - Signaler l'arrêt — lorsque l'utilisateur dit qu'il a fini d'exercer l'application,
touch /tmp/stop-trace. Le script envoie proprement un SIGINT à xctrace et attend jusqu'à 60s la finalisation. - Analyser la trace résultante (passer au flux de travail "Amélioration basée sur les traces" ci-dessous).
Amélioration basée sur les traces (fourniture d'un fichier .trace Instruments)
Déclencher chaque fois que la requête de l'utilisateur fait référence à un fichier .trace. Un fichier source SwiftUI cible est optionnel — s'il est donné, citer des lignes spécifiques ; sinon, recommander où chercher en fonction des noms de vues et des symboles que la trace révèle déjà.
Référence complète : references/trace-analysis.md.
Blocages : si xctrace help liste triage (Xcode 27.2 le fait), commencer par xctrace triage <trace> --style hangs, puis approfondir avec xctrace show. L'analyseur fourni reste l'outil pour les accrocs, les mises à jour SwiftUI, le graphe des causes et les fenêtres de logs ou signposts.
Résumé du modèle de composition de l'analyseur :
- Délimiter l'analyse. Se demander : l'utilisateur veut-il la trace entière, ou une partie ?
- "concentrer sur X / après X / entre X et Y / pendant X" → résoudre d'abord une fenêtre (voir étape 2).
- Aucune indication de délimitation → analyser la trace entière.
- Résoudre une fenêtre (uniquement si l'utilisateur a délimité). L'analyseur expose deux modes de découverte :
Les deux modes acceptent# Trouver un log qui marque le début/fin de la région d'intérêt : python3 "${SKILL_DIR}/scripts/analyze_trace.py" --trace <chemin> \ --list-logs --log-message-contains "flux chargé" --log-limit 5 # Ou lister les intervalles os_signpost (début/fin appariés), filtrables par nom : python3 "${SKILL_DIR}/scripts/analyze_trace.py" --trace <chemin> \ --list-signposts --signpost-name-contains "ImageDecode"--window START_MS:END_MSpour délimiter la découverte. Choisir letime_ms(pour les logs) oustart_ms/end_ms(pour les signposts) qui correspondent à la description de l'utilisateur. Construire une fenêtre comme--window 10400:11700. - Lancer l'analyse principale (avec ou sans
--window) :python3 "${SKILL_DIR}/scripts/analyze_trace.py" --trace <chemin> \ --json-only --top 10 [--window START_MS:END_MS] - Interpréter avec
references/trace-analysis.md— diagnostics clés :main_running_coverage_pctdans chaque corrélation (<25 % = bloqué ; ≥75 % = lié au CPU).swiftui-causes.top_sourcesrévèle pourquoi les mises à jour continuent — les sources à haut nombre d'arêtes commeUserDefaultObserver.send()ou les entréesEnvironmentWriterlarges sont des bugs d'invalidation structurelle. En corriger un effondre souvent plusieurs vues chaudes en aval.
- Lorsqu'une vue spécifique est coûteuse, demander qui l'invalide. Utiliser
--fanin-for "<nom de vue>"pour obtenir la liste classée des nœuds sources qui entraînent les mises à jour. - Optionnellement, ancrer dans le source. Si l'utilisateur a pointé un fichier, le lire et faire correspondre les noms de vues / symboles de code utilisateur avec les identifiants présents. Sinon, recommander les fichiers à ouvrir en fonction des noms de vues rapportés par SwiftUI.
- Retourner un plan priorisé. Citer des preuves (pourcentage de couverture, symbole chaud, vue superposée, horodatage de log, arêtes du graphe de causes) et router chaque recommandation vers une référence du routeur thématique.
- Ne modifier le code que si l'utilisateur a demandé des modifications.
Routeur thématique
Consulter le fichier de référence pour chaque sujet pertinent à la tâche en cours :
| Sujet | Référence |
|---|---|
| Gestion d'état | references/state-management.md |
Environnement et @Entry, y compris les avertissements "Storing a closure/class type in '@Entry var'" | references/environment-patterns.md |
| Composition de vues | references/view-structure.md |
| Modificateurs de vue et identité | references/modifier-patterns.md |
| Performances | references/performance-patterns.md |
| Listes et ForEach | references/list-patterns.md |
| Mise en page redimensionnable, zones de sécurité, réorganisation sur deux colonnes, grilles pliables, arrangements et régions réservées | references/layout-best-practices.md |
| Écrans iPhone Duo, pliables ou grand écran (lire en premier pour choisir la technique) | references/iphone-duo.md |
Feuilles, navigation, NavigationSplitView sur grand écran, et barre d'onglets/barre latérale (sidebarAdaptable) | references/sheet-navigation-patterns.md |
| ScrollView, position de défilement et géométrie de défilement | references/scroll-patterns.md |
| Gestion du focus | references/focus-patterns.md |
| Animations (bases) | references/animation-basics.md |
| Animations (transitions) | references/animation-transitions.md |
| Animations (avancé) | references/animation-advanced.md |
| Accessibilité | references/accessibility-patterns.md |
| Swift Charts | references/charts.md |
| Accessibilité des graphiques | references/charts-accessibility.md |
| Optimisation d'image et échelle d'affichage | references/image-optimization.md |
| Barres d'outils | references/toolbar-patterns.md |
| Applications basées sur des documents | references/document-apps.md |
| WebKit | references/webkit-integration.md |
| Édition de texte stylisé | references/styled-text-editing.md |
| Liquid Glass (iOS 26+) | references/liquid-glass.md |
| Scènes macOS | references/macos-scenes.md |
| Style de fenêtre macOS | references/macos-window-styling.md |
| Vues macOS | references/macos-views.md |
| Patrons de texte | references/text-patterns.md |
| Localisation | references/localization.md |
| Recherche d'API dépréciée | references/latest-apis.md |
| Gestion des API mollement dépréciées | references/soft-deprecation.md |
| Aperçus | references/previews.md |
| Analyse de trace Instruments | references/trace-analysis.md |
| Enregistrement de trace Instruments | references/trace-recording.md |
Checklist d'exactitude
Ce sont des règles strictes — leur violation est toujours un bug :
- Les propriétés
@Statesontprivate -
@Bindinguniquement là où un enfant modifie l'état du parent - Les entrées modifiables appartenant au parent ne sont pas stockées comme
@State/@StateObject; les graines d'état intentionnelles sont documentées comme ponctuelles -
@StateObjectpour les objets appartenant à la vue ;@ObservedObjectpour les objets injectés - iOS 17+ :
@Stateavec@Observable;@Bindablepour les observables injectés nécessitant des liaisons -
ForEachutilise une identité stable (jamais.indices/\.offset; l'identité survit à la vue et n'est pas dérivée d'un contenu mutable) - Nombre constant de vues par élément
ForEach; les lignesListsont unaire - Aucune fermeture stockée dans les clés
@Environment/@FocusedValuepersonnalisées - Les valeurs par défaut de
@Entrypersonnalisées sont stables (pas d'expressionsModel()/Date()/UUID()) - L'échelle d'affichage SwiftUI provient de
@Environment(\.displayScale), pas de l'état d'écran global - Les contenus de zone de sécurité n'appliquent pas deux fois
GeometryProxy.safeAreaInsets -
.animation(_:value:)inclut toujours le paramètrevalue - Les propriétés
@FocusStatesontprivate - Pas d'écritures redondantes
@FocusStatedans les gestionnaires de tap sur les vues.focusable() - Les API spécifiques à une version sont filtrées avec
#availableet ont des solutions de repli pertinentes -
import Chartsprésent dans les fichiers utilisant des types de graphiques - Les aperçus utilisent des données mock auto-contenues ; aucune dépendance aux services en direct ou au réseau