← Tous les articles

Plongée approfondie dans le privacy manifest : ce qui compte comme collecte de données

Depuis le 1er mai 2024, chaque application et SDK tiers téléversé sur App Store Connect doit comporter un privacy manifest déclarant son utilisation des « API à motif requis », son comportement de tracking et les types de données collectées1. Le manifest est une property list (PrivacyInfo.xcprivacy) que l’App Store ingère au moment de la soumission, valide par rapport à une surface connue d’API sensibles à la vie privée et fait apparaître dans le label nutritionnel de confidentialité visible par l’utilisateur. Les applications qui omettent le manifest, ou qui utilisent un API sensible à la vie privée sans déclarer un motif approuvé, sont rejetées à la soumission avec le code ITMS-91053 ou des codes similaires2.

La plupart des équipes traitent le manifest comme une tâche de conformité unique : on l’écrit, on l’expédie, on n’y touche plus jamais. Le manifest est plus que cela. C’est un contrat structuré entre l’application et Apple qui codifie ce que l’application fait avec les données privées, et c’est le seul endroit où ce contrat existe sous forme lisible par machine. Le lire attentivement révèle ce qu’Apple considère comme sensible à la vie privée (la surface est plus large que ce que la plupart des développeurs imaginent), ce que l’utilisateur voit réellement dans le label nutritionnel (plus granulaire que ce que la plupart des équipes réalisent) et ce que les SDK tiers doivent divulguer (une véritable obligation, pas une politesse).

TL;DR

  • Le privacy manifest comporte quatre sections de premier niveau : NSPrivacyTracking, NSPrivacyTrackingDomains, NSPrivacyCollectedDataTypes et NSPrivacyAccessedAPITypes3.
  • La liste des API à motif requis couvre cinq catégories initiales : horodatage de fichier, heure de démarrage du système, espace disque, claviers actifs et User Defaults. Chaque catégorie possède une liste fermée de codes de motif approuvés ; les applications doivent en choisir un ou réécrire le code pour éviter l’API4.
  • Le tracking est défini de manière restrictive : lier les données utilisateur à des données provenant d’autres entreprises à des fins publicitaires ou de partage avec des courtiers en données. Si NSPrivacyTracking vaut true, chaque domaine utilisé pour le tracking doit apparaître dans NSPrivacyTrackingDomains3.
  • Les SDK tiers doivent livrer leurs propres manifests. Le manifest de l’application est fusionné avec ceux de tous les SDK liés au moment de la soumission ; les manifests manquants pour les SDK figurant sur la liste publiée par Apple bloquent l’application5.
  • Le plus grand piège : tout accès à UserDefaults compte toujours comme un appel d’API à motif requis. Un simple UserDefaults.standard.set(...) requiert un code de motif déclaré.

Les quatre sections

Un fichier PrivacyInfo.xcprivacy complet comporte quatre clés de premier niveau3. La structure est une property list, modifiée en XML brut ou via l’éditeur de privacy manifest de Xcode.

NSPrivacyTracking (booléen)

Déclare si l’application ou le SDK suit l’utilisateur à travers les applications et sites web d’autres entreprises. La définition sémantique s’aligne sur App Tracking Transparency : lier des données utilisateur à des données provenant d’autres entreprises dans le but de cibler de la publicité, de diffuser de la publicité ciblée ou de partager des données utilisateur avec des courtiers en données6.

Si NSPrivacyTracking vaut true, chaque domaine utilisé pour le tracking doit apparaître dans la liste NSPrivacyTrackingDomains. Si false, la liste est omise (ou vide).

La définition restrictive a son importance. De nombreuses applications qui affichent des publicités (via SKAdNetwork d’Apple ou des SDK publicitaires sans tracking) peuvent déclarer NSPrivacyTracking à false. Le tracking est le lien avec des données externes, pas l’affichage de publicités.

NSPrivacyTrackingDomains (tableau de chaînes)

La liste des domaines que l’application ou le SDK contacte à des fins de tracking. Les applications qui déclarent NSPrivacyTracking à true doivent énumérer ici chaque endpoint de tracking.

