Le symptôme : le même commit Flutter réussissait avant la mise à niveau, puis Flutter 3.47 et Xcode 27 font échouer la construction iOS.

La solution la plus rapide : passez d’abord au dernier correctif stable de la branche Flutter 3.47, reproduisez la résolution et l’Archive avec le même commit, puis contrôlez Swift Package Manager et les plugins avant tout nettoyage destructif.

Qui doit suivre cette procédure ?

Ce guide s’adresse à l’indépendant qui vient de mettre à niveau Flutter 3.47 et ne peut plus construire ou archiver son application iOS.

Il concerne aussi les petites équipes qui utilisent Xcode 27, un Mac distant ou une chaîne sans surveillance, ainsi que les projets iOS Add-to-App mêlant Swift Package Manager et CocoaPods.

Dernière mise à jour : 16 septembre 2026. Les éléments de version et de compatibilité ont été vérifiés dans le changelog officiel de Flutter, les informations de publication de Xcode 27 et les notes de version Xcode d’Apple.

Première étape : conserver la panne avant de la corriger

Ne commencez pas par supprimer Pods, réinitialiser le cache des packages ou recréer votre machine de compilation. Ces opérations peuvent effacer l’indice qui permet de distinguer une régression Flutter d’un changement d’environnement.

Conservez une copie désensibilisée des éléments suivants :

  • la version exacte de Flutter, y compris son correctif ;
  • la version de Xcode et le chemin réellement utilisé par la tâche ;
  • le commit, le fichier de verrouillage et les plugins installés ;
  • la commande qui échoue ;
  • le premier message d’erreur exploitable, et non la dernière ligne générique ;
  • le résultat de la résolution des dépendances ;
  • le résultat d’un Build ordinaire ;
  • le résultat d’une Archive Release.

Cette séparation est importante. Une résolution Swift Package Manager peut échouer avant Xcode. Un Build peut ensuite échouer à cause d’une cible ou d’un plugin. Une Archive peut enfin révéler un problème de configuration de distribution qui n’apparaît jamais en Debug.

Le cas concret à reconstituer

Imaginez un journal anonymisé dans lequel le commit a1b2c3d construit correctement avant la mise à niveau. Après le passage à Flutter 3.47 et Xcode 27, la résolution des packages ou la construction d’un package Flutter Swift échoue. Le projet n’a pas changé, mais l’environnement, lui, a changé.

Votre première question n’est donc pas « quel cache faut-il supprimer ? ». Elle est : « à quelle étape le premier écart apparaît-il, avec quelles versions exactes ? »

Cette méthode évite de confondre trois causes :

  • la correction Flutter manquante ;
  • une intégration Swift Package Manager incomplète ;
  • un problème propre au Mac distant, à la session ou à l’outil sélectionné.

Deuxième étape : vérifier le correctif Flutter avant de modifier le projet

Le changelog de Flutter indique que des corrections liées à l’activation de Swift Package Manager et aux constructions iOS ou macOS ont été intégrées dans Flutter 3.47.2. Il mentionne également l’échec de construction de packages Flutter Swift dans des projets iOS Add-to-App avec Xcode 27, ainsi que des changements poursuivis dans Flutter 3.47.3. Consultez directement le changelog Flutter correspondant aux correctifs 3.47 avant de tirer une conclusion générale sur Flutter 3.47.

Xcode 27 a été officiellement publié le 14 septembre 2026, selon les informations de version d’Apple. Cette date ne prouve pas que votre erreur vient de Xcode. Elle indique seulement pourquoi il faut documenter séparément le changement Flutter et le changement Xcode.

Procédez dans cet ordre :

  • créez une branche de maintenance ou une copie réversible ;
  • installez le dernier correctif stable disponible de la branche Flutter 3.47 ;
  • laissez le code source, les plugins et les commandes inchangés ;
  • relancez la résolution des dépendances ;
  • relancez un Build ;
  • conservez le journal avant de passer à l’Archive.

