Le point décisif est le chemin de Bundle fourni par App Store Connect : localisez d’abord ce chemin dans l’archive xcarchive, puis corrigez la cible réellement responsable. Cette méthode s’applique lorsque votre dépôt semble correct, mais que l’envoi d’une application iOS ou macOS échoue à cause de PrivacyInfo.xcprivacy, d’une déclaration Required Reason API ou d’un SDK tiers.
Vous êtes concerné si vous avez reçu une erreur ITMS-91056 ou un message voisin et devez rétablir TestFlight ou une soumission App Store. Ce guide vise aussi les équipes qui utilisent Swift Package Manager, CocoaPods ou des XCFrameworks et construisent depuis un Mac distant ou une intégration continue.
01 Le chemin du Bundle comme première preuve
Un message d’App Store Connect peut désigner l’application principale, une extension, un framework imbriqué ou un autre composant du produit. Ces erreurs ne se corrigent pas de la même façon. Distinguez donc :
| Signal observé | Ce qu’il faut vérifier | Action initiale |
|---|---|---|
| Manifeste invalide | Syntaxe, clés, types et structure du fichier | Examiner le fichier dans l’archive finale |
| Manifeste absent | Intégration dans la bonne cible et le bon Bundle | Contrôler la phase de copie des ressources |
Required Reason API non déclarée |
Catégorie d’API et raison approuvée | Relier la déclaration à un appel réel |
| SDK tiers signalé | Version, manifeste fourni et signature | Identifier le mainteneur et le mode d’installation |
| Erreur liée à un composant imbriqué | Chemin du framework ou de l’extension | Suivre le chemin exact indiqué par Apple |
Apple explique la procédure de diagnostic dans sa note technique TN3181 sur les manifestes de confidentialité invalides. Le nom du fichier, le code d’erreur et le chemin du Bundle forment votre première preuve. Ne commencez pas par ajouter un fichier générique au projet principal.
Conservez le message reçu, en supprimant le nom du projet, l’identifiant de Bundle, le compte, les chemins internes et les noms privés de SDK. Le but est de garder une correspondance vérifiable entre le message et l’élément de l’archive.
Attention. Le fichier visible dans le navigateur de projet Xcode n’est pas nécessairement celui qui a été envoyé. Une ressource peut être exclue de la cible, copiée dans un mauvais Bundle ou remplacée par une version apportée par une dépendance.
02 Format plist et état du produit archivé
Le fichier PrivacyInfo.xcprivacy est un plist. Vous devez toutefois l’examiner dans l’archive soumise, pas uniquement dans le répertoire source. Une syntaxe correcte ne garantit pas que les clés, les valeurs et le contexte du Bundle respectent les contrôles d’App Store Connect.
Dans Xcode, ouvrez le fichier avec l’éditeur de propriétés. Vérifiez notamment :
- que l’objet racine est du type attendu ;
- que les tableaux contiennent bien des valeurs du type attendu ;
- que les dictionnaires sont placés au niveau correct ;
- que les valeurs booléennes sont réellement booléennes et non des chaînes de caractères ;
- que les tableaux vides ne remplacent pas une déclaration exigée ;
- qu’aucune clé provenant d’un exemple ancien ou d’un script interne n’a été ajoutée par erreur.
Pour contrôler une copie de travail sans modifier l’archive d’origine, utilisez des chemins fictifs et une copie séparée :
plutil -lint "/chemin/vers/cop ie/PrivacyInfo.xcprivacy"
plutil -p "/chemin/vers/cop ie/PrivacyInfo.xcprivacy"
Remplacez évidemment le chemin avec espace accidentel ci-dessus par un chemin réel correctement saisi, par exemple :
plutil -lint "/chemin/vers/copie/PrivacyInfo.xcprivacy"
plutil -p "/chemin/vers/copie/PrivacyInfo.xcprivacy"
La première commande indique si le plist est lisible. La seconde permet d’observer les types et les niveaux imbriqués. Elle ne certifie ni la validité des raisons déclarées ni la conformité du SDK.
Apple décrit la structure d’un manifeste ajouté à une application ou à un SDK tiers. Utilisez cette référence pour comparer la forme attendue, puis revenez au chemin du Bundle signalé.
| Contrôle local | Résultat acceptable | Ce que ce résultat ne prouve pas |
|---|---|---|
plutil -lint |
Le fichier peut être lu comme plist | Les clés sont autorisées |
Inspection avec plutil -p |
Types et niveaux cohérents | Les raisons correspondent au code |
| Recherche dans l’archive | Le fichier est dans le Bundle concerné | La signature reste valide après modification |
| Rapport de confidentialité | Les déclarations attendues apparaissent | L’envoi distant sera accepté sans traitement |
Ne modifiez pas directement un fichier à l’intérieur d’une archive destinée à être envoyée. Une modification change le contenu signé. Si vous devez examiner ou corriger une copie d’archive à titre exceptionnel, prévoyez ensuite une signature complète adaptée au produit et refaites l’ensemble de la validation.
03 Déclarations d’API et raisons approuvées
Une erreur Required Reason API ne se résout pas en choisissant la première raison proposée. La raison doit correspondre à l’utilisation réelle de l’API. Cette utilisation peut venir de votre code, d’une bibliothèque ou d’un composant embarqué.
Commencez par rechercher les appels concernés dans votre dépôt et dans les dépendances résolues. Comparez ensuite :
- la catégorie d’API détectée ;
- la raison inscrite dans
PrivacyInfo.xcprivacy; - le code qui justifie cette utilisation ;
- le rapport de confidentialité généré par l’environnement de construction.
La documentation Apple consacrée aux Required Reason API présente le principe général. La note TN3183 sur l’ajout des entrées aide à relier la catégorie d’API à la déclaration attendue.
Ne déclarez pas une raison qui ne décrit pas la fonction réelle de l’application uniquement pour faire disparaître le message. Cette approche peut déplacer le problème vers la conformité de la déclaration. De même, le manifeste de l’application principale ne remplace pas automatiquement celui d’un SDK qui utilise lui-même une API concernée.
La distinction est importante pour une application créative. Un outil audio peut utiliser des composants système pour enregistrer ou exporter un fichier, tandis qu’un éditeur vidéo peut embarquer plusieurs bibliothèques de traitement. Le nom du produit ne suffit pas à choisir une raison : c’est l’usage du code qui sert de preuve.
04 Dépendances, manifestes et signatures
Le responsable du fichier dépend du mode d’installation. Pour chaque dépendance, notez sa source, sa version résolue et le Bundle final qui la contient.
Avec Swift Package Manager, vérifiez si le paquet déclare une ressource de manifeste et si cette ressource est bien copiée au moment de l’archivage. Avec CocoaPods, inspectez les phases de ressources et les frameworks produits. Pour un framework dynamique ou un XCFramework binaire, contrôlez le contenu livré par le fournisseur, sans supposer que le manifeste de votre application couvre le binaire.
La page Apple sur les exigences applicables aux SDK tiers confirme que certains SDK doivent fournir un manifeste conforme et, selon le cas, respecter des exigences de signature. Si un SDK officiel ou répertorié est en cause, privilégiez une version publiée par son mainteneur avec les fichiers attendus.
La séquence de décision peut rester simple :
- Si le fichier appartient à votre code et que l’usage est documenté, corrigez la source, la cible et la déclaration, puis archivez à nouveau.
- Si le fichier provient d’un paquet géré et qu’une version corrigée existe, mettez à jour le paquet en conservant le fichier de verrouillage.
- Si le SDK est binaire et que son manifeste ou sa signature est incorrect, demandez une version corrigée au mainteneur avant de modifier le produit.
- Si une correction temporaire dans l’archive est inévitable, travaillez sur une copie, documentez la modification et refaites la signature selon les règles du produit.
- Si aucun responsable n’est identifiable, comparez le contenu du Bundle, la liste des dépendances et le rapport de confidentialité avant toute nouvelle tentative.
Une modification manuelle du framework peut être écrasée au prochain nettoyage des dépendances. Elle peut également rendre la signature incohérente. Ce n’est donc pas une stratégie de maintenance durable.
05 Cibles et emplacements du Bundle
Un projet peut contenir plusieurs cibles : application, extension, App Clip, framework, composant Mac Catalyst ou application macOS. La présence d’un manifeste dans le dépôt ne signifie pas que chaque cible l’intègre.
Dans l’archive, examinez le produit réel et recherchez les occurrences de PrivacyInfo.xcprivacy :
find "/chemin/vers/Produit.xcarchive" \
-name "PrivacyInfo.xcprivacy" \
-print
Comparez chaque résultat au chemin fourni dans le message App Store Connect. Si l’application principale possède un fichier valide mais qu’un framework imbriqué en contient un autre qui est invalide, corriger uniquement l’application ne changera pas l’erreur.
Contrôlez aussi les points suivants :
- la cible du fichier dans la section d’appartenance Xcode ;
- les phases « Copy Bundle Resources » ou l’équivalent géré par la dépendance ;
- le chemin final du framework dans
Frameworks; - le contenu des extensions et des App Clips ;
- la variante construite pour Mac Catalyst ou macOS ;
- les scripts qui copient, génèrent ou remplacent des ressources pendant la compilation.
Apple détaille également l’ajout d’un manifeste à une application ou à un SDK. Utilisez cette page pour distinguer le fichier que vous fournissez de celui qu’un SDK doit fournir lui-même.
06 Questions fréquentes sur le diagnostic
ITMS-91056 et manifeste invalide
L’erreur ITMS-91056 doit être traitée à partir du chemin et du Bundle mentionnés. Copiez l’archive dans un emplacement de travail, inspectez le plist et identifiez son propriétaire. Ensuite seulement, décidez s’il faut modifier votre cible, mettre à jour une dépendance ou demander une livraison corrigée au mainteneur du SDK.
Archive et emplacement réel du fichier
Dans une archive, cherchez le fichier dans le produit final et non dans le répertoire du projet. Une extension ou un framework peut contenir son propre manifeste. Le chemin relatif au Bundle est plus fiable que le nom du fichier seul, car plusieurs composants peuvent embarquer une ressource portant exactement le même nom.
Validation locale et refus distant
plutil répond à une question limitée : le fichier est-il un plist lisible ? App Store Connect examine d’autres critères, notamment les clés, les valeurs, le Bundle, les API déclarées, les exigences liées à certains SDK et la signature. Une réussite locale doit donc être suivie d’un contrôle de l’archive et d’un véritable envoi.
07 Nouvelle archive et validation d’envoi
Après la correction, supprimez l’ambiguïté entre l’ancien et le nouveau produit. Créez une archive entièrement nouvelle avec les dépendances résolues et le même commit que celui que vous souhaitez publier.
Suivez cette séquence :
- nettoyez ou isolez l’environnement de construction sans supprimer les preuves nécessaires ;
- vérifiez le fichier de verrouillage des dépendances ;
- archivez avec la cible et la configuration destinées à la publication ;
- inspectez le nouveau produit et le chemin du Bundle responsable ;
- relancez les contrôles plist sur une copie ;
- confirmez la signature des composants après toute modification ;
- générez ou conservez le rapport de confidentialité ;
- envoyez cette nouvelle archive ;
- attendez le traitement complet dans App Store Connect avant de conclure.
La documentation Apple sur la distribution des applications avec Xcode rappelle que la création de l’archive, sa distribution et son traitement sont des étapes distinctes. Ne considérez donc pas un succès de compilation comme une preuve d’acceptation.
Dans une intégration continue ou sur un Mac distant, conservez l’identifiant de commit, le fichier de verrouillage, les journaux de construction, le rapport de confidentialité, le chemin du Bundle et le message final d’App Store Connect. Ces éléments permettent de reproduire la même archive au lieu de corriger au hasard une machine de développement.
08 Checklist d’acceptation
Cochez chaque ligne avant de fermer l’incident :
- [ ] Le code d’erreur, le nom du fichier et le chemin du Bundle ont été conservés.
- [ ] Le fichier a été retrouvé dans l’archive effectivement destinée à l’envoi.
- [ ] Le plist passe le contrôle syntaxique sur une copie de travail.
- [ ] Les types, tableaux, dictionnaires et clés ont été vérifiés.
- [ ] Chaque
Required Reason APIcorrespond à un usage réel. - [ ] Le manifeste du SDK n’a pas été remplacé par celui de l’application principale.
- [ ] La source de chaque dépendance est connue.
- [ ] Les cibles, extensions, frameworks et variantes macOS ont été inspectés.
- [ ] Toute modification d’un binaire a été suivie d’une procédure de signature appropriée.
- [ ] Une nouvelle archive a été créée.
- [ ] Le rapport de confidentialité et les journaux ont été sauvegardés.
- [ ] L’envoi réel a été traité sans reprendre l’ancien produit.
Si vous avez besoin d’un environnement durable pour conserver les archives, verrouiller les dépendances et rejouer un envoi, vous pouvez consulter les options Mac à distance de CALMVPS. Pour comparer les modalités avant de déplacer votre chaîne de publication, la page des tarifs CALMVPS permet d’examiner le coût du maintien d’un poste de construction disponible.
Un Mac local reste préférable si vous avez besoin d’interfaces physiques, d’un travail quotidien sans dépendance réseau ou d’une charge lourde et stable sur le long terme. En revanche, un environnement distant dédié évite d’utiliser votre poste principal comme machine de publication, conserve plus facilement une archive et sépare les dépendances de production des essais audio, vidéo ou design. Pour une campagne de correction, une reprise après échec ou une validation continue, louer un Mac avec CALMVPS peut donc offrir un cadre plus reproductible qu’un poste partagé ou qu’un serveur non macOS.
La règle à retenir est opérationnelle : partez de l’archive et du chemin de Bundle signalés, ne masquez pas une erreur de SDK par une déclaration générique, puis validez une nouvelle archive jusqu’au traitement réel d’App Store Connect.