# ITMS-91053: risolvere “Missing API declaration” con Expo

> ITMS-91053: la tua build usa un'API a motivazione obbligatoria senza dichiararla. Aggiungi categoria e codice in ios.privacyManifests e rifai la build.

Pagina originale: [ITMS-91053: risolvere “Missing API declaration” con Expo](https://devoria.fr/it/blog/itms-91053-missing-api-declaration-expo)
Autore: [Mehdi Azizi](https://devoria.fr/it/mehdi-azizi)
Pubblicazione: 2026-10-25
Ultima revisione dei contenuti: 2026-10-25


ITMS-91053 è un controllo automatico di Apple, inviato via e-mail dopo [la consegna della tua build](https://devoria.fr/it/blog/eas-submit-ios-pubblicare-app-expo-app-store). Ti dice che il codice della tua app usa un'API "a motivazione obbligatoria" (preferenze, date dei file, tempo dall'avvio, spazio su disco o tastiere) senza spiegare perché nel suo manifest della privacy. **Con Expo la correzione si fa in `ios.privacyManifests`: la categoria citata da Apple, il codice che descrive il tuo uso reale, poi una nuova build.**

Su Solys, la mia sveglia con minigiochi, queste motivazioni sono dichiarate nella configurazione dell'app. Qui trovi la sua dichiarazione reale, il comando che elenca cosa usano le tue dipendenze e il controllo da fare sul file finale prima dell'invio.

## Cosa significa l'errore ITMS-91053?

Il messaggio si intitola "ITMS-91053: Missing API declaration". Indica che il codice di un file preciso della tua build fa riferimento a una o più API che richiedono una motivazione. Poi elenca le categorie in questione, per esempio `NSPrivacyAccessedAPICategoryUserDefaults`.

Queste API non chiedono nessuna autorizzazione all'utente. Però possono servire a riconoscere un dispositivo, quello che Apple chiama fingerprinting. È vietato, anche quando l'utente accetta il tracciamento. Apple lo spiega nella sua pagina sulle [API a motivazione obbligatoria](https://developer.apple.com/documentation/bundleresources/describing-use-of-required-reason-api): ogni app e ogni SDK deve dichiarare perché le usa.

La stessa pagina fissa la regola: **dal 1° maggio 2024 App Store Connect non accetta più un'app che non descrive questi usi nel suo manifest.** Alcuni sviluppatori hanno segnalato questa e-mail come un semplice avviso, su una build accettata. Non contarci: trattala come un blocco e correggi prima del prossimo invio.

Come gli altri errori ITMS, non è il rifiuto di un reviewer. Nessuno ha aperto la tua app: Apple ha analizzato il binario.

## Il privacy manifest iOS: il file PrivacyInfo.xcprivacy

Il manifest della privacy è un file chiamato `PrivacyInfo.xcprivacy`, posizionato nella radice del bundle dell'app. Secondo la [documentazione di Apple sui privacy manifest](https://developer.apple.com/documentation/bundleresources/privacy-manifest-files), descrive i dati raccolti, il tracciamento e le API a motivazione obbligatoria. Queste ultime vanno nell'array `NSPrivacyAccessedAPITypes`: una voce per categoria, con il suo tipo e l'elenco delle sue motivazioni.

Il punto che frega: **un manifest copre solo il proprio bundle.** Apple lo scrive: ogni eseguibile o libreria dinamica che usa queste API deve avere un manifest nel proprio bundle. Quello della tua app non copre un framework incorporato, e un SDK non può contare su quello della tua app.

Non confonderlo con le frasi dell'Info.plist richieste da [ITMS-90683](https://devoria.fr/it/blog/itms-90683-missing-purpose-string-expo). Quelle vengono mostrate all'utente in una richiesta di autorizzazione. Il manifest invece lo legge solo Apple.

## Le 5 categorie di API e i loro codici di motivazione

Il nome completo di una categoria inizia con `NSPrivacyAccessedAPICategory`. L'elenco delle API e delle motivazioni si trova nella pagina della chiave [NSPrivacyAccessedAPIType](https://developer.apple.com/documentation/bundleresources/app-privacy-configuration/nsprivacyaccessedapitypes/nsprivacyaccessedapitype), consultata il 15 ottobre 2026.

| Categoria       | API tipica                   | Motivazione comune |
| --------------- | ---------------------------- | ------------------ |
| UserDefaults    | `UserDefaults`               | CA92.1             |
| FileTimestamp   | `creationDate`               | C617.1             |
| SystemBootTime  | `systemUptime`               | 35F9.1             |
| DiskSpace       | `volumeAvailableCapacityKey` | E174.1             |
| ActiveKeyboards | `activeInputModes`           | 54BD.1             |

I codici che incontrerai più spesso:

- **CA92.1**: l'app legge e scrive le proprie preferenze, inaccessibili alle altre app.
- **1C8F.1**: preferenze condivise con un widget o un'estensione dello stesso App Group.
- **C617.1**: date o dimensioni di file salvati nel container dell'app.
- **3B52.1**: file scelti dall'utente, per esempio in un selettore di documenti.
- **35F9.1**: misurare il tempo trascorso tra due eventi dell'app, o far girare un timer.
- **E174.1**: verificare lo spazio libero prima di scrivere file, con un effetto visibile per l'utente.
- **85F4.1**: mostrare lo spazio su disco all'utente.

**Dichiara la motivazione che corrisponde al tuo uso reale, non quella che sembra più ampia.** Apple precisa che queste API e i loro dati servono solo alle motivazioni dichiarate, e mai al tracciamento. Due codici sono riservati agli SDK di terze parti: C56D.1 e 0A2A.1. Non vanno nel manifest della tua app.

## Dichiarare il privacy manifest in Expo

Con Expo il file non lo scrivi tu. Lo descrivi sotto `expo.ios.privacyManifests`, in app.json o app.config, e il prebuild genera `PrivacyInfo.xcprivacy`. È il metodo della [documentazione di Expo sui privacy manifest](https://docs.expo.dev/guides/apple-privacy/).

Ecco l'estratto reale della configurazione di Solys. La chiave contiene anche il tracciamento e i dati raccolti, qui rimossi:

```json
{
  "expo": {
    "ios": {
      "privacyManifests": {
        "NSPrivacyAccessedAPITypes": [
          {
            "NSPrivacyAccessedAPIType": "NSPrivacyAccessedAPICategoryUserDefaults",
            "NSPrivacyAccessedAPITypeReasons": ["CA92.1", "1C8F.1"]
          },
          {
            "NSPrivacyAccessedAPIType": "NSPrivacyAccessedAPICategoryFileTimestamp",
            "NSPrivacyAccessedAPITypeReasons": ["C617.1"]
          },
          {
            "NSPrivacyAccessedAPIType": "NSPrivacyAccessedAPICategorySystemBootTime",
            "NSPrivacyAccessedAPITypeReasons": ["35F9.1"]
          }
        ]
      }
    }
  }
}
```

CA92.1, C617.1 e 35F9.1 riprendono quello che dichiarano React Native e i moduli Expo dell'app. 1C8F.1 viene da Solys stessa: l'app condivide impostazioni con il suo widget tramite un App Group.

Una trappola da conoscere: se la tua cartella `ios` è generata e ignorata da git, **un `PrivacyInfo.xcprivacy` scritto a mano in quella cartella non arriva mai nella build.** EAS rilancia il prebuild e rigenera la cartella. L'ho verificato su uno dei miei progetti il 9 settembre 2026: il manifest scritto a mano era sparito dopo un prebuild. La dichiarazione deve stare nella configurazione.

Ultimo punto: il manifest fa parte del binario. Un aggiornamento remoto non lo modifica. Devi rifare una build e reinviarla.

## Gli SDK di terze parti che includono il proprio manifest

La maggior parte delle librerie recenti fornisce il proprio manifest. I pacchetti Expo che usano queste API hanno un `PrivacyInfo.xcprivacy` nella loro cartella `ios`, proprio come React Native. Il problema sta nel modo in cui sono collegati alla tua app.

La documentazione di Expo avverte: Apple non legge correttamente tutti i manifest delle dipendenze CocoaPods collegate staticamente, ed è il caso dei pacchetti Expo. Quindi potresti dover ricopiare le loro motivazioni nella configurazione della tua app.

Per limitare questo lavoro, l'impostazione `ios.privacyManifestAggregationEnabled` di [expo-build-properties](https://docs.expo.dev/versions/latest/sdk/build-properties/) unisce i manifest delle dipendenze CocoaPods in un unico file. Nel Podfile che Expo genera sui miei progetti (SDK 57), questa unione è attiva, a meno che tu non la disattivi.

L'unione ha un limite: vede solo le dipendenze che forniscono un manifest. Una libreria vecchia che non ce l'ha resta invisibile. **Leggi quindi il percorso del file citato nell'e-mail**: ti dice dove correggere.

| File citato            | Dove correggere          |
| ---------------------- | ------------------------ |
| L'eseguibile dell'app  | `ios.privacyManifests`   |
| Un `.framework`        | Aggiornare l'SDK         |
| Un'estensione `.appex` | Manifest dell'estensione |

## Verificare prima dell'invio

Expo propone di aspettare l'e-mail di Apple dopo un invio. Funziona, ma ogni andata e ritorno costa una build. Ecco i quattro controlli che faccio prima.

**1. Elenca cosa dichiarano le tue dipendenze.** Dalla radice del progetto:

```bash
find node_modules -name PrivacyInfo.xcprivacy -not -path '*/example/*' \
  -exec grep -ho "NSPrivacyAccessedAPICategory[A-Za-z]*" {} + | sort | uniq -c
```

Su Solys, il 15 ottobre 2026, il comando trova 13 manifest e quattro categorie: date dei file, preferenze, tempo dall'avvio e spazio su disco. Ogni categoria elencata deve comparire nel manifest finale dell'app, o in quello del framework che la usa.

**2. Cerca nel tuo codice nativo.** Moduli tuoi, plugin, target come un widget: questo codice nessun SDK lo dichiara al posto tuo.

```bash
grep -rlE "UserDefaults|systemUptime|mach_absolute_time|creationDate|modificationDate|volumeAvailableCapacity|activeInputModes" \
  --include='*.swift' --include='*.m' --include='*.mm' modules plugins targets
```

Adatta le cartelle al tuo progetto. Su Solys è questa ricerca a far emergere le preferenze condivise tramite App Group, da cui il codice 1C8F.1.

**3. Leggi il manifest generato.** Lancia `npx expo prebuild -p ios`, poi apri `ios/<NomeDellaTuaApp>/PrivacyInfo.xcprivacy`. Attenzione: questo comando può cancellare e ricreare la cartella `ios`. Se ci hai fatto modifiche a mano, lavora su una copia del progetto.

**4. Controlla la build finale.** È l'unica prova che conta. Scarica l'IPA dalla pagina della build su expo.dev, poi lancia sul tuo Mac:

```bash
unzip -q MyApp.ipa -d ipa
find ipa/Payload -name PrivacyInfo.xcprivacy
plutil -p ipa/Payload/*.app/PrivacyInfo.xcprivacy
```

La seconda riga elenca tutti i manifest inclusi, quello dell'app e quelli dei framework. La terza mostra quello dell'app, da confrontare con l'elenco del passaggio 1.

## Cosa deve raccontare il manifest insieme alla tua scheda

Il manifest non vive da solo. Se dichiara tracciamento o dati raccolti, la tua scheda App Store e la tua privacy policy devono dire la stessa cosa. Una differenza tra i tre può poi costarti un rifiuto umano, ai sensi della [guideline 5.1.1](https://devoria.fr/it/blog/guideline-5-1-1-rifiuto-app-store). Cosa allineare è spiegato in dettaglio in [privacy policy di un'app](https://devoria.fr/it/blog/privacy-policy-app-ios-apple).

## Inviare la tua build senza brutte sorprese

Gli errori ITMS si correggono in fretta quando sai leggerli. I rifiuti che arrivano dopo richiedono più distacco: il procedimento è nella pagina [app rifiutata da Apple](https://devoria.fr/it/expertise/app-rifiutata-da-apple), e i motivi più frequenti sono in [perché Apple rifiuta un'app](https://devoria.fr/it/blog/app-rifiutata-da-apple-perche-casi-reali).

Per verificare il tuo progetto prima dell'invio, l'[Apple Review Kit](https://devoria.fr/it/kits/review-apple) raccoglie la mia checklist e delle skill di Claude Code che rileggono il tuo progetto. Se il tuo invio è bloccato e vuoi uno sguardo umano, [prenota un'ora con me](https://devoria.fr/it/coaching): riprendiamo il tuo progetto in videochiamata, sul tuo schermo. E se stai preparando la tua prima uscita, [fai il tuo diagnostico gratuito](https://devoria.fr/it/diagnostic): rimette i passaggi in ordine e ti manda la mia checklist anti-rifiuto Apple.

## Domande frequenti

### ITMS-91053 blocca l'invio della mia build?

Apple scrive che dal 1° maggio 2024 App Store Connect non accetta più le app che non descrivono il loro uso di queste API. Eppure alcuni sviluppatori hanno ricevuto l'e-mail su una build accettata, come un avviso. In entrambi i casi, correggi il manifest prima della prossima build.

### Quale codice di motivazione scegliere per UserDefaults?

CA92.1 se l'app legge e scrive solo le proprie preferenze. Aggiungi 1C8F.1 se le condivide con un widget o un'estensione tramite un App Group. C56D.1 è riservato agli SDK di terze parti: non metterlo nel manifest della tua app.

### Devo ricopiare il manifest di ogni SDK in app.json?

Non per forza. Se l'unione dei manifest è attiva, quelli delle dipendenze CocoaPods vengono riuniti durante l'installazione dei pod. Ricopia una categoria solo se manca nel manifest finale, con la motivazione che descrive l'uso reale.

### Il mio widget o la mia estensione ha bisogno di un proprio manifest?

Secondo Apple, ogni bundle che contiene un eseguibile che usa queste API deve avere il proprio manifest. Un'estensione è un eseguibile a parte, nel suo bundle: il manifest dell'app non la copre.

### Si può correggere ITMS-91053 senza rifare una build?

No. Il manifest della privacy fa parte del binario. Correggi la configurazione, rifai una build, poi testala su [TestFlight](https://devoria.fr/it/blog/testflight-testare-app-iphone-prima-invio) prima di inviarla in revisione.


## Il tuo progetto

[Apple Review Kit](https://devoria.fr/it/kits/review-apple): La checklist review App Store che uso, i miei rifiuti di Apple corretti, le note per il revisore e due skill Claude Code che rileggono la tua app. 29 €.

[iOS Kit](https://devoria.fr/it/kits/ios): Crea la tua app iPhone con Claude Code: lo Starter Code delle mie app, gli skill che verificano il suo lavoro, e l'Apple Review Kit, l'App Store Screenshots Kit e l'ASO Kit. 129,99 €.