Si le même commit fonctionne après le correctif, vous avez un indice fort en faveur d’une régression déjà identifiée. Si l’échec reste identique, ne concluez pas encore à une incompatibilité générale : passez à l’intégration et aux plugins.

Ce qu’il ne faut pas faire à ce stade

Ne mélangez pas une mise à niveau de Flutter avec une modification du Podfile, un changement de version minimale d’iOS et une nouvelle version de plugin. Vous pourriez obtenir un résultat différent, mais vous ne sauriez plus quelle modification a résolu le problème.

Ne considérez pas non plus Flutter 3.47.0, 3.47.1, 3.47.2 et les correctifs suivants comme une seule version fonctionnelle. Pour ce type de panne, le correctif exact fait partie du diagnostic.

Troisième étape : contrôler l’intégration Swift Package Manager selon le projet

Flutter documente une intégration Swift Package Manager différente selon la structure du projet. Consultez le guide officiel d’intégration Swift Package Manager pour les applications Flutter et comparez-le à votre dépôt.

Dans une application Flutter classique, cherchez les éléments générés et les scripts attendus par l’outil. Dans un projet iOS Add-to-App, la cible hôte et les packages Flutter Swift peuvent suivre un autre chemin. Une cible personnalisée peut encore modifier les dépendances, les scripts ou les phases de construction.

Vérifiez notamment :

  • la présence de FlutterGeneratedPluginSwiftPackage lorsqu’elle est attendue ;
  • l’appartenance du package à la bonne cible ;
  • les phases exécutées avant la construction ;
  • les chemins utilisés par les scripts générés ;
  • l’absence d’une intégration partiellement supprimée ;
  • la cohérence entre le projet ouvert dans Xcode et la commande automatisée.

Le nom d’un package présent dans le projet ne suffit pas. Il faut démontrer qu’il est résolu, attaché à la cible correcte et utilisé par le même chemin de construction que votre tâche de publication.

Pourquoi Xcode 27 ne doit pas être traité comme un simple détail

Les notes de version Xcode d’Apple permettent de vérifier les changements de l’outil et les restrictions connues. Les nouveautés de Xcode 27 donnent également le contexte nécessaire pour distinguer une erreur propre à Xcode d’une intégration Flutter incomplète.

Votre test doit rester contrôlé :

  1. ouvrez ou générez le projet avec le même commit ;
  2. sélectionnez explicitement le Xcode prévu ;
  3. résolvez les packages ;
  4. construisez la cible concernée ;
  5. archivez ensuite avec la configuration Release.

Un projet Add-to-App qui échoue n’est pas automatiquement représentatif d’une application Flutter classique. Cette distinction doit apparaître dans le rapport de panne.

Quatrième étape : isoler les plugins et choisir un repli réversible

Après la vérification du correctif et de l’intégration, examinez chaque plugin qui introduit du code natif. La question est moins « Swift Package Manager ou CocoaPods est-il meilleur ? » que « quel chemin ce plugin utilise-t-il réellement dans ce projet ? »

Un plugin peut :

  • prendre en charge Swift Package Manager ;
  • continuer à exiger CocoaPods ;
  • utiliser une dépendance native privée ;
  • imposer une version minimale d’iOS ;
  • modifier les phases de construction ;
  • fonctionner en Build mais échouer pendant l’Archive.

Consignez ces faits plugin par plugin. Ne supprimez pas globalement la configuration CocoaPods si un composant en dépend encore. À l’inverse, ne gardez pas une chaîne CocoaPods par habitude si le problème vient d’une intégration Swift Package Manager incomplète que le correctif Flutter résout.

Le repli vers CocoaPods est justifié seulement lorsque vous disposez d’une preuve :

  • le plugin n’est pas compatible avec Swift Package Manager ;
  • la dépendance native ne peut pas être résolue par le chemin Swift ;
  • l’équipe accepte de maintenir temporairement cette variante ;
  • le retour peut être annulé sans perdre la configuration précédente.

Créez alors une modification isolée et documentée. Conservez le fichier de verrouillage correspondant. Testez de nouveau la résolution, le Build et l’Archive. Si vous obtenez un succès, vous avez une solution de continuité, pas nécessairement la correction définitive.

