ITMS-90683: cum repari „Missing purpose string” cu Expo
De Mehdi Azizi
Publicat pe , 6 min.
ITMS-90683 Missing purpose string: de ce îți respinge Apple build-ul, ce cheie adaugi în app.json cu Expo și cum găsești cheile lipsă înainte de trimitere.
ITMS-90683 e o respingere automată de la Apple: vine pe e-mail la scurt timp după ce trimiți build-ul, înainte de orice review uman. Înseamnă că în fișierul tău Info.plist lipsește fraza care explică de ce aplicația accesează o dată sensibilă. Reparația înseamnă doi pași: adaugi cheia menționată în mesaj în ios.infoPlist, apoi refaci build-ul.
Am luat-o pe Solys, alarma mea cu mini-jocuri, pentru o dată pe care aplicația nici măcar n-o folosește. Uite ce înseamnă mesajul, de ce apare și cum îl eviți.
Ce înseamnă eroarea ITMS-90683?
Mesajul complet are titlul „ITMS-90683: Missing purpose string in Info.plist”. Spune că codul aplicației tale face referire la un API care atinge date sensibile (poze, cameră, microfon, locație, contacte) și că Info.plist-ul tău nu conține cheia de descriere corespunzătoare. Mesajul numește cheia, de exemplu NSPhotoLibraryUsageDescription.
Fraza asta de descriere se numește „purpose string”. E textul pe care iOS îl afișează în fereastra de cerere a permisiunii. Apple scrie asta în documentația despre accesul la resursele protejate: App Review respinge aplicațiile al căror cod accesează aceste resurse fără purpose string.
Nu e respingerea unui reviewer. Verificarea e automată și are loc la livrarea build-ului, înainte să intre în review, ca ITMS-91053 pentru privacy manifest. Build-ul e respins și trebuie să trimiți altul.
De ce te respinge Apple deși aplicația ta nu folosește data respectivă
Asta e partea care surprinde. Apple analizează codul din build-ul tău, nu ce face aplicația de fapt. Dacă o bibliotecă inclusă conține o referință la biblioteca foto, cheia e obligatorie, chiar dacă niciun ecran nu cere vreodată acces la poze. Mesajul Apple spune asta chiar el: o bibliotecă sau un SDK extern poate face referire la aceste API-uri, iar purpose string-ul rămâne obligatoriu.
Cazul meu, pe 26 septembrie 2026. Când am curățat configurația Solys, am scos cheia NSPhotoLibraryUsageDescription, pentru că aplicația nu atinge nicio poză. Build-ul următor a fost respins cu ITMS-90683. Cauza: două biblioteci Expo pe care le folosește aplicația, expo-image și expo-file-system, conțin cod care face referire la biblioteca foto. Build-ul anterior trecea, pentru că cheia era încă acolo.
Lecția: o cheie de descriere nu se scoate „pentru că n-o folosim”. Se scoate doar când nicio bibliotecă din build nu mai face referire la API.
Cele mai comune chei
NSPhotoLibraryUsageDescription: citirea sau scrierea pozelor.NSPhotoLibraryAddUsageDescription: adăugarea de poze, fără citire.NSCameraUsageDescription: camera.NSMicrophoneUsageDescription: microfonul.NSLocationWhenInUseUsageDescription: locația în timpul utilizării.NSContactsUsageDescription: contactele.NSUserTrackingUsageDescription: urmărirea publicitară (App Tracking Transparency).
Apple descrie fiecare cheie în documentație, de exemplu pe cea pentru NSPhotoLibraryUsageDescription: e obligatorie de îndată ce aplicația folosește un API care citește sau scrie în biblioteca foto.
Cum repari ITMS-90683 într-o aplicație Expo
- Notează cheia menționată în e-mailul de la Apple. Mesajul îi dă numele exact.
- Adaug-o în configurație, sub
ios.infoPlist, cum arată documentația Expo despre permisiuni:
{
"expo": {
"ios": {
"infoPlist": {
"NSPhotoLibraryUsageDescription": "Solys nu accesează pozele tale. Această permisiune nu este cerută niciodată."
}
}
}
}
- Refă build-ul. Expo precizează: o modificare în Info.plist nu trece printr-un update la distanță, are nevoie de un binar nou.
- Retrimite build-ul la Apple, apoi selectează-l în versiunea ta.
O capcană dacă aplicația ta e tradusă: fișierele de limbă traduc o cheie, nu o declară. Cheia trebuie să existe mai întâi în ios.infoPlist (sau în configurația plugin-ului respectiv). Altfel aplicația poate crăpa la primul apel.
Ce frază scrii dacă aplicația nu folosește data?
Apple cere o descriere exactă, utilă și precisă. Dacă aplicația chiar folosește data, spune la ce îi trebuie, într-o frază: „Aplicația folosește camera ca să scaneze codul de bare de pe biletul tău.”
Dacă cheia e acolo doar din cauza unei biblioteci, Apple dă două soluții: scrii fraza sau scoți codul care accesează data. Când codul vine dintr-o bibliotecă, nu-l poți scoate pur și simplu. Pe Solys am scris deci adevărul: „Solys nu accesează pozele tale. Această permisiune nu este cerută niciodată.” E o alegere pragmatică: build-ul următor a trecut la livrare, dar nu-ți pot spune că Apple va accepta mereu fraza asta.
Cum găsești cheile lipsă înainte de trimitere
Din rădăcina proiectului, comanda asta listează fișierele bibliotecilor al căror cod iOS face referire la cele mai monitorizate API-uri:
grep -rlE "PHPhotoLibrary|AVCaptureDevice|CLLocationManager|CNContactStore|EKEventStore|ATTrackingManager" \
node_modules/*/ios node_modules/@*/*/ios
Fiecare nume corespunde unei date: PHPhotoLibrary pentru poze, AVCaptureDevice pentru cameră și microfon, CLLocationManager pentru locație, CNContactStore pentru contacte, EKEventStore pentru calendar, ATTrackingManager pentru urmărire. Pentru fiecare rezultat, verifică dacă cheia de descriere corespunzătoare există în configurația ta.
Plasa asta prinde cazurile pe care le-am întâlnit. Nu înlocuiește citirea e-mailului de la Apple, care rămâne singura listă sigură, ca pentru API-urile non-publice din ITMS-90338. De la respingerea asta, verificarea vine înaintea fiecărui build: durează câteva secunde, pe când o respingere ITMS-90683 te costă un build și timpul să-l refaci.
Trimite-ți build-ul fără surprize neplăcute
ITMS-90683 se repară repede când știi să-l citești, la fel ca ITMS-90725, care vizează versiunea de Xcode. Respingerile care vin după, cele de la un reviewer, cer mai mult discernământ: pașii sunt pe pagina aplicație respinsă de Apple, iar cele mai frecvente motive sunt în de ce respinge Apple o aplicație.
Ca să-ți verifici dosarul înainte de trimitere, Apple Review Kit adună checklist-ul meu și skill-uri Claude Code care îți recitesc proiectul. Dacă trimiterea ți se blochează și vrei o privire umană, rezervă o oră cu mine: reluăm proiectul tău pe video, pe ecranul tău. Și dacă îți pregătești prima lansare, fă-ți diagnosticul gratuit: îți pune pașii în ordine și îți trimite checklist-ul meu anti-respingere Apple.
Întrebări frecvente
ITMS-90683 e o respingere de la App Review?
Nu în sensul unui reviewer uman. E o verificare automată făcută pe build la livrare, înainte să intre în review, ca ITMS-90717 pentru iconiță. Nimeni nu ți-a deschis aplicația. Build-ul e respins: trebuie să corectezi Info.plist și să trimiți unul nou.
De ce cere Apple o cheie pentru o dată pe care aplicația mea n-o folosește?
Pentru că Apple analizează codul din build, nu comportamentul aplicației. Dacă o bibliotecă inclusă face referire la biblioteca foto sau la cameră, cheia de descriere e obligatorie, chiar dacă niciun ecran nu cere vreodată accesul ăsta.
Pot repara ITMS-90683 cu un update la distanță?
Nu. Cheia lipsă se află în Info.plist, care face parte din binar. Un update la distanță nu modifică fișierul ăsta: trebuie să refaci build-ul și să-l retrimiți la Apple.
Unde adaug NSPhotoLibraryUsageDescription într-un proiect Expo?
În configurația aplicației, sub ios.infoPlist, cu o frază care descrie utilizarea. Unele biblioteci oferă și o setare dedicată în plugin, care poate adăuga alte chei, cum ar fi un mod de fundal. În ambele cazuri, cheia trebuie să existe în configurația de bază, nu doar în fișierele de traducere.
Trebuie să scot cheile de descriere nefolosite?
Doar dacă nicio bibliotecă din build nu mai face referire la API-ul respectiv. Altfel, următoarea trimitere va fi respinsă cu ITMS-90683. Înainte să scoți o cheie, caută numele API-ului în codul iOS al dependențelor tale.