ITMS-90683 : corriger « Missing purpose string » avec Expo
Par Mehdi Azizi
Publié le , 6 min
ITMS-90683 Missing purpose string : pourquoi Apple refuse ton build, quelle clé ajouter dans app.json avec Expo, et comment repérer les clés manquantes avant l'envoi.
ITMS-90683 est un refus automatique d'Apple : il arrive par e-mail peu après l'envoi de ton build, avant toute revue humaine. Il veut dire qu'il manque, dans ton fichier Info.plist, la phrase qui explique pourquoi l'app accède à une donnée sensible. La correction tient en deux gestes : ajouter la clé citée dans le message à ios.infoPlist, puis refaire un build.
Je l'ai pris sur Solys, mon réveil à mini-jeux, pour une donnée que l'app n'utilise même pas. Voici ce que le message veut dire, pourquoi il tombe, et comment l'éviter.
Que veut dire l'erreur ITMS-90683 ?
Le message complet s'intitule « ITMS-90683: Missing purpose string in Info.plist ». Il dit que le code de ton app fait référence à une API qui touche des données sensibles (photos, caméra, micro, position, contacts), et que ton Info.plist ne contient pas la clé de description correspondante. Le message nomme cette clé, par exemple NSPhotoLibraryUsageDescription.
Cette phrase de description s'appelle une « purpose string ». C'est le texte qu'iOS affiche dans la fenêtre de demande d'autorisation. Apple l'écrit dans sa documentation sur l'accès aux ressources protégées : App Review refuse les apps dont le code accède à ces ressources sans purpose string.
Ce n'est pas le refus d'un reviewer. Le contrôle est automatique et tombe à la livraison du build, avant la mise en revue, comme ITMS-91053 pour le manifeste de confidentialité. Le build est écarté et il faut en renvoyer un.
Pourquoi Apple refuse alors que ton app n'utilise pas cette donnée
C'est le point qui surprend. Apple analyse le code contenu dans ton build, pas ce que ton app fait réellement. Si une bibliothèque que tu embarques contient une référence à la photothèque, la clé est exigée, même si aucun écran ne demande jamais l'accès aux photos. Le message d'Apple le précise lui‑même : une bibliothèque ou un SDK externe peut faire référence à ces API, et la purpose string reste obligatoire.
Mon cas, le 26 septembre 2026. En nettoyant la configuration de Solys, j'avais retiré la clé NSPhotoLibraryUsageDescription, puisque l'app ne touche à aucune photo. Le build suivant a été refusé en ITMS-90683. La cause : deux bibliothèques d'Expo que l'app utilise, expo-image et expo-file-system, contiennent du code qui fait référence à la photothèque. Le build précédent passait, parce que la clé était encore là.
La leçon : une clé de description ne se retire pas « parce qu'on ne s'en sert pas ». Elle se retire seulement quand plus aucune bibliothèque du build ne fait référence à l'API.
Les clés les plus courantes
NSPhotoLibraryUsageDescription: lecture ou écriture des photos.NSPhotoLibraryAddUsageDescription: ajout de photos, sans lecture.NSCameraUsageDescription: caméra.NSMicrophoneUsageDescription: micro.NSLocationWhenInUseUsageDescription: position pendant l'usage.NSContactsUsageDescription: contacts.NSUserTrackingUsageDescription: suivi publicitaire (App Tracking Transparency).
Apple décrit chaque clé dans sa documentation, par exemple celle de NSPhotoLibraryUsageDescription : elle est exigée dès que l'app utilise une API qui lit ou écrit dans la photothèque.
Corriger ITMS-90683 dans une app Expo
- Relève la clé citée dans l'e-mail d'Apple. Le message donne son nom exact.
- Ajoute-la dans ta configuration, sous
ios.infoPlist, comme l'indique la documentation d'Expo sur les autorisations :
{
"expo": {
"ios": {
"infoPlist": {
"NSPhotoLibraryUsageDescription": "Solys n'accède pas à tes photos. Cette autorisation n'est jamais demandée."
}
}
}
}
- Refais un build. Expo le précise : une modification de l'Info.plist ne passe pas par une mise à jour à distance, elle demande un nouveau binaire.
- Renvoie le build à Apple, puis sélectionne-le dans ta version.
Un piège si ton app est traduite : les fichiers de langue traduisent une clé, ils ne la déclarent pas. La clé doit d'abord exister dans ios.infoPlist (ou dans la configuration du plugin concerné). Sinon l'app peut planter au premier appel.
Quelle phrase écrire si ton app n'utilise pas la donnée ?
Apple demande une description exacte, utile et précise. Si ton app se sert vraiment de la donnée, dis à quoi elle sert, en une phrase : « L'app utilise la caméra pour scanner le code-barres de ton billet. »
Si la clé n'est là qu'à cause d'une bibliothèque, Apple donne deux remèdes : écrire la phrase, ou retirer le code qui accède à la donnée. Quand ce code vient d'une bibliothèque, tu ne peux pas le retirer simplement. Sur Solys, j'ai donc écrit la vérité : « Solys n'accède pas à tes photos. Cette autorisation n'est jamais demandée. » C'est un choix pragmatique : le build suivant est passé à la livraison, mais je ne peux pas te dire qu'Apple acceptera toujours cette phrase.
Repérer les clés manquantes avant l'envoi
Depuis la racine de ton projet, cette commande liste les fichiers des bibliothèques dont le code iOS fait référence aux API les plus surveillées :
grep -rlE "PHPhotoLibrary|AVCaptureDevice|CLLocationManager|CNContactStore|EKEventStore|ATTrackingManager" \
node_modules/*/ios node_modules/@*/*/ios
Chaque nom correspond à une donnée : PHPhotoLibrary pour les photos, AVCaptureDevice pour la caméra et le micro, CLLocationManager pour la position, CNContactStore pour les contacts, EKEventStore pour le calendrier, ATTrackingManager pour le suivi. Pour chaque résultat, vérifie que la clé de description correspondante existe dans ta configuration.
Ce filet attrape les cas que j'ai rencontrés. Il ne remplace pas la lecture de l'e-mail d'Apple, qui reste la seule liste sûre, comme pour les API non publiques d'ITMS-90338. Depuis ce refus, cette vérification passe avant chaque build : elle prend quelques secondes, alors qu'un refus ITMS-90683 coûte un build et le temps de le refaire.
Envoyer ton build sans mauvaise surprise
ITMS-90683 se corrige vite quand on sait le lire, tout comme ITMS-90725, qui vise la version de Xcode. Les refus qui viennent ensuite, ceux d'un reviewer, demandent plus de recul : la démarche est sur la page application refusée par Apple, et les motifs les plus fréquents sont dans pourquoi Apple refuse une app.
Pour vérifier ton dossier avant l'envoi, le Kit Review Apple réunit ma checklist et des skills Claude Code qui relisent ton projet. Si ton envoi bloque et que tu veux un regard humain, réserve une heure avec moi : on reprend ton projet en visio, sur ton écran. Et si tu prépares ta première sortie, fais ton diagnostic gratuit : il remet les étapes dans l'ordre et t'envoie ma checklist anti-refus Apple.
Questions fréquentes
ITMS-90683 est-il un refus d'App Review ?
Pas au sens d'un reviewer humain. C'est un contrôle automatique fait sur le build à sa livraison, avant la mise en revue, comme ITMS-90717 pour l'icône. Personne n'a ouvert ton app. Le build est écarté : il faut corriger l'Info.plist et en envoyer un nouveau.
Pourquoi Apple demande une clé pour une donnée que mon app n'utilise pas ?
Parce qu'Apple analyse le code présent dans le build, pas le comportement de l'app. Si une bibliothèque embarquée fait référence à la photothèque ou à la caméra, la clé de description est exigée, même si aucun écran ne demande jamais cet accès.
Peut-on corriger ITMS-90683 avec une mise à jour à distance ?
Non. La clé manquante se trouve dans l'Info.plist, qui fait partie du binaire. Une mise à jour à distance ne modifie pas ce fichier : il faut refaire un build et le renvoyer à Apple.
Où ajouter NSPhotoLibraryUsageDescription dans un projet Expo ?
Dans ta configuration d'app, sous ios.infoPlist, avec une phrase qui décrit l'usage. Certaines bibliothèques proposent aussi un réglage dédié dans leur plugin, qui peut ajouter d'autres clés, comme un mode d'arrière-plan. Dans les deux cas, la clé doit exister dans la configuration de base, pas seulement dans les fichiers de traduction.
Faut-il retirer les clés de description inutilisées ?
Seulement si plus aucune bibliothèque du build ne fait référence à l'API concernée. Sinon le prochain envoi sera refusé en ITMS-90683. Avant de retirer une clé, cherche le nom de l'API dans le code iOS de tes dépendances.