Le dépôt officiel de Swift Package Manager peut aider à comprendre le fonctionnement du gestionnaire, mais il ne remplace pas la documentation Flutter sur la manière dont les packages sont générés et reliés à une application.

Cinquième étape : transformer un Build réussi en preuve de publication

Un Build Debug réussi ne rétablit pas votre chaîne de livraison. Vous devez exécuter les étapes dans l’ordre où elles seront utilisées en production :

  • résolution des dépendances ;
  • construction Release ;
  • création de l’Archive ;
  • export avec le format prévu ;
  • vérification des artefacts ;
  • téléversement de test ou publication selon votre processus ;
  • conservation des journaux.

Séparez bien la construction, l’Archive, la signature et le téléversement. Une Archive correcte peut encore être exportée avec une mauvaise option. Un export correct peut encore échouer dans la session automatisée. Une tâche locale peut fonctionner parce qu’elle utilise un trousseau ou une autorisation déjà présente dans la session graphique.

À ce stade, ne revenez pas automatiquement sur la gestion des certificats. Le sujet de cet article est la régression de construction Flutter, Swift Package Manager et Xcode 27. Si le journal montre une erreur de certificat ou de trousseau, ouvrez une branche de diagnostic distincte et ne mélangez pas les conclusions.

Checklist de validation avant de déclarer la panne résolue

  • [ ] Le commit testé est identique avant et après la mise à niveau.
  • [ ] La version exacte de Flutter et son correctif sont consignés.
  • [ ] La version de Xcode sélectionnée par l’interface et par la tâche est identique.
  • [ ] La résolution Swift Package Manager a été testée séparément.
  • [ ] Le type de projet est identifié : application Flutter, Add-to-App ou cible personnalisée.
  • [ ] Les plugins natifs et leur gestionnaire de dépendances sont listés.
  • [ ] Toute modification du Podfile est isolée et réversible.
  • [ ] Le Build Debug ne constitue pas l’unique preuve de succès.
  • [ ] Une construction Release et une Archive ont réussi.
  • [ ] L’export de l’Archive a été vérifié.
  • [ ] Le même flux a été lancé dans la session distante réellement utilisée.
  • [ ] Une déconnexion puis une reconnexion n’ont pas modifié le résultat.
  • [ ] Un redémarrage du Mac a été suivi d’une nouvelle résolution et d’une nouvelle Archive.
  • [ ] Flutter, Xcode, les dépendances et la commande de publication sont verrouillés dans la documentation de l’équipe.

Questions fréquentes sur Flutter 3.47, SwiftPM et Xcode 27

Les réponses détaillées sont regroupées dans le bloc FAQ associé à cette page. Retenez surtout la règle de séquencement : corriger la version, prouver l’intégration, isoler les plugins, puis valider l’Archive. Une suppression massive de caches ne remplace aucune de ces preuves.

Sixième étape : stabiliser la chaîne distante pendant la première semaine

Après le premier succès, ne basculez pas immédiatement toute la production. Gardez une petite tâche de régression qui exécute la résolution, le Build et l’Archive sur un commit connu.

Documentez :

  • la version Flutter retenue ;
  • la version Xcode retenue ;
  • le fichier de verrouillage ;
  • le gestionnaire utilisé par chaque plugin ;
  • la commande de construction ;
  • le répertoire de travail ;
  • les conditions d’accès au trousseau ;
  • les journaux attendus à chaque étape.

Pour un Mac distant, comparez ensuite le lancement graphique, SSH et votre tâche automatisée. Une divergence entre ces modes peut venir de PATH, d’un Xcode sélectionné différemment, de droits sur le répertoire, d’un cache appartenant à un autre utilisateur ou d’une session non ouverte.

Le guide Flutter consacré à Add-to-App est utile si votre projet embarque Flutter dans une application iOS existante. Il faut toutefois adapter la validation à la cible réellement archivée, et non à un exemple d’application vierge.