La liste est appliquée à l’exécution via App Privacy Report : si l’application contacte un domaine signalé comme étant du tracking mais non déclaré, App Privacy Report révèle l’écart à l’utilisateur. Des violations répétées exposent à un retrait de l’App Store.

NSPrivacyCollectedDataTypes (tableau de dictionnaires)

La déclaration structurée de collecte de données qui alimente le label nutritionnel de confidentialité de l’App Store3. Chaque entrée décrit un type de données collecté par l’application, avec des sous-clés :

  • NSPrivacyCollectedDataType : le type de données issu de la liste fermée d’Apple (par exemple, NSPrivacyCollectedDataTypeName, NSPrivacyCollectedDataTypeEmailAddress, NSPrivacyCollectedDataTypeCrashData).
  • NSPrivacyCollectedDataTypeLinked : booléen, indique si la donnée est liée à l’identité de l’utilisateur.
  • NSPrivacyCollectedDataTypeTracking : booléen, indique si la donnée est utilisée pour le tracking.
  • NSPrivacyCollectedDataTypePurposes : tableau, les finalités pour lesquelles la donnée est collectée (analytics, fonctionnement de l’application, publicité, etc.).

Cette section est la source de vérité pour le label nutritionnel de confidentialité. Les catégories « Données utilisées pour vous suivre » et « Données liées à vous » du label nutritionnel sont calculées à partir de ces drapeaux. Des déclarations inexactes produisent des labels nutritionnels inexacts et exposent à des actions de mise en conformité de l’App Store.

NSPrivacyAccessedAPITypes (tableau de dictionnaires)

La déclaration des API à motif requis. Chaque entrée associe une catégorie d’API à motif requis à un ensemble de codes de motif approuvés4.

<key>NSPrivacyAccessedAPITypes</key>
<array>
    <dict>
        <key>NSPrivacyAccessedAPIType</key>
        <string>NSPrivacyAccessedAPICategoryUserDefaults</string>
        <key>NSPrivacyAccessedAPITypeReasons</key>
        <array>
            <string>CA92.1</string>
        </array>
    </dict>
    <dict>
        <key>NSPrivacyAccessedAPIType</key>
        <string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
        <key>NSPrivacyAccessedAPITypeReasons</key>
        <array>
            <string>C617.1</string>
        </array>
    </dict>
</array>

Les motifs sont des listes fermées. L’application en choisit un ou plusieurs dans la liste publiée par Apple pour chaque catégorie ; les chaînes arbitraires sont rejetées à la soumission.

Les cinq catégories d’API à motif requis

La liste initiale d’Apple en 2024 a défini cinq catégories d’API nécessitant un motif déclaré4 :

NSPrivacyAccessedAPICategoryFileTimestamp

Déclenchée par tout API qui retourne l’heure de création, de modification ou d’accès d’un fichier. Points d’entrée courants : URL.resourceValues(forKeys: [.creationDateKey, ...]), FileManager.attributesOfItem(atPath:), stat(), fstat(), lstat(). Les quatre motifs approuvés4 :

  • DDA9.1. Afficher les horodatages de fichiers à l’utilisateur de l’appareil. Les informations consultées pour ce motif ne peuvent pas être envoyées hors de l’appareil.
  • C617.1. Accéder aux métadonnées de fichiers (horodatages, taille, etc.) pour les fichiers situés dans le conteneur de l’application, le conteneur de groupe d’applications ou le conteneur CloudKit.
  • 3B52.1. Accéder aux métadonnées de fichiers pour des fichiers ou répertoires auxquels l’utilisateur a explicitement accordé l’accès (sélecteur de documents, etc.).
  • 0A2A.1. Wrappers de SDK tiers qui n’accèdent aux API d’horodatage de fichier que lorsque l’application appelle le wrapper. Réservé aux SDK.

La plupart des applications utilisent C617.1 (accès au conteneur propre) pour la gestion interne des fichiers. Les applications qui affichent des dates de fichiers dans une UI utilisateur utilisent DDA9.1. Les applications qui lisent des fichiers accordés par l’utilisateur (sélecteur de documents, cibles d’extension de partage) utilisent 3B52.1. Les auteurs de SDK utilisent uniquement 0A2A.1.

