Depuis Flutter 3.44, Swift Package Manager est utilisé par défaut pour les dépendances natives iOS et macOS, tandis que les dépendances incompatibles peuvent encore revenir à CocoaPods selon la documentation officielle de Flutter (migration vers Swift Package Manager). La conséquence est simple : pour une migration des dépendances iOS de Flutter 3.47, ne supprimez pas immédiatement votre configuration CocoaPods. Activez SwiftPM, conservez une voie CocoaPods pour les plugins non compatibles, puis ne modifiez la chaîne de production qu’après un Archive et une installation TestFlight réussis dans un environnement Mac isolé.
Dernière mise à jour : 17 septembre 2026. Les informations ont été vérifiées à partir des documents Flutter sur SwiftPM, du guide de publication iOS et des règles Apple relatives aux téléversements App Store Connect.
Cet article s’adresse aux développeurs indépendants qui passent d’une ancienne version de Flutter à 3.47 sans pouvoir interrompre leurs livraisons iOS, aux projets utilisant plusieurs plugins natifs dont la compatibilité SwiftPM reste incertaine, ainsi qu’aux petites équipes qui codent sous Windows ou Linux mais doivent construire et publier depuis un Mac.
Pourquoi préparer une migration à double voie
Le changement de gestionnaire ne concerne pas seulement le fichier de dépendances. Flutter peut régénérer ou modifier des éléments du projet iOS lors de la mise à niveau, de la récupération des paquets et de l’ouverture du projet dans Xcode. Cette évolution peut toucher l’enregistrement des plugins, la résolution des paquets, les réglages de construction et les scripts d’intégration.
La première erreur consiste à interpréter une compilation Debug réussie comme une preuve de compatibilité complète. Un plugin peut compiler dans le simulateur tout en échouant pendant un Archive signé, ou fonctionner jusqu’à l’installation TestFlight avant de révéler un problème de module, de version minimale d’iOS ou de ressource native.
La seconde erreur consiste à retirer CocoaPods avant d’avoir classé les plugins. La documentation Flutter prévoit encore un mécanisme de retour pour les dépendances qui ne prennent pas en charge SwiftPM. La compatibilité doit donc être vérifiée plugin par plugin, et non déduite de la version globale du projet.
| Élément à comparer | Swift Package Manager | CocoaPods conservé en secours |
|---|---|---|
| Rôle pendant la migration | Voie par défaut pour les dépendances compatibles | Voie de repli pour les plugins non compatibles |
| Risque principal | Paquet non résolu, module absent ou réglage natif incomplet | Configuration historique, Podfile personnalisé ou dépendance obsolète |
| Niveau de confiance après Debug | Insuffisant pour autoriser la production | Insuffisant également sans Archive signé |
| Décision recommandée | Étendre progressivement après vérification | Garder tant qu’un plugin ou un script l’exige |
| Note éditoriale pour une migration contrôlée | 4/5 | 4/5 comme mécanisme de continuité |
Le projet doit aussi être traité comme un actif publiable. Avant toute modification, vous devez pouvoir répondre à trois questions : quelle version de Flutter produisait le dernier binaire accepté, quelle configuration signait ce binaire, et comment revenir à cette configuration sans dépendre d’un état Xcode non documenté ?
Première étape : établir la base qui peut encore publier
Créez une branche dédiée ou copiez le projet dans un répertoire de migration. Ne travaillez pas directement sur l’unique Mac qui produit les versions destinées aux utilisateurs. Cette séparation est particulièrement importante lorsque le Mac est utilisé à distance : une session interrompue ou une mise à jour de l’environnement ne doit pas détruire votre seul chemin de publication.
Conservez les éléments suivants dans un dossier de preuve, sans y placer de secret :
- la sortie de
flutter --version; - le fichier
pubspec.locket les fichiers de verrouillage propres aux dépendances natives ; - le contenu du
Podfileet les éventuelles configurations personnalisées ; - la version sélectionnée dans Xcode ;
- le mode de signature utilisé ;
- le numéro de version et le numéro de build du dernier Archive réussi ;
- le journal de compilation et le résultat de l’installation TestFlight correspondante.
Remplacez dans les exemples ci-dessous les noms de projet, identifiants d’application, identifiants d’équipe et chemins par des valeurs neutres. Ne publiez jamais une clé privée, un certificat exporté ou un jeton App Store Connect dans un journal partagé.
Dans un terminal ouvert avec le compte macOS qui exécutera ensuite la construction, placez-vous dans le projet :
# Compte : compte de construction dédié
# Répertoire : /Users/build/flutter-app
# SDK Flutter : /opt/flutter
cd /Users/build/flutter-app
/opt/flutter/bin/flutter --version
/opt/flutter/bin/flutter pub get
/opt/flutter/bin/flutter doctor -v
La sortie attendue doit confirmer la version Flutter ciblée et permettre d’identifier Xcode ainsi que les outils iOS disponibles. Si flutter doctor -v signale déjà une incohérence, arrêtez la migration : corriger d’abord l’outil de base rendra les erreurs de dépendances interprétables.
| Preuve à conserver | Pourquoi elle compte | Action si elle manque |
|---|---|---|
| Dernier Archive signé | Point de comparaison pour le binaire final | Produire un Archive avant la migration |
pubspec.lock |
Reproduction des versions Dart et Flutter | Restaurer depuis le dépôt validé |
| Podfile et réglages Xcode | Détection des adaptations manuelles | Copier les fichiers dans la branche de migration |
| Méthode de signature | Évite de confondre dépendance et certificat | Documenter le compte et le trousseau utilisés |
| Résultat TestFlight | Validation réelle après traitement Apple | Conserver le build précédent comme référence |
Deuxième étape : dresser la carte des plugins natifs
La question n’est pas de savoir si votre application utilise Flutter, mais quels paquets introduisent du code iOS natif. Les plugins liés à l’audio, à la vidéo, au design, à la caméra, aux notifications, au stockage sécurisé ou aux achats intégrés méritent une vérification particulière, car ils peuvent embarquer des frameworks, des ressources ou des réglages Xcode que le seul code Dart ne montre pas.
Examinez l’arbre des dépendances :
# Compte : compte de construction dédié
# Répertoire : /Users/build/flutter-app
cd /Users/build/flutter-app
/opt/flutter/bin/flutter pub deps --style=compact
grep -R "podspec\|Package.swift\|xcframework\|framework" ios .dart_tool 2>/dev/null
Ces commandes ne constituent pas une preuve automatique de compatibilité. Elles servent à repérer les dépendances qui nécessitent une lecture du fichier du plugin, de sa documentation et des journaux Flutter. La documentation officielle de Flutter rappelle que la prise en charge de SwiftPM dépend des plugins et de leur mode d’intégration (documentation destinée aux développeurs de plugins).
Classez ensuite chaque plugin dans l’une des trois catégories :
- Compatible SwiftPM confirmé : le plugin et ses dépendances natives sont pris en charge, sans Podfile personnalisé requis.
- CocoaPods nécessaire : le plugin utilise encore une intégration qui n’est pas disponible ou pas complète avec SwiftPM.
- État à confirmer : présence d’un dépôt privé, d’un framework local, d’un script de construction ou d’une configuration écrite à la main.
Flutter 3.47 modifie automatiquement certains éléments du projet iOS : faut-il considérer cela comme une erreur ?
Non, pas automatiquement. Une mise à niveau peut appliquer les conventions nécessaires au nouveau mode de gestion des dépendances. En revanche, vous devez comparer les fichiers avant et après, puis vérifier les journaux de résolution. Une modification non documentée du Podfile, du projet Xcode ou d’un script de signature devient un risque de régression si elle n’est pas enregistrée dans votre branche de migration.
Troisième étape : activer SwiftPM sans effacer l’ancien chemin
Après avoir créé la branche de migration, mettez Flutter et les dépendances à niveau selon la procédure propre au projet. Ouvrez ensuite le projet iOS dans l’environnement attendu par Flutter, sans modifier manuellement les fichiers générés avant d’avoir observé leur état.
# Compte : compte de construction dédié
# Répertoire : /Users/build/flutter-app
# SDK Flutter : /opt/flutter
cd /Users/build/flutter-app
/opt/flutter/bin/flutter clean
/opt/flutter/bin/flutter pub get
open ios/Runner.xcworkspace
Le fichier Runner.xcworkspace est important lorsqu’une partie du projet utilise encore CocoaPods. Si votre projet est entièrement compatible SwiftPM, Xcode peut afficher une organisation différente ; ce changement doit être comparé au dépôt plutôt que corrigé instinctivement.
Commencez par une construction sans signature destinée au simulateur ou à une vérification locale :
# Compte : compte de construction dédié
# Répertoire : /Users/build/flutter-app
cd /Users/build/flutter-app
/opt/flutter/bin/flutter build ios --debug --no-codesign
Vous cherchez ici des preuves précises : résolution complète des paquets, enregistrement des plugins, compilation des modules et absence de symbole dupliqué. Si cette étape échoue, ne passez pas à la signature. Notez le premier message d’erreur, le paquet concerné et le fichier qui a changé.
Attention. Ne supprimez pas le
Podfile.lock, les réglages de pods ou la branche de production simplement parce que SwiftPM résout correctement un premier paquet. Le test doit couvrir tous les plugins natifs et une construction Release.
Un plugin Flutter ne prend pas encore en charge Swift Package Manager : quelle décision prendre ?
Conservez-le avec CocoaPods si son fonctionnement est nécessaire à l’application et si aucune alternative validée n’est disponible. Vous pouvez aussi remplacer le plugin après une analyse fonctionnelle, mais il est déconseillé de modifier directement son code source uniquement pour obtenir une migration « pure » vers SwiftPM. Une adaptation locale augmente la charge de maintenance et peut disparaître lors de la prochaine mise à jour.
Quatrième étape : gérer la coexistence sans dupliquer une bibliothèque
Flutter 3.47 peut fonctionner avec une stratégie mixte, mais SwiftPM et CocoaPods ne doivent pas importer deux fois la même bibliothèque native. La coexistence doit donc être organisée par dépendance, pas activée indistinctement pour tout le projet.
Utilisez cette grille de décision :
- Si le plugin est officiellement compatible SwiftPM et n’apparaît pas dans une configuration CocoaPods équivalente, sélectionnez SwiftPM, puis vérifiez la compilation et les ressources.
- Si le plugin dépend encore d’un pod indispensable, conservez CocoaPods pour ce plugin et documentez la raison dans la carte de compatibilité.
- Si le même framework apparaît deux fois dans les journaux ou dans les phases de liaison, revenez au dernier état connu et retirez l’un des chemins d’intégration avant de continuer.
- Si le module est introuvable, vérifiez d’abord le produit importé, le nom du module et la cible Xcode avant de changer la version minimale d’iOS.
- Si une version minimale d’iOS devient incompatible, comparez la contrainte du paquet avec celle de la cible de l’application ; ne la relevez pas uniquement pour faire disparaître l’erreur.
- Si le téléchargement d’un paquet distant échoue, conservez CocoaPods pour la dépendance concernée ou corrigez l’accès réseau, puis recommencez depuis un état propre.
Un projet Flutter peut-il utiliser SwiftPM et CocoaPods pendant la même migration ?
Oui, lorsque chaque voie prend en charge des dépendances différentes et qu’aucune bibliothèque native n’est importée deux fois. Cette solution est souvent préférable à une migration forcée : elle permet de livrer, de mesurer le risque et de traiter les plugins un par un. Elle ne dispense toutefois pas d’un Archive signé ni d’une installation TestFlight.
Les symptômes les plus utiles sont plus fiables que le nom du gestionnaire :
- « duplicate symbols » indique généralement une double intégration ;
- « module not found » oriente vers un produit, un nom de module ou une cible mal reliée ;
- une erreur de version minimale révèle une contrainte iOS incompatible ;
- un échec de téléchargement concerne la résolution ou l’accès au dépôt ;
- une fonction absente après installation TestFlight peut venir d’une ressource native non copiée, et pas seulement du code Dart.
Cinquième étape : rendre le Mac distant reproductible
Si vous développez sous Windows ou Linux, le code Dart peut rester sur votre poste principal, mais la résolution native, Xcode, la signature et l’Archive doivent être vérifiés sur macOS. Pour une migration risquée, utilisez un Mac séparé de la machine qui publie déjà.
La documentation Flutter décrit les étapes générales du déploiement iOS (guide officiel de construction et de publication). Dans votre environnement distant, fixez explicitement :
- le chemin du SDK Flutter ;
- la version de Xcode sélectionnée ;
- le compte macOS de construction ;
- les fichiers de verrouillage ;
- les variables d’environnement ;
- l’emplacement des caches SwiftPM et CocoaPods ;
- la procédure de reprise après coupure de session SSH ou VNC.
Le cache accélère une construction déjà comprise ; il ne prouve pas qu’un environnement propre saura résoudre les dépendances. Effectuez donc une vérification sans cache ou dans une copie neuve du projet, puis comparez le résultat avec l’environnement habituel.
Séparez les caches des secrets de publication. Les certificats, clés privées et identifiants App Store Connect ne doivent pas être copiés dans le même répertoire que les paquets. Après une interruption, reconnectez-vous avec le même compte de construction, contrôlez la branche Git et relancez la résolution avant de relancer la signature.
Pour une équipe qui ne possède pas de Mac de test, la configuration d’un Mac distant pour un environnement Flutter iOS peut servir à isoler la migration, à condition de traiter cette machine comme un environnement de validation et non comme un coffre-fort pour des secrets non sauvegardés. L’accès graphique peut être utile pour Xcode, tandis que SSH convient mieux aux commandes reproductibles ; les deux voies doivent produire les mêmes journaux.
Sixième étape : valider Release, Archive et TestFlight
Une compilation Debug ne clôt pas la migration. Passez d’abord en Release sans chercher à modifier simultanément la signature :
# Compte : compte de construction dédié
# Répertoire : /Users/build/flutter-app
cd /Users/build/flutter-app
/opt/flutter/bin/flutter build ios --release --no-codesign
Si la compilation Release est correcte, ouvrez Xcode, sélectionnez la cible et la configuration de distribution, puis lancez l’Archive. Vérifiez le numéro de version, le numéro de build, l’équipe de signature, les capacités activées et les extensions éventuelles. Flutter recommande de suivre son flux de publication iOS, tandis qu’Apple documente les conditions de téléversement des builds dans App Store Connect (règles Apple pour envoyer un build).
Après export de l’IPA, téléversez le build et attendez son traitement. Apple distingue plusieurs états de build ; un téléversement accepté par le transporteur n’équivaut pas encore à un build disponible pour TestFlight (états de traitement des builds App Store Connect). Installez ensuite le build sur un appareil réel et testez les fonctions liées aux plugins migrés :
- ouverture de session et notifications ;
- achats intégrés ou abonnements ;
- accès caméra, microphone ou fichiers ;
- lecture audio et vidéo ;
- génération et partage de contenus ;
- fonctionnalités de design ou de rendu propres à l’application ;
- démarrage à froid et reprise après interruption.
Comment revenir en arrière si l’Archive échoue après le passage à SwiftPM ?
Conservez l’Archive précédent, la branche de production et le verrouillage des dépendances. Revenez à la branche validée, restaurez le projet Xcode et le Podfile enregistrés, puis reconstruisez avec le même compte et le même profil de signature. Ne tentez pas de réparer une chaîne de publication unique en supprimant au hasard des caches : vous risqueriez de masquer la cause et de perdre le point de comparaison.
Le retour arrière doit être considéré comme réussi seulement lorsque l’ancien chemin produit à nouveau un Archive installable. Une fois ce point obtenu, vous pouvez corriger le plugin fautif sur une branche séparée au lieu de bloquer les utilisateurs.
Décision finale : basculer, rester en double voie ou attendre
À la fin de la vérification TestFlight, choisissez explicitement l’une des trois issues suivantes :
- Bascule complète vers SwiftPM si tous les plugins natifs sont confirmés, que l’Archive signé fonctionne et que les fonctions critiques passent l’installation réelle.
- Maintien de la double voie si un ou plusieurs plugins fonctionnent correctement avec CocoaPods et que leur remplacement n’apporte pas de bénéfice immédiat.
- Report documenté si la résolution, la signature ou une fonction native reste instable ; indiquez le plugin concerné, la preuve manquante et la condition de réexamen.
Apple décrit également le flux général de gestion des builds et des versions dans App Store Connect (workflow officiel App Store Connect). Gardez au moins un nœud de publication ancien tant que la nouvelle chaîne n’a pas été installée et vérifiée par les testeurs. Vous pourrez ensuite supprimer progressivement les éléments devenus inutiles, mais seulement après avoir confirmé qu’ils ne sont plus requis par un plugin ou un script.
Une seule machine de production reste un point de défaillance : elle mélange le développement quotidien, les caches, les certificats et la publication. Si votre poste principal est sous Windows ou Linux, ou si vous ne disposez que d’un Mac déjà utilisé pour livrer l’application, préparer temporairement un environnement distant SSHMac permet d’exécuter la migration Flutter 3.47 à l’écart de la chaîne stable. Vous pouvez comparer les modalités d’accès distant au Mac, conserver l’ancien chemin CocoaPods, puis décider après TestFlight s’il faut maintenir cette séparation.
Cette approche est généralement plus rationnelle qu’un achat immédiat si le besoin porte sur une migration ponctuelle, un audit de compatibilité ou quelques cycles de publication. Elle l’est moins pour une charge lourde et permanente qui exige des périphériques physiques, une présence locale ou une maîtrise complète du matériel. Dans ces cas, un Mac acheté et administré sur place peut rester préférable. Pour une équipe qui utilise actuellement une seule machine, dépend de caches locaux difficiles à reproduire et interrompt sa production dès qu’une migration Xcode échoue, le Mac distant loué apporte surtout une séparation opérationnelle et un environnement disponible à la demande, sans transformer la branche de production en laboratoire.