Si vous devez conserver une ancienne et une nouvelle chaîne, un environnement Mac distant documenté peut servir de sas de validation. Vous pouvez examiner les solutions de Mac cloud disponibles en français ou comparer un environnement destiné à la compilation distante dans la commande d’un Mac mini cloud. L’objectif n’est pas de déplacer une panne non comprise : c’est de reproduire le même commit dans un environnement contrôlé.

Tableau de décision pour le prochain essai

Observation après le correctif Flutter Interprétation prudente Action suivante
La résolution et le Build réussissent avec le même commit Le problème peut correspondre à une correction de Flutter 3.47 Poursuivre avec Release et Archive
La résolution échoue encore avant Xcode Build L’intégration Swift Package Manager ou une source de package reste suspecte Vérifier package généré, cible, scripts et accès
Une application Flutter classique réussit, mais Add-to-App échoue Le chemin d’intégration n’est pas équivalent Comparer les cibles et suivre la documentation Add-to-App
Un plugin échoue après la résolution Une dépendance native ou son gestionnaire peut être incompatible Isoler le plugin, puis envisager un repli CocoaPods
Le local réussit et le Mac distant échoue L’environnement d’exécution diffère probablement Comparer Xcode, session, droits, chemins et caches
Build réussi mais Archive échouée La chaîne de publication n’est pas rétablie Examiner Release, export et réglages propres à l’Archive

Tableau de séparation des environnements

Élément à comparer Poste local Mac distant ou tâche automatisée Preuve à conserver
Flutter Version et correctif affichés Version réellement appelée par le script Sortie de version désensibilisée
Xcode Sélection graphique Chemin sélectionné par la tâche Version et chemin utilisés
Dépendances Cache de l’utilisateur Cache et droits du compte d’exécution Journal de résolution
Projet Répertoire ouvert dans Xcode Répertoire de travail du script Commit et chemin anonymisé
Session Trousseau et autorisations disponibles Session éventuellement absente Mode de lancement et résultat
Archive Export manuel possible Export sans interaction Archive, export et journaux

Tableau d’acceptation de la chaîne Flutter iOS

Niveau de preuve Résultat attendu Décision
Résolution Packages cohérents et verrouillés Continuer uniquement si le journal est conservé
Build Cible construite avec la configuration prévue Ne pas conclure à la publication
Release Construction reproductible hors Debug Préparer l’Archive
Archive Archive créée avec le même commit Examiner l’export
Export Artefact conforme au flux choisi Tester le téléversement
Reconnexion Même résultat après nouvelle session Envisager l’usage distant régulier
Redémarrage Même résultat après redémarrage du Mac Documenter l’environnement comme récupérable

Le poste actuel peut rester pratique pour l’édition, les tests rapides ou les usages audio, vidéo et design qui dépendent de vos périphériques locaux. Il devient moins adapté lorsque vous devez conserver deux chaînes Flutter et Xcode, laisser une Archive s’exécuter sans surveillance ou reprendre une publication après une coupure.

À l’inverse, un Mac distant ne corrige pas un plugin incompatible et ne remplace pas la documentation de vos dépendances. Il ajoute une couche d’accès, de session et de reprise qu’il faut valider. Pour un indépendant sous Windows ou Linux, ou pour une équipe qui doit garder un environnement de publication disponible, la location d’un Mac avec MACCOME peut néanmoins éviter l’achat d’une machine réservée au seul archivage. Vous pouvez commencer par un environnement de test, y rejouer le commit corrigé et ne le conserver que si l’Archive, la reconnexion et le redémarrage répondent à vos critères.

La décision raisonnable est donc conditionnelle : gardez votre poste actuel si vous maîtrisez déjà la chaîne et n’avez pas besoin d’un environnement persistant ; utilisez un Mac distant si l’absence de macOS, la coexistence de versions ou la continuité du packaging bloque vos livraisons. Dans les deux cas, la preuve finale reste la même : une Archive Release reproductible, exportable et vérifiée après la correction de Flutter 3.47.