NSPrivacyAccessedAPICategorySystemBootTime

Déclenchée par mach_absolute_time(), mach_continuous_time() et les API d’uptime associés. La préoccupation de confidentialité : l’heure de démarrage du système est un signal identifiable par empreinte qui peut servir à identifier l’appareil après réinstallation. Les trois motifs approuvés4 :

  • 35F9.1. Accéder à l’heure de démarrage du système pour mesurer des intervalles de temps entre événements de l’application ou pour activer des minuteurs.
  • 8FFB.1. Accéder à l’heure de démarrage du système pour calculer les horodatages absolus d’événements au sein de l’application.
  • 3D61.1. Inclure l’information sur l’heure de démarrage du système dans un rapport de bug optionnel que l’utilisateur choisit de soumettre.

La plupart des applications utilisent 35F9.1 pour la mesure de performance. 8FFB.1 couvre les cas où l’application dérive des horodatages d’événements à partir de l’heure de démarrage (par rapport à la session de l’appareil). À noter que Date() et Date.now ne déclenchent pas cette catégorie ; ils utilisent une source de temps différente. La catégorie couvre spécifiquement les appels de la famille mach_*_time.

NSPrivacyAccessedAPICategoryDiskSpace

Déclenchée par les API qui retournent la capacité disque ou l’espace libre, notamment URL.resourceValues(forKeys: [.volumeAvailableCapacityKey, ...]) et les API d’attributs de système de fichiers de NSFileManager. La préoccupation de confidentialité : les motifs d’espace disque constituent un signal identifiable par empreinte. Les quatre motifs approuvés4 :

  • 854F.1. Afficher l’information d’espace disque à l’utilisateur de l’appareil, en unités de données ou en unités de durée de média.
  • E174.1. Vérifier l’espace disque lors de l’écriture de fichiers ou pour gérer un espace disque faible (décider s’il faut télécharger un asset, nettoyer les fichiers en cache).
  • 7D9E.1. Inclure l’information d’espace disque dans un rapport de bug optionnel que l’utilisateur choisit de soumettre.
  • B728.1. Applications de recherche en santé qui détectent et informent les participants d’un espace disque faible affectant la collecte de données de l’étude.

NSPrivacyAccessedAPICategoryActiveKeyboards

Déclenchée par UITextInputMode.activeInputModes. Les applications qui lisent cette liste (typiquement pour localiser un comportement ou détecter la langue de saisie) doivent déclarer un motif. Les deux motifs approuvés4 :

  • 3EC4.1. Une application de clavier personnalisé qui détermine les claviers actifs sur l’appareil.
  • 54BD.1. Accéder aux informations sur les claviers actifs pour personnaliser l’interface utilisateur en conséquence (typiquement pour une UX consciente de la langue de saisie).

La plupart des applications n’ont pas besoin de cette catégorie. Si votre code appelle activeInputModes indirectement via une bibliothèque tierce, le manifest de cette bibliothèque la déclare.

NSPrivacyAccessedAPICategoryUserDefaults

La catégorie qui attrape presque toutes les applications. Tout accès à UserDefaults (UserDefaults.standard, defaults de groupe d’applications via init(suiteName:), appels individuels set/get) déclenche l’exigence7. Les quatre motifs approuvés4 :

  • CA92.1. Accéder aux user defaults pour lire/écrire des données exclusives à l’application elle-même (ou à une extension d’application appariée uniquement avec l’application).
  • 1C8F.1. Accéder aux user defaults pour lire/écrire des données uniquement au sein d’applications, d’extensions d’application et d’App Clips membres du même App Group.
  • C56D.1. Wrappers de SDK tiers qui n’accèdent aux API de user defaults que lorsque l’application appelle le wrapper. Réservé aux SDK.
  • AC6B.1. Accéder aux user defaults pour récupérer des configurations d’application gérées définies par un administrateur MDM/IT, ou pour stocker des informations de retour destinées à l’administrateur.

Presque chaque application iOS utilise UserDefaults.standard pour au moins un élément d’état (le dernier onglet sélectionné par l’utilisateur, son ordre de tri préféré, un feature flag). Le motif CA92.1 le couvre. Les applications qui partagent un état entre extensions d’application via un app group ajoutent 1C8F.1. Les auteurs de SDK utilisent C56D.1. Les applications déployées via un MDM qui lisent des clés définies par l’administrateur (par exemple, com.apple.configuration.managed) utilisent AC6B.1.

Le piège : un SDK tiers qui touche à UserDefaults déclenche l’exigence pour le compte de l’application. Le manifest du SDK doit déclarer le motif. Si le SDK figure sur la liste d’Apple des SDK devant livrer un privacy manifest, l’absence du manifest du SDK bloque l’application.

Domaines de tracking : validation à l’exécution

NSPrivacyTrackingDomains est appliqué via App Privacy Report à l’exécution6. Lorsqu’une application déclare NSPrivacyTracking = true, le système suit chaque requête réseau et compare la destination à la liste déclarée. Les domaines contactés à des fins de tracking mais non déclarés apparaissent dans les sections « Lieux fréquents » et « Autres domaines contactés » d’App Privacy Report.

La validation à l’exécution crée une structure d’incitation intéressante. Une application qui déclare NSPrivacyTracking = false (pas de tracking) mais que l’on observe contacter des domaines de tracking connus est signalée dans App Privacy Report et s’expose à des plaintes d’utilisateurs. Le bon réflexe est la déclaration honnête.

Pour les SDK, le privacy manifest du SDK déclare son comportement de tracking. Le manifest de l’application n’a pas besoin d’énumérer les domaines de tracking du SDK ; le manifest du SDK le fait déjà. À la soumission, Apple fusionne les manifests et vérifie la cohérence.

Manifests de SDK : une véritable obligation

Les SDK tiers de deux catégories doivent livrer un privacy manifest5 :

  1. Les SDK figurant sur la liste publiée par Apple des SDK requérant un privacy manifest. Cette liste inclut Firebase Analytics, Google Mobile Ads, Adjust, Segment, AppsFlyer et une trentaine d’autres en date d’iOS 26.
  2. Les SDK distribués sous forme de binaires précompilés (XCFrameworks, bibliothèques statiques) auxquels l’application se lie.

La soumission d’une application qui se lie à un SDK requis sans le manifest du SDK échoue avec une erreur de la série ITMS-91xxx couvrant manifest de confidentialité manquant, signature de manifest manquante ou déclaration d’API manquante dans l’espace de noms du SDK2. Le correctif consiste soit à passer à une version du SDK livrant un manifest, soit à supprimer le SDK.

Pour les SDK propriétaires (votre équipe livre un framework interne utilisé par vos applications), vous pouvez choisir de ne pas fournir de manifest si le framework ne figure pas sur la liste d’Apple. Le geste pragmatique est d’en livrer un quand même : les futures expansions de la liste Apple, les futurs travaux d’audit et la future réutilisation par des tiers bénéficient tous de la présence d’un manifest.

Pièges courants

Cinq modes d’échec récurrents tirés des journaux de rejet de l’App Store :

1. Déclaration UserDefaults oubliée. Le rejet le plus fréquent. L’application utilise @AppStorage (qui encapsule UserDefaults) à un endroit anodin, le manifest ne le déclare pas. Correctif : toute application qui utilise @AppStorage, UserDefaults ou tout wrapper autour d’eux a besoin de NSPrivacyAccessedAPICategoryUserDefaults avec CA92.1.

2. Accès caché à l’horodatage de fichier via URLResourceValues. Le code qui lit les dates de modification de fichiers via URL.resourceValues(forKeys: [.contentModificationDateKey]) déclenche la catégorie, même si le site d’appel ne ressemble pas à un stat.

3. Attentes concernant le manifest de SDK. Les équipes applicatives supposent que le manifest du SDK est le problème de l’auteur du SDK. C’est le cas, mais la soumission de l’équipe applicative échoue tant que le SDK n’en livre pas un.

4. NSPrivacyTracking = false malgré un SDK de tracking lié. Lier Firebase Analytics ou Google Mobile Ads avec les paramètres par défaut déclenche souvent un comportement de tracking. Le manifest de l’application déclarant NSPrivacyTracking = false alors que celui du SDK déclare true produit une contradiction que la fusion signale.

5. Codes de motif obsolètes. Apple met occasionnellement à jour les codes de motif approuvés. Des codes valides en 2024 peuvent être remplacés ou étendus. Le correctif consiste à revérifier la liste publiée actuelle à chaque release majeure plutôt que de recopier d’anciens manifests.

Outils de validation

Trois vérifications à effectuer avant la soumission :

Le workflow d’archivage « Generate Privacy Report » de Xcode. Après Product > Archive, l’Organizer propose une action « Generate Privacy Report » qui produit un rapport agrégé à partir du manifest de l’application et de chaque SDK lié. Ce rapport est ce qu’App Store Connect ingère ; l’exécuter localement est l’équivalent le plus proche d’un essai à blanc avant soumission.

Analyse statique des API à motif requis. Des outils open source scannent un projet à la recherche des sites d’appel d’API qui déclenchent les cinq catégories. Le CLI communautaire stelabouras/privacy-manifest analyse les sources Swift et les binaires xcframework pour faire ressortir les codes de motif déclarés et non déclarés ; crasowas/app_store_required_privacy_manifest_analyser fournit un scan similaire. L’un comme l’autre permet de détecter utilement les déclarations manquantes avant la soumission.

Recoupement avec App Privacy Report. Exécutez l’application en mode App Privacy Report d’iOS (Réglages > Confidentialité et sécurité > Rapport de confidentialité de l’app). Les domaines contactés par l’application apparaissent dans le rapport ; recoupez-les avec les déclarations de tracking du manifest.

Ce que ce modèle signifie pour les applications iOS 26+

Trois enseignements.

  1. Traitez le privacy manifest comme un contrat structuré, pas comme une case à cocher. Le manifest est le seul enregistrement lisible par machine de ce que fait l’application avec les données privées. Le construire une fois et l’ignorer pour toujours est la voie vers une soumission rejetée six mois plus tard, quand une mise à jour de SDK étend silencieusement la surface requise du manifest.

  2. Auditez vos accès à UserDefaults et aux horodatages de fichiers à chaque release. Ce sont les deux catégories qui croissent silencieusement avec le code. Une vue SwiftUI utilisant @AppStorage ajoutée lors d’un refactoring tire NSPrivacyAccessedAPICategoryUserDefaults dans le périmètre ; une fonctionnalité de listage de fichiers ajoutée plus tard tire NSPrivacyAccessedAPICategoryFileTimestamp. Revalidez à chaque fois.

  3. Utilisez des SDK qui livrent leurs propres manifests. Lors de l’évaluation d’un SDK tiers, la présence et la qualité de son privacy manifest est désormais un signal de qualité. Les SDK sans manifest forcent l’équipe applicative à se battre en amont ; ceux avec manifest s’intègrent proprement à la fusion.

L’ensemble du cluster Apple Ecosystem : App Intents typés ; serveurs MCP ; la question du routage ; Foundation Models ; la distinction LLM runtime contre tooling ; les trois surfaces ; le pattern de source de vérité unique ; Two MCP Servers ; les hooks pour le développement Apple ; les Live Activities ; le contrat d’exécution watchOS ; les internes de SwiftUI ; le modèle mental spatial de RealityKit ; la discipline de schéma SwiftData ; les patterns Liquid Glass ; l’expédition multi-plateformes ; la matrice des plateformes ; le framework Vision ; le vocabulaire des Symbol Effects ; l’inférence Core ML ; l’API Writing Tools ; Swift Testing ; ce sur quoi je refuse d’écrire. Le hub se trouve dans la série Apple Ecosystem. Pour un contexte plus large iOS-avec-agents-AI, voir le guide iOS Agent Development.

FAQ

Quelle est la différence entre NSPrivacyTracking et NSPrivacyCollectedDataTypeTracking ?

NSPrivacyTracking est le booléen au niveau de l’application : cette application suit-elle les utilisateurs (selon la définition restrictive d’Apple) tout court ? NSPrivacyCollectedDataTypeTracking est par type de données : pour un type de données donné collecté par l’application, cette donnée est-elle utilisée pour le tracking ? Une application peut collecter des données sans tracker (analytics qui ne lient pas entre entreprises) ; le drapeau par type capture si chaque type de donnée spécifique contribue au comportement de tracking.

Ai-je besoin d’un privacy manifest pour une application TestFlight interne uniquement ?

Oui. L’application des règles du privacy manifest s’effectue à la soumission à App Store Connect, y compris pour les builds TestFlight. Une bêta interne sans manifest échoue à la même vérification ITMS-91053 qu’une release publique.

Que se passe-t-il si je déclare un API à motif requis sans l’utiliser ?

Rien sur le plan fonctionnel. Le manifest déclare une borne supérieure sur la surface des API ; déclarer une catégorie inutilisée est sans danger. Le coût est la dérive documentaire : les futurs mainteneurs peuvent supposer que la déclaration reflète le code actuel, alors que l’appel a en fait été supprimé. Le bon geste est de déclarer ce que l’application utilise réellement, audité à chaque release majeure.

Existe-t-il des catégories d’API à motif requis au-delà des cinq d’origine ?

En date d’iOS 26, les cinq catégories d’origine (horodatage de fichier, heure de démarrage du système, espace disque, claviers actifs, User Defaults) restent la liste canonique4. Apple a ajouté des codes de motif approuvés au sein des catégories au fil du temps mais n’a pas étendu la liste des catégories. Surveillez la page de documentation Required Reason API d’Apple pour les ajouts.

Comment le privacy manifest interagit-il avec App Tracking Transparency ?

App Tracking Transparency (ATT) régit l’invite de permission à l’exécution pour le tracking inter-applications. Le privacy manifest déclare l’intention de l’application de manière statique. Ils sont complémentaires : une application qui effectue du tracking inter-applications déclare NSPrivacyTracking = true dans le manifest et demande la permission ATT à l’exécution. Une application déclarant NSPrivacyTracking = false ne devrait pas demander ATT (l’absence de tracking inter-applications signifie que l’invite est inutile).

Références


  1. Documentation développeur Apple : Privacy manifest files. La référence du format et le calendrier d’application au 1er mai 2024. 

  2. Apple Developer : Erreurs de soumission App Store Connect couvrant ITMS-91053 (déclaration d’API manquante) et codes connexes. 

  3. Documentation développeur Apple : App privacy configuration. Les quatre clés de premier niveau (NSPrivacyTracking, NSPrivacyTrackingDomains, NSPrivacyCollectedDataTypes, NSPrivacyAccessedAPITypes) et leurs schémas. 

  4. Documentation développeur Apple : Describing use of required reason API. Les cinq catégories d’API à motif requis avec les codes de motif approuvés. 

  5. Apple Developer : Exigences de privacy manifest pour les SDK tiers. La liste des SDK qui doivent livrer un privacy manifest. 

  6. Documentation développeur Apple : User privacy and data use. La définition restrictive du tracking et le framework App Tracking Transparency. 

  7. Documentation développeur Apple : NSPrivacyAccessedAPICategoryUserDefaults. La catégorie couvrant tous les accès à UserDefaults y compris les wrappers basés sur @AppStorage

Articles connexes

SwiftData's Real Cost Is Schema Discipline

SwiftData's API is two macros. The cost is what happens after you ship. Optional fields are the cheap migration; non-opt…

15 min de lecture

Liquid Glass in SwiftUI: Three Patterns From Shipping Return on iOS 26

Apple's Liquid Glass is a one-line SwiftUI API. Three patterns from Return go beyond .glassEffect(): glass on text via C…

19 min de lecture

The Cleanup Layer Is the Real AI Agent Market

Charlie Labs pivoted from building agents to cleaning up after them. The AI agent market is moving from generation to pr…

15 min de lecture