Symptôme → solution la plus rapide : en cas d’échec de résolution de Swift Package Manager dans Xcode 26.6, ne supprimez pas immédiatement tous les caches. Figez d’abord la version de Xcode, le fichier Package.resolved et la commande de résolution, puis comparez séparément le graphe des dépendances, l’accès Git et l’état des caches.
Cette méthode s’applique si le problème est apparu après une mise à niveau, si un produit de package est introuvable, ou si une construction automatisée échoue uniquement sur un Mac distant. Elle vous évite de transformer un diagnostic localisable en téléchargement complet et non reproductible.
À qui s’adresse ce guide ?
Aux développeurs indépendants confrontés à une résolution de packages instable dans Xcode 26.6, notamment avec des packages privés.
Il concerne aussi les petites équipes qui utilisent xcodebuild sur un Mac distant comme machine de compilation iOS persistante.
Dernière mise à jour : 23 août 2026. Les informations sur la version stable de Xcode et ses notes de publication ont été vérifiées dans les publications officielles d’Apple et les notes de version de Xcode 26.6. Xcode 27 reste une version bêta à cette date ; ses éventuels changements ne doivent pas servir de base à un environnement de production.
1. Établissez une base de comparaison avant toute suppression
Une erreur de résolution n’est pas nécessairement une erreur de compilation. Ces états doivent rester séparés :
- résolution des versions des packages ;
- téléchargement ou récupération du dépôt ;
- extraction du graphe des dépendances ;
- association d’un produit de package à une cible ;
- compilation du code Swift ou Objective-C ;
- création de l’Archive.
Le premier objectif est d’identifier l’état exact qui échoue. Un message comme « product not found » peut apparaître après une résolution réussie, lorsque le produit demandé ne correspond pas au nom réellement déclaré par le package. À l’inverse, un délai d’accès à un dépôt privé survient avant la construction du graphe.
Relevez les quatre éléments qui doivent rester identiques
Conservez, dans un fichier local désensibilisé, les éléments suivants :
- la version active de Xcode ;
- le chemin de l’outil de développement utilisé par la session ;
- le projet ou le workspace réellement construit ;
- la commande exacte de résolution ou de construction.
Ne publiez jamais le chemin personnel, le nom du dépôt, le nom d’utilisateur, l’hôte Git, le jeton d’accès ou le contenu d’une clé SSH. Remplacez-les par des valeurs explicites comme <PROJET>, <WORKSPACE>, <DEPOT_PRIVE>, <UTILISATEUR_CI> et <CHEMIN_TRAVAIL>.
Pour la session graphique, lancez la résolution depuis Xcode et exportez uniquement la partie utile du journal. Pour la session shell, utilisez votre commande xcodebuild avec le projet ou le workspace approprié, puis conservez la première erreur exploitable plutôt que les dizaines de messages secondaires. Les paramètres et flux de travail documentés par Apple pour les constructions continues constituent le point de référence pour cette comparaison entre Xcode et l’intégration continue.
Un journal de référence peut ressembler à ceci :
Xcode: <VERSION_XCODE>
Developer directory: <CHEMIN_DEVELOPPEUR>
Workspace: <WORKSPACE>
Scheme: <SCHEME>
Working directory: <CHEMIN_TRAVAIL>
Resolving package graph...
Fetching <DEPOT_PUBLIC>
Fetching <DEPOT_PRIVE>
error: <MESSAGE_DESENSIBILISEE>
Répétez le même test dans Xcode et depuis le terminal. Si l’interface réussit mais que xcodebuild échoue, suspectez d’abord la session shell, l’utilisateur d’exécution, le trousseau, Git ou SSH. Si les deux échouent sur le même dépôt et la même révision, examinez la contrainte de version ou le dépôt lui-même.
2. Vérifiez la cohérence entre Package.swift, le projet et Package.resolved
Package.resolved doit être lu comme un état verrouillé, pas comme une simple copie de Package.swift. Le fichier de manifeste décrit des contraintes ; le fichier de résolution enregistre les versions et révisions retenues pour le graphe du projet. La documentation Apple sur les dépendances de Package explique les formes de contraintes acceptées, tandis que la documentation officielle de Swift Package Manager sur la résolution des versions décrit la logique générale de sélection.
Ce qu’il faut comparer
Commencez par le dépôt de votre application :
- les URL des packages dans
Package.swiftou dans la configuration du projet ; - les bornes de version déclarées ;
- les produits effectivement utilisés par les cibles ;
- les révisions inscrites dans
Package.resolved.
Vérifiez ensuite si le fichier verrouillé correspond à l’application ou à une bibliothèque référencée. Dans un projet applicatif, Package.resolved appartient généralement au contexte de résolution de l’application. Une bibliothèque distribuée ne doit pas imposer silencieusement le verrouillage propre à l’application qui la consomme. Le traitement exact dépend toutefois de la structure du dépôt et de la manière dont le package est intégré.
Après un changement de branche, recherchez les traces suivantes :
- conflit Git résolu en conservant deux entrées incompatibles ;
- enregistrement d’une révision qui ne satisfait plus la contrainte actuelle ;
- package supprimé du manifeste mais encore présent dans le fichier verrouillé ;
- script d’automatisation qui régénère le fichier avant chaque construction ;
- différence entre le fichier versionné et celui présent dans le répertoire de travail.
La bonne question n’est pas seulement « le fichier existe-t-il ? ». Demandez plutôt : « ce fichier décrit-il encore la même intention que le manifeste et le projet ? »
Attention : avant de régénérer
Package.resolved, copiez sa version actuelle et notez la révision Git du projet. Sinon, une résolution apparemment réussie peut remplacer une version connue par une version nouvelle, ce qui rend la comparaison avec la dernière construction fonctionnelle beaucoup plus difficile.
Faut-il versionner Package.resolved ?
Pour une application destinée à être construite de façon reproductible, versionner Package.resolved est généralement le choix le plus contrôlable. Il permet à votre poste local, à votre Mac distant et à la chaîne d’intégration de partir du même état déclaré. Une mise à jour de dépendance devient alors une modification examinable, et non un effet secondaire d’une tâche planifiée.
La situation est différente pour une bibliothèque réutilisable : le verrouillage produit par l’environnement de développement de la bibliothèque ne doit pas être confondu avec les choix de résolution de l’application cliente. Examinez donc la structure du dépôt avant d’ajouter ce fichier à l’aveugle dans une revue de code.
3. Séparez connexion, authentification et téléchargement Git
Un package public et un package privé ne se diagnostiquent pas de la même manière. Pour un dépôt public, un échec peut venir de l’URL, du DNS, du proxy ou d’une indisponibilité réseau. Pour un dépôt privé, ajoutez les droits du compte, le chargement de la clé SSH, l’empreinte de l’hôte et la configuration du trousseau.
Testez dans cet ordre
Pour chaque URL concernée, identifiez la première étape qui échoue :
- résolution DNS du nom d’hôte ;
- connexion réseau vers le service Git ;
- vérification de l’empreinte SSH ou négociation HTTPS ;
- présentation du compte ou de la clé ;
- autorisation de lecture du dépôt ;
- récupération de la référence demandée.
Ne réutilisez pas une clé privée dans un ticket ou dans un journal. Utilisez un hôte sous la forme <HOTE_GIT> et un dépôt sous la forme <ORGANISATION>/<DEPOT>. Les commandes de test doivent également éviter l’affichage des variables secrètes.
Le point souvent négligé est la différence entre votre terminal interactif et l’utilisateur qui exécute la tâche automatisée. Une clé chargée dans votre session peut être absente lorsque le service de compilation démarre. De même, un fichier de configuration Git présent dans votre répertoire personnel peut ne pas être lu par l’utilisateur <UTILISATEUR_CI>.
xcodebuild peut aussi s’inscrire dans un environnement différent de celui de votre Git configuré manuellement. Ne concluez donc pas que « Git fonctionne » parce qu’une commande interactive réussit. Comparez l’utilisateur, le répertoire personnel, les variables d’environnement, le trousseau accessible et le chemin vers les outils de développement. Utilisez comme référence l’entrée Apple consacrée à la résolution des problèmes courants de configuration et de compilation.
4. Examinez les dépendances locales, binaires et les produits déclarés
Une résolution terminée par « succès » ne garantit pas que la cible pourra être construite. Le package peut être récupéré correctement tout en exposant un produit différent de celui attendu par le projet.
Contrôlez les correspondances suivantes :
- nom du package et nom du produit ;
- produit déclaré et produit lié à la cible ;
- version résolue et API réellement disponible ;
- dépendance distante et package local utilisé en substitution ;
- dépendance source et archive binaire téléchargée ;
- architecture disponible dans une dépendance binaire ;
- absence de cycle entre packages.
Pour une dépendance binaire, vérifiez aussi la validité de l’archive et de ses métadonnées. Apple fournit une procédure dédiée pour identifier les dépendances binaires dans Xcode. Cette vérification est importante lorsque le problème n’apparaît que sur une cible, une configuration ou un Scheme particulier.
Si « missing package product » n’apparaît que sur une branche, créez un petit projet de reproduction avec le même package et la même contrainte. Trois résultats sont alors possibles :
- le projet minimal échoue aussi : le dépôt, la version ou l’accès sont probablement en cause ;
- le projet minimal réussit mais l’application échoue : inspectez la structure du projet, le Scheme et les produits liés ;
- seul l’Archive échoue : la résolution est probablement terminée, et il faut poursuivre le diagnostic côté signature, configuration ou compilation.
Cette réduction est préférable à la suppression répétée de fichiers, car elle transforme un symptôme visuel en comparaison mesurable.
5. Réinitialisez uniquement le cache correspondant au symptôme
Le terme « cache » recouvre plusieurs couches. Elles n’ont ni le même contenu ni le même coût de restauration :
- cache des dépôts Swift Package Manager ;
- répertoires de checkout des dépendances ;
DerivedData;- produits de compilation ;
- fichiers de travail du projet.
Supprimer DerivedData peut aider un problème de compilation ou d’indexation, mais ne répare pas nécessairement un dépôt privé inaccessible. À l’inverse, effacer les données de packages force de nouvelles récupérations et peut masquer une divergence de version.
Commencez par comparer une résolution avec le cache actuel et une résolution après nettoyage ciblé, en conservant le même commit, le même Package.resolved et la même commande. Notez précisément si l’erreur change :
- même erreur, même dépôt : suspectez l’URL, les droits ou la contrainte ;
- erreur différente : le cache ou le checkout intervenait probablement ;
- résolution identique mais produit absent : revenez au projet et au graphe ;
- résolution réussie puis compilation différente : examinez les produits et les artefacts.
Ne touchez pas aux certificats, profils de provisioning, clés de signature ni éléments du trousseau pendant une opération de nettoyage de cache. Ils ne constituent pas le cache de résolution et leur suppression crée un incident de publication distinct.
Expérience de maintenance : une purge globale peut donner l’impression d’avoir réparé la machine simplement parce qu’elle déclenche un nouveau téléchargement. Si la cause est une identité d’exécution mal configurée, le même échec reviendra au prochain redémarrage ou sur la prochaine tâche automatisée.
6. Traitez le Mac distant comme un environnement à reproduire
Quand la construction locale fonctionne mais que le Mac distant échoue, ne partez pas du principe que le projet est différent. Comparez d’abord les conditions d’exécution.
Contrôles à réaliser sur le poste distant
Utilisez le même commit et le même Package.resolved, puis vérifiez :
- la version de Xcode appelée par le processus ;
- le chemin du répertoire de développement actif ;
- l’utilisateur qui lance
xcodebuild; - le répertoire de travail réellement utilisé ;
- les fichiers Git et SSH lus par cet utilisateur ;
- la présence et les droits du checkout ;
- le Scheme et la destination de construction ;
- le résultat de la résolution avant le build ;
- le résultat d’une construction ordinaire ;
- le résultat d’un Archive.
Ces contrôles ne sont pas dix mesures de performance : ce sont dix conditions de reproductibilité. Ils servent à déterminer si le problème appartient au dépôt, au projet ou à l’environnement.
Pour un service distant, votre procédure de validation doit survivre à trois événements : redémarrage de l’hôte, nettoyage du répertoire de travail et récupération complète du dépôt. Une seule construction réussie ne prouve pas que la machine est prête à servir de serveur de compilation iOS.
Les équipes qui déplacent cette charge vers un Mac distant accessible pour les travaux Xcode devraient d’abord tester un projet réel, avec son package privé éventuel et son Archive. L’objectif n’est pas seulement d’obtenir une session graphique utilisable pour du design, de l’audio ou de la vidéo, mais de confirmer que le processus sans surveillance lit les mêmes informations que votre poste de développement.
7. Choisissez la prochaine action avec des critères explicites
Utilisez les branches suivantes plutôt qu’une purge automatique :
- Si Xcode et
xcodebuildéchouent sur le même package public, alors comparez l’URL, la contrainte et la résolution enregistrée avant de modifier le cache. - Si seul le package privé échoue, alors contrôlez l’utilisateur, les droits de lecture, SSH, le trousseau et le proxy.
- Si le fichier
Package.resolvedne correspond plus au manifeste, alors restaurez la dernière version cohérente ou mettez à jour la dépendance dans une modification examinée. - Si la résolution réussit mais qu’un produit manque, alors inspectez le nom du produit, la cible et le Scheme ; ne recommencez pas le diagnostic réseau.
- Si le poste local réussit et que le Mac distant échoue, alors comparez l’environnement d’exécution avant de recréer la machine.
- Si le même dépôt ne retrouve pas une base stable après ces contrôles, alors préparez une reconstruction documentée de l’environnement.
- Si le problème disparaît uniquement après une purge globale, alors reproduisez la panne avec un cache froid et un cache conservé avant de déclarer la correction durable.
Cette logique répond aussi au cas où la réinitialisation du cache des packages ne change rien : revenez à la version, à l’accès et à l’identité d’exécution. Le cache n’est qu’une hypothèse parmi d’autres.
Comparer les résultats avant et après intervention
Placez vos observations dans une fiche courte. Elle doit permettre à une autre personne de relancer le test sans deviner ce qui a été changé.
| Indicateur | Avant correction | Après correction | Interprétation |
|---|---|---|---|
| Xcode et répertoire actif | <VERSION> / <CHEMIN> |
<VERSION> / <CHEMIN> |
Doivent rester identiques |
| Commit du projet | <COMMIT> |
<COMMIT> |
Évite de comparer deux sources |
Package.resolved |
<HASH_OU_ETAT> |
<HASH_OU_ETAT> |
Montre si le graphe a changé |
| Première erreur | <ERREUR_DESENSIBILISEE> |
<RESULTAT> |
Mesure le changement réel |
| Package concerné | <PACKAGE> |
<PACKAGE> |
Distingue réseau et projet |
| Utilisateur d’exécution | <UTILISATEUR> |
<UTILISATEUR> |
Détecte une configuration différente |
| Archive | échec / non testée | réussite / échec | Sépare résolution et livraison |
Ne renseignez pas de secret dans ce tableau. Un identifiant de commit, une catégorie d’erreur et un nom de variable remplacé par un jeton neutre suffisent pour l’analyse.
Quel environnement retenir pour un build régulier ?
| Situation constatée | Choix recommandé | Pourquoi |
|---|---|---|
| Le poste local et le Mac distant partagent le même graphe et la même commande | Conserver le Mac distant | La construction est reproductible |
| Seul l’utilisateur automatisé échoue à accéder au package privé | Corriger l’identité d’exécution | Recréer l’hôte ne supprimerait pas la cause |
| Le projet réussit seulement avec un cache ancien non documenté | Stabiliser puis documenter le cache | Une purge ultérieure provoquerait une nouvelle panne |
| La machine échoue après redémarrage ou récupération propre | Reconfigurer l’environnement | La réussite actuelle dépend d’un état implicite |
| Vous avez besoin d’un poste graphique ponctuel pour Xcode, le design, l’audio ou la vidéo | Envisager une session Mac distante temporaire | Vous évitez d’acheter une machine dédiée à un besoin intermittent |
| Le build est lourd, permanent et dépend d’interfaces physiques locales | Garder ou acheter un Mac dédié | La location distante n’est pas adaptée à chaque contrainte matérielle |
Pour une machine conservée à distance, la persistance du répertoire de travail n’est pas une preuve suffisante. Vous devez pouvoir repartir du dépôt, réappliquer l’authentification et résoudre les packages avec le même résultat. Si votre organisation utilise déjà plusieurs postes, comparez également le coût opérationnel des téléchargements, de la surveillance et des interventions manuelles, sans confondre ce coût avec celui d’une licence ou d’un matériel.
Ce que votre solution actuelle peut réellement vous coûter
Si vous utilisez un poste Windows ou Linux pour l’essentiel du développement, vous devrez malgré tout maintenir un environnement macOS pour Xcode, les signatures et l’Archive. Une virtualisation mal adaptée ajoute des limites d’accès matériel et de maintenance ; une machine personnelle peut perdre son cache, être éteinte ou être occupée au moment du build ; un serveur improvisé peut exécuter la tâche sous un autre compte que votre session interactive.
Dans ce contexte, louer un Mac avec MACCOME peut être plus cohérent pour valider un projet réel avant de maintenir une machine de compilation. Vous conservez un environnement macOS accessible à distance, vous évitez l’achat d’un poste réservé aux tâches de publication et vous pouvez examiner la reproductibilité sur un hôte distinct. Commencez par examiner les possibilités de Mac distant proposées par MACCOME, puis exécutez votre propre résolution, votre build et votre Archive avec vos packages désensibilisés.
Cette option n’est pas automatiquement préférable pour une charge lourde et permanente, pour un besoin de périphérique physique ou pour une équipe qui doit contrôler chaque élément matériel. Elle est surtout pertinente lorsque votre problème vient d’un environnement macOS instable, d’un utilisateur automatisé différent ou de l’impossibilité de conserver durablement un poste de compilation.
La bonne séquence reste donc la même : figer le contexte, identifier l’étape fautive, corriger la couche concernée, puis vérifier la récupération après redémarrage et nettoyage. Si cette base ne tient pas sur votre machine actuelle, testez-la sur un Mac distant avec votre dépôt réel avant de décider entre réparation, migration ou maintien de deux environnements.