# ITMS-91053: popravi »Missing API declaration« v Expo

> ITMS-91053: tvoj build uporablja API z obveznim razlogom, ne da bi ga prijavil. Dodaj kategorijo in kodo v ios.privacyManifests ter naredi nov build.

Izvirna stran: [ITMS-91053: popravi »Missing API declaration« v Expo](https://devoria.fr/sl/blog/itms-91053-missing-api-declaration-expo)
Avtor: [Mehdi Azizi](https://devoria.fr/sl/mehdi-azizi)
Objava: 2026-10-25
Zadnja revizija vsebine: 2026-10-25


ITMS-91053 je Applovo samodejno preverjanje, ki ga dobiš po e-pošti po [oddaji builda](https://devoria.fr/sl/blog/eas-submit-ios-objava-aplikacije-expo-app-store). Pove ti, da koda tvoje aplikacije uporablja API »z obveznim razlogom« (nastavitve, datumi datotek, čas od zagona, prostor na disku ali tipkovnice), ne da bi v manifestu zasebnosti pojasnila, zakaj. **V Expu to popraviš v `ios.privacyManifests`: kategorija, ki jo navaja Apple, koda, ki opisuje tvojo dejansko uporabo, nato nov build.**

V Solysu, mojem budilniku z mini igrami, so ti razlogi prijavljeni v konfiguraciji aplikacije. Tukaj je njegova dejanska prijava, ukaz, ki izpiše, kaj uporabljajo tvoje odvisnosti, in preverjanje končne datoteke pred oddajo.

## Kaj pomeni napaka ITMS-91053?

Sporočilo ima naslov »ITMS-91053: Missing API declaration«. Pove, da koda v točno določeni datoteki tvojega builda kliče enega ali več API-jev, ki zahtevajo razlog. Nato našteje kategorije, na primer `NSPrivacyAccessedAPICategoryUserDefaults`.

Ti API-ji od uporabnika ne zahtevajo nobenega dovoljenja. Lahko pa služijo za prepoznavanje naprave, kar Apple imenuje fingerprinting. To je prepovedano, tudi če uporabnik sledenje sprejme. Apple to razloži na strani o [API-jih z obveznim razlogom](https://developer.apple.com/documentation/bundleresources/describing-use-of-required-reason-api): vsaka aplikacija in vsak SDK mora prijaviti, zakaj jih uporablja.

Ista stran postavi pravilo: **od 1. maja 2024 App Store Connect ne sprejme več aplikacije, ki teh uporab ne opiše v svojem manifestu.** Nekateri razvijalci so ta e-mail dobili le kot opozorilo, pri sprejetem buildu. Ne zanašaj se na to: obravnavaj ga kot blokado in popravi pred naslednjo oddajo.

Kot pri drugih napakah ITMS to ni zavrnitev recenzenta. Nihče ni odprl tvoje aplikacije: Apple je analiziral binarno datoteko.

## Privacy manifest za iOS: datoteka PrivacyInfo.xcprivacy

Manifest zasebnosti je datoteka z imenom `PrivacyInfo.xcprivacy` v korenu bundla aplikacije. Po [Applovi dokumentaciji o privacy manifestih](https://developer.apple.com/documentation/bundleresources/privacy-manifest-files) opisuje zbrane podatke, sledenje in API-je z obveznim razlogom. Ti gredo v tabelo `NSPrivacyAccessedAPITypes`: en vnos na kategorijo, z njenim tipom in seznamom razlogov.

Past: **manifest pokriva samo svoj bundle.** Apple to napiše: vsaka izvršljiva datoteka ali dinamična knjižnica, ki uporablja te API-je, mora imeti manifest v svojem bundlu. Manifest tvoje aplikacije ne pokriva vgrajenega frameworka, SDK pa se ne more zanašati na manifest tvoje aplikacije.

Ne zamenjaj ga s stavki v Info.plist, ki jih zahteva [ITMS-90683](https://devoria.fr/sl/blog/itms-90683-missing-purpose-string-expo). Ti se uporabniku prikažejo v prošnji za dovoljenje. Manifest pa bere samo Apple.

## 5 kategorij API-jev in njihove kode razlogov

Polno ime kategorije se začne z `NSPrivacyAccessedAPICategory`. Seznam API-jev in razlogov je na strani ključa [NSPrivacyAccessedAPIType](https://developer.apple.com/documentation/bundleresources/app-privacy-configuration/nsprivacyaccessedapitypes/nsprivacyaccessedapitype), prebrano 15. oktobra 2026.

| Kategorija      | Tipičen API                  | Pogost razlog |
| --------------- | ---------------------------- | ------------- |
| UserDefaults    | `UserDefaults`               | CA92.1        |
| FileTimestamp   | `creationDate`               | C617.1        |
| SystemBootTime  | `systemUptime`               | 35F9.1        |
| DiskSpace       | `volumeAvailableCapacityKey` | E174.1        |
| ActiveKeyboards | `activeInputModes`           | 54BD.1        |

Kode, na katere boš naletel najpogosteje:

- **CA92.1**: aplikacija bere in piše svoje lastne nastavitve, ki drugim aplikacijam niso dostopne.
- **1C8F.1**: nastavitve, deljene z widgetom ali razširitvijo v isti App Group.
- **C617.1**: datumi ali velikost datotek v vsebniku aplikacije.
- **3B52.1**: datoteke, ki jih je izbral uporabnik, na primer v izbirniku dokumentov.
- **35F9.1**: merjenje časa med dvema dogodkoma v aplikaciji ali poganjanje časovnika.
- **E174.1**: preverjanje prostega prostora pred pisanjem datotek, z učinkom, ki ga uporabnik vidi.
- **85F4.1**: prikaz prostora na disku uporabniku.

**Prijavi razlog, ki ustreza tvoji dejanski uporabi, ne tistega, ki se zdi najširši.** Apple poudarja, da se ti API-ji in njihovi podatki uporabljajo samo za prijavljene razloge in nikoli za sledenje. Dve kodi sta rezervirani za SDK-je tretjih oseb: C56D.1 in 0A2A.1. V manifestu tvoje aplikacije jima ni mesta.

## Prijava privacy manifesta v Expu

V Expu datoteke ne pišeš sam. Opišeš jo pod `expo.ios.privacyManifests`, v app.json ali app.config, prebuild pa ustvari `PrivacyInfo.xcprivacy`. To je metoda iz [Expove dokumentacije o privacy manifestih](https://docs.expo.dev/guides/apple-privacy/).

Tu je dejanski izsek konfiguracije Solysa. Ključ vsebuje tudi sledenje in zbrane podatke, ki sem jih tu odstranil:

```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 in 35F9.1 povzemajo, kar prijavljajo React Native in Expo moduli aplikacije. 1C8F.1 prihaja iz samega Solysa: aplikacija si nastavitve deli s svojim widgetom prek App Groupa.

Past, ki jo moraš poznati: če je tvoja mapa `ios` generirana in jo git ignorira, **ročno napisan `PrivacyInfo.xcprivacy` v tej mapi nikoli ne pride v build.** EAS znova zažene prebuild in mapo ustvari na novo. To sem opazil na enem svojih projektov 9. septembra 2026: ročno napisan manifest je po prebuildu izginil. Prijava mora živeti v konfiguraciji.

Še zadnje: manifest je del binarne datoteke. Posodobitev na daljavo ga ne spremeni. Narediti moraš nov build in ga znova oddati.

## SDK-ji tretjih oseb z lastnim manifestom

Večina novejših knjižnic ima svoj manifest. Expo paketi, ki uporabljajo te API-je, imajo `PrivacyInfo.xcprivacy` v svoji mapi `ios`, prav tako React Native. Težava je v tem, kako so povezani s tvojo aplikacijo.

Expova dokumentacija opozarja: Apple ne prebere pravilno vseh manifestov statično povezanih odvisnosti CocoaPods, kar velja za Expo pakete. Zato boš morda moral njihove razloge prepisati v konfiguracijo svoje aplikacije.

Da to delo zmanjšaš, nastavitev `ios.privacyManifestAggregationEnabled` v [expo-build-properties](https://docs.expo.dev/versions/latest/sdk/build-properties/) združi manifeste odvisnosti CocoaPods v eno datoteko. V Podfilu, ki ga Expo ustvari na mojih projektih (SDK 57), je to združevanje vklopljeno, razen če ga izklopiš.

Združevanje ima omejitev: vidi samo odvisnosti, ki imajo manifest. Starejša knjižnica brez njega ostane nevidna. **Zato preberi pot datoteke, navedeno v e-mailu**: pove ti, kje popraviti.

| Navedena datoteka              | Kje popraviti          |
| ------------------------------ | ---------------------- |
| Izvršljiva datoteka aplikacije | `ios.privacyManifests` |
| `.framework`                   | Posodobi SDK           |
| Razširitev `.appex`            | Manifest razširitve    |

## Preverjanje pred oddajo

Expo predlaga, da po oddaji počakaš na Applov e-mail. Deluje, a vsak krog stane en build. Tukaj so štiri preverjanja, ki jih naredim prej.

**1. Izpiši, kaj prijavljajo tvoje odvisnosti.** Iz korena projekta:

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

Na Solysu je ukaz 15. oktobra 2026 našel 13 manifestov in štiri kategorije: datumi datotek, nastavitve, čas od zagona in prostor na disku. Vsaka izpisana kategorija mora biti v končnem manifestu aplikacije ali v manifestu frameworka, ki jo uporablja.

**2. Preišči svojo nativno kodo.** Lastni moduli, vtičniki, cilji, kot je widget: te kode noben SDK ne prijavi namesto tebe.

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

Mape prilagodi svojemu projektu. Na Solysu je prav to iskanje razkrilo nastavitve, deljene prek App Groupa, od tod koda 1C8F.1.

**3. Preberi ustvarjeni manifest.** Zaženi `npx expo prebuild -p ios`, nato odpri `ios/<ImeTvojeAplikacije>/PrivacyInfo.xcprivacy`. Pozor: ta ukaz lahko mapo `ios` izbriše in ustvari na novo. Če si v njej kaj spreminjal ročno, delaj na kopiji projekta.

**4. Preveri končni build.** To je edini dokaz, ki šteje. Prenesi IPA s strani builda na expo.dev, nato na Macu zaženi:

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

Druga vrstica izpiše vse vgrajene manifeste, aplikacijin in tiste iz frameworkov. Tretja prikaže manifest aplikacije, ki ga primerjaš s seznamom iz 1. koraka.

## Kaj mora manifest povedati skupaj s tvojo stranjo v trgovini

Manifest ne živi sam. Če prijavlja sledenje ali zbrane podatke, morata tvoja stran v App Storu in tvoja politika zasebnosti povedati isto. Neskladje med vsemi tremi te lahko pozneje stane človeške zavrnitve po [guideline 5.1.1](https://devoria.fr/sl/blog/smernica-5-1-1-zavrnitev-app-store). Kaj uskladiti, je podrobno opisano v članku [politika zasebnosti za aplikacijo](https://devoria.fr/sl/blog/politika-zasebnosti-aplikacija-ios).

## Oddaj build brez neprijetnih presenečenj

Napake ITMS se hitro popravijo, ko jih znaš brati. Zavrnitve, ki pridejo potem, zahtevajo več razmisleka: postopek je na strani [aplikacija, ki jo je Apple zavrnil](https://devoria.fr/sl/expertise/apple-zavrnil-aplikacijo), najpogostejši razlogi pa v članku [zakaj Apple zavrne aplikacijo](https://devoria.fr/sl/blog/apple-zavrnil-aplikacijo-razlogi).

Da preveriš svojo oddajo, [Apple Review Kit](https://devoria.fr/sl/kits/review-apple) združuje moj kontrolni seznam in skille za Claude Code, ki pregledajo tvoj projekt. Če se ti oddaja zatakne in želiš človeški pogled, [rezerviraj uro z mano](https://devoria.fr/sl/coaching): projekt pregledava prek videoklica, na tvojem zaslonu. Če pa pripravljaš prvo izdajo, [naredi brezplačno diagnostiko](https://devoria.fr/sl/diagnostic): korake postavi v pravi vrstni red in ti pošlje moj kontrolni seznam proti Applovim zavrnitvam.

## Pogosta vprašanja

### Ali ITMS-91053 blokira oddajo mojega builda?

Apple piše, da od 1. maja 2024 App Store Connect ne sprejema več aplikacij, ki ne opišejo uporabe teh API-jev. Nekateri razvijalci so e-mail kljub temu dobili pri sprejetem buildu, kot opozorilo. V obeh primerih popravi manifest pred naslednjim buildom.

### Katero kodo razloga izbrati za UserDefaults?

CA92.1, če aplikacija bere in piše samo svoje nastavitve. Dodaj 1C8F.1, če jih deli z widgetom ali razširitvijo prek App Groupa. C56D.1 je rezervirana za SDK-je tretjih oseb: ne daj je v manifest svoje aplikacije.

### Ali moram manifest vsakega SDK-ja prepisati v app.json?

Ne nujno. Če je združevanje manifestov vklopljeno, se manifesti odvisnosti CocoaPods združijo ob namestitvi podov. Kategorijo prepiši samo, če manjka v končnem manifestu, z razlogom, ki opisuje dejansko uporabo.

### Ali moj widget ali razširitev potrebuje svoj manifest?

Po Applu mora imeti vsak bundle z izvršljivo datoteko, ki uporablja te API-je, svoj manifest. Razširitev je ločena izvršljiva datoteka v svojem bundlu: manifest aplikacije je ne pokriva.

### Ali lahko ITMS-91053 popravim brez novega builda?

Ne. Manifest zasebnosti je del binarne datoteke. Popravi konfiguracijo, naredi nov build in ga preizkusi v [TestFlightu](https://devoria.fr/sl/blog/testflight-testiranje-aplikacije-iphone), preden ga oddaš v pregled.


## Tvoj projekt

[Apple Review Kit](https://devoria.fr/sl/kits/review-apple): Kontrolni seznam za App Store review, ki ga uporabljam, moje popravljene zavrnitve, opombe za preizkuševalca in dva skilla Claude Code, ki pregledata tvojo aplikacijo. 29 €.

[iOS Kit](https://devoria.fr/sl/kits/ios): Ustvari aplikacijo za iPhone s Claude Code: začetna koda mojih aplikacij, skilli, ki preverjajo njegovo delo, ter Apple Review Kit, App Store Screenshots Kit in ASO Kit. 129,99 €.
