# ITMS-90683: “Missing purpose string” oplossen met Expo

> ITMS-90683 Missing purpose string: waarom Apple je build weigert, welke sleutel je in app.json zet met Expo en hoe je ontbrekende sleutels vooraf vindt.

Originele pagina: [ITMS-90683: “Missing purpose string” oplossen met Expo](https://devoria.fr/nl/blog/itms-90683-missing-purpose-string-expo)
Auteur: [Mehdi Azizi](https://devoria.fr/nl/mehdi-azizi)
Publicatie: 2026-10-09
Laatste inhoudsrevisie: 2026-10-09


ITMS-90683 is een automatische afwijzing van Apple. Je krijgt hem per e-mail kort nadat je je build hebt verstuurd, nog vóór er een mens naar kijkt. Hij betekent dat er in je Info.plist een zin ontbreekt die uitlegt waarom de app een gevoelig gegeven gebruikt. **Oplossen doe je in twee stappen: zet de sleutel uit het bericht in `ios.infoPlist` en maak een nieuwe build.**

Ik kreeg hem zelf op Solys, mijn wekker met minigames, voor een gegeven dat de app niet eens gebruikt. Hier lees je wat het bericht betekent, waarom je hem krijgt en hoe je hem voorkomt.

## Wat betekent de fout ITMS-90683?

Het volledige bericht heet "ITMS-90683: Missing purpose string in Info.plist". Het zegt dat de code van je app verwijst naar een API die gevoelige gegevens aanraakt (foto's, camera, microfoon, locatie, contacten), en dat je Info.plist de bijbehorende beschrijvingssleutel mist. Het bericht noemt die sleutel, bijvoorbeeld `NSPhotoLibraryUsageDescription`.

Die beschrijvende zin heet een "purpose string". Het is de tekst die iOS laat zien in het venster waarin om toestemming wordt gevraagd. Apple schrijft het in zijn documentatie over [toegang tot beschermde bronnen](https://developer.apple.com/documentation/uikit/requesting-access-to-protected-resources): App Review weigert apps waarvan de code deze bronnen gebruikt zonder purpose string.

Het is geen afwijzing door een reviewer. De controle is automatisch en gebeurt bij de levering van de build, vóór de review, net als [ITMS-91053](https://devoria.fr/nl/blog/itms-91053-missing-api-declaration-expo) voor het privacymanifest. De build wordt geweigerd en je moet een nieuwe sturen.

## Waarom Apple weigert terwijl je app dat gegeven niet gebruikt

Dit is het verrassende deel. **Apple analyseert de code in je build, niet wat je app echt doet.** Bevat een library die je meelevert een verwijzing naar de fotobibliotheek, dan is de sleutel verplicht, ook als geen enkel scherm ooit om toegang tot foto's vraagt. Apple zegt het zelf in het bericht: een externe library of SDK kan naar deze API's verwijzen, en de purpose string blijft verplicht.

Mijn geval, op 26 september 2026. Bij het opschonen van de configuratie van Solys had ik de sleutel `NSPhotoLibraryUsageDescription` weggehaald, want de app doet niets met foto's. De volgende build werd geweigerd met ITMS-90683. De oorzaak: twee Expo-libraries die de app gebruikt, `expo-image` en `expo-file-system`, bevatten code die naar de fotobibliotheek verwijst. De vorige build kwam er wel door, omdat de sleutel er toen nog in stond.

**De les**: je haalt een beschrijvingssleutel niet weg "omdat je hem niet gebruikt". Dat doe je pas als geen enkele library in de build nog naar de API verwijst.

## De meest voorkomende sleutels

- `NSPhotoLibraryUsageDescription`: foto's lezen of schrijven.
- `NSPhotoLibraryAddUsageDescription`: foto's toevoegen, zonder lezen.
- `NSCameraUsageDescription`: camera.
- `NSMicrophoneUsageDescription`: microfoon.
- `NSLocationWhenInUseUsageDescription`: locatie tijdens gebruik.
- `NSContactsUsageDescription`: contacten.
- `NSUserTrackingUsageDescription`: advertentietracking ([App Tracking Transparency](https://devoria.fr/nl/blog/guideline-5-1-2-ai-derden-att-data-delen)).

Apple beschrijft elke sleutel in zijn documentatie, bijvoorbeeld die van [NSPhotoLibraryUsageDescription](https://developer.apple.com/documentation/bundleresources/information-property-list/nsphotolibraryusagedescription): die is verplicht zodra de app een API gebruikt die in de fotobibliotheek leest of schrijft.

## ITMS-90683 oplossen in een Expo-app

1. **Noteer de sleutel uit de e-mail van Apple.** Het bericht geeft de exacte naam.
2. **Zet hem in je configuratie**, onder `ios.infoPlist`, zoals de [Expo-documentatie over permissies](https://docs.expo.dev/guides/permissions/) aangeeft:

```json
{
  "expo": {
    "ios": {
      "infoPlist": {
        "NSPhotoLibraryUsageDescription": "Solys gebruikt je foto's niet. Deze toestemming wordt nooit gevraagd."
      }
    }
  }
}
```

3. **Maak een nieuwe build.** Expo zegt het erbij: een wijziging in de Info.plist gaat niet via een update op afstand, je hebt een nieuw binary nodig.
4. **Stuur de build opnieuw** naar Apple en selecteer hem in je versie.

Een valkuil als je app vertaald is: taalbestanden vertalen een sleutel, ze declareren hem niet. De sleutel moet eerst bestaan in `ios.infoPlist` (of in de configuratie van de betreffende plugin). Anders kan de app crashen bij de eerste aanroep.

## Welke zin schrijf je als je app het gegeven niet gebruikt?

Apple vraagt om een juiste, nuttige en precieze beschrijving. Gebruikt je app het gegeven echt, zeg dan in één zin waarvoor: "De app gebruikt de camera om de barcode van je ticket te scannen."

Staat de sleutel er alleen vanwege een library, dan geeft Apple twee oplossingen: de zin schrijven, of de code verwijderen die het gegeven gebruikt. Komt die code uit een library, dan kun je hem niet zomaar weghalen. Op Solys schreef ik dus gewoon de waarheid: "Solys gebruikt je foto's niet. Deze toestemming wordt nooit gevraagd." Dat is een pragmatische keuze: de volgende build kwam door de levering, maar ik kan je niet beloven dat Apple deze zin altijd accepteert.

## Ontbrekende sleutels vinden vóór het versturen

Vanuit de root van je project toont dit commando de bestanden van libraries waarvan de iOS-code verwijst naar de meest gecontroleerde API's:

```bash
grep -rlE "PHPhotoLibrary|AVCaptureDevice|CLLocationManager|CNContactStore|EKEventStore|ATTrackingManager" \
  node_modules/*/ios node_modules/@*/*/ios
```

Elke naam hoort bij een gegeven: `PHPhotoLibrary` voor foto's, `AVCaptureDevice` voor camera en microfoon, `CLLocationManager` voor locatie, `CNContactStore` voor contacten, `EKEventStore` voor de agenda, `ATTrackingManager` voor tracking. Controleer bij elk resultaat of de bijbehorende beschrijvingssleutel in je configuratie staat.

Dit vangnet vangt de gevallen die ik ben tegengekomen. Het vervangt het lezen van de e-mail van Apple niet: die blijft de enige betrouwbare lijst, net als bij de niet-publieke API's van ITMS-90338. Sinds die afwijzing doe ik deze check vóór elke build: hij kost een paar seconden, terwijl een ITMS-90683 je een build kost plus de tijd om hem opnieuw te maken.

## Je build versturen zonder nare verrassingen

ITMS-90683 los je snel op als je hem kunt lezen, net als ITMS-90725, die over de Xcode-versie gaat. De afwijzingen daarna, die van een reviewer, vragen meer afstand: de aanpak staat op de pagina [app afgewezen door Apple](https://devoria.fr/nl/expertise/app-afgewezen-door-apple), en de meest voorkomende redenen vind je in [waarom Apple een app weigert](https://devoria.fr/nl/blog/app-afgewezen-door-apple-waarom).

Wil je je dossier vóór het versturen checken? De [Apple Review Kit](https://devoria.fr/nl/kits/review-apple) bundelt mijn checklist en Claude Code-skills die je project nalopen. Loopt je inzending vast en wil je een menselijke blik, [boek een uur met mij](https://devoria.fr/nl/coaching): we lopen je project samen door via video, op jouw scherm. En bereid je je eerste release voor, [doe dan je gratis diagnose](https://devoria.fr/nl/diagnostic): die zet de stappen op volgorde en stuurt je mijn checklist tegen Apple-afwijzingen.

## Veelgestelde vragen

### Is ITMS-90683 een afwijzing door App Review?

Niet in de zin van een menselijke reviewer. Het is een automatische controle op de build bij de levering, vóór de review, net als ITMS-90717 voor het icoon. Niemand heeft je app geopend. De build wordt geweigerd: je moet de Info.plist corrigeren en een nieuwe sturen.

### Waarom vraagt Apple een sleutel voor een gegeven dat mijn app niet gebruikt?

Omdat Apple de code in de build analyseert, niet het gedrag van de app. Verwijst een meegeleverde library naar de fotobibliotheek of de camera, dan is de beschrijvingssleutel verplicht, ook als geen enkel scherm ooit om die toegang vraagt.

### Kun je ITMS-90683 oplossen met een update op afstand?

Nee. De ontbrekende sleutel zit in de Info.plist, en die hoort bij het binary. Een update op afstand past dat bestand niet aan: je moet een nieuwe build maken en die opnieuw naar Apple sturen.

### Waar zet je NSPhotoLibraryUsageDescription in een Expo-project?

In je appconfiguratie, onder `ios.infoPlist`, met een zin die het gebruik beschrijft. Sommige libraries bieden ook een eigen instelling in hun plugin, die andere sleutels kan toevoegen, zoals een achtergrondmodus. In beide gevallen moet de sleutel in de basisconfiguratie staan, niet alleen in de vertaalbestanden.

### Moet je ongebruikte beschrijvingssleutels weghalen?

Alleen als geen enkele library in de build nog naar de betreffende API verwijst. Anders wordt je volgende inzending geweigerd met ITMS-90683. Zoek voordat je een sleutel weghaalt de naam van de API op in de iOS-code van je dependencies.


## Je project

[Apple Review Kit](https://devoria.fr/nl/kits/review-apple): De App Store-reviewchecklist die ik gebruik, mijn opgeloste afwijzingen, de notities voor de tester en twee Claude Code-skills die je app nalezen. 29 €.

[iOS Kit](https://devoria.fr/nl/kits/ios): Maak je iPhone-app met Claude Code: de Starter Code van mijn apps, skills die zijn werk controleren, en de Apple Review Kit, App Store Screenshots Kit en ASO Kit. 129,99 €.
