ITMS-91053: a „Missing API declaration” javítása Expóval
Írta: Mehdi Azizi
Megjelent: , 8 p
ITMS-91053: a buildod indokolást igénylő API-t használ, de nem deklarálja. Add meg a kategóriát és a kódot az ios.privacyManifests alatt, majd buildelj újra.
Az ITMS-91053 az Apple automatikus ellenőrzése, amelyet e-mailben küld, miután feltöltötted a buildet. Azt jelzi, hogy az appod kódja egy „indokolást igénylő” API-t használ (beállítások, fájlok dátumai, indulás óta eltelt idő, lemezterület vagy billentyűzetek), de az adatvédelmi manifest nem magyarázza meg, miért. Expóval a javítás az ios.privacyManifests alatt történik: az Apple által megnevezett kategória, a valós használatodat leíró kód, aztán egy új build.
A Solysban, a minijátékos ébresztőórámban ezek az indokok az app konfigurációjában vannak deklarálva. Megmutatom a valós deklarációt, a parancsot, amely kilistázza, mit használnak a függőségeid, és az ellenőrzést, amit a végleges fájlon érdemes elvégezni küldés előtt.
Mit jelent az ITMS-91053 hiba?
Az üzenet címe: „ITMS-91053: Missing API declaration”. Azt jelzi, hogy a buildod egy adott fájljának kódja egy vagy több olyan API-ra hivatkozik, amelyhez indokolás kell. Aztán felsorolja az érintett kategóriákat, például NSPrivacyAccessedAPICategoryUserDefaults.
Ezek az API-k nem kérnek engedélyt a felhasználótól. Viszont alkalmasak lehetnek egy eszköz azonosítására, ezt az Apple fingerprintingnek hívja. Ez tilos, még akkor is, ha a felhasználó elfogadja a követést. Az Apple ezt az indokolást igénylő API-król szóló oldalán magyarázza el: minden appnak és minden SDK-nak deklarálnia kell, miért használja őket.
Ugyanez az oldal rögzíti a szabályt: 2024. május 1. óta az App Store Connect nem fogad el olyan appot, amely nem írja le ezeket a használatokat a manifestjében. Egyes fejlesztők szerint ez az e-mail csak figyelmeztetésként jött, egy elfogadott buildre. Ne számíts erre: kezeld blokkolásként, és javítsd a következő küldés előtt.
A többi ITMS-hibához hasonlóan ez sem egy reviewer elutasítása. Senki nem nyitotta meg az appodat: az Apple a binárist elemezte.
Az iOS privacy manifest: a PrivacyInfo.xcprivacy fájl
Az adatvédelmi manifest egy PrivacyInfo.xcprivacy nevű fájl az app bundle gyökerében. Az Apple privacy manifestekről szóló dokumentációja szerint leírja a gyűjtött adatokat, a követést és az indokolást igénylő API-kat. Ez utóbbiak az NSPrivacyAccessedAPITypes tömbbe kerülnek: kategóriánként egy bejegyzés, a típusával és az indokok listájával.
A csapda: egy manifest csak a saját bundle-jére vonatkozik. Az Apple le is írja: minden futtatható állománynak vagy dinamikus könyvtárnak, amely ezeket az API-kat használja, saját manifest kell a bundle-jében. Az appod manifestje nem fed le egy beágyazott frameworköt, és egy SDK sem támaszkodhat az appod manifestjére.
Ne keverd össze az Info.plist szövegeivel, amelyeket az ITMS-90683 követel. Azok engedélykéréskor megjelennek a felhasználónak. A manifestet viszont csak az Apple olvassa.
Az 5 API-kategória és az indokkódok
Egy kategória teljes neve NSPrivacyAccessedAPICategory-vel kezdődik. Az API-k és indokok listája az NSPrivacyAccessedAPIType kulcs oldalán található, 2026. október 15-i állapot szerint.
| Kategória | Tipikus API | Gyakori indok |
|---|---|---|
| UserDefaults | UserDefaults | CA92.1 |
| FileTimestamp | creationDate | C617.1 |
| SystemBootTime | systemUptime | 35F9.1 |
| DiskSpace | volumeAvailableCapacityKey | E174.1 |
| ActiveKeyboards | activeInputModes | 54BD.1 |
A kódok, amelyekkel a leggyakrabban találkozol:
- CA92.1: az app a saját beállításait olvassa és írja, ezek más appok számára nem elérhetők.
- 1C8F.1: ugyanabban az App Groupban lévő widgettel vagy bővítménnyel megosztott beállítások.
- C617.1: az app konténerében tárolt fájlok dátumai vagy mérete.
- 3B52.1: a felhasználó által kiválasztott fájlok, például egy dokumentumválasztóban.
- 35F9.1: az app két eseménye között eltelt idő mérése, vagy egy időzítő futtatása.
- E174.1: a szabad hely ellenőrzése fájlok írása előtt, a felhasználó számára látható hatással.
- 85F4.1: a lemezterület megjelenítése a felhasználónak.
Azt az indokot deklaráld, amely a valós használatodnak felel meg, ne azt, amelyik a legtágabbnak tűnik. Az Apple pontosítja, hogy ezek az API-k és adataik csak a deklarált célokra használhatók, követésre soha. Két kód harmadik féltől származó SDK-knak van fenntartva: C56D.1 és 0A2A.1. Ezeknek nincs helyük az appod manifestjében.
A privacy manifest deklarálása Expóban
Expóval nem te írod meg a fájlt. Az expo.ios.privacyManifests alatt írod le, az app.json vagy az app.config fájlban, és a prebuild legenerálja a PrivacyInfo.xcprivacy fájlt. Ez az Expo privacy manifestekről szóló dokumentációjában leírt módszer.
Íme a Solys konfigurációjának valós részlete. A kulcs tartalmazza a követést és a gyűjtött adatokat is, ezeket itt kivettem:
{
"expo": {
"ios": {
"privacyManifests": {
"NSPrivacyAccessedAPITypes": [
{
"NSPrivacyAccessedAPIType": "NSPrivacyAccessedAPICategoryUserDefaults",
"NSPrivacyAccessedAPITypeReasons": ["CA92.1", "1C8F.1"]
},
{
"NSPrivacyAccessedAPIType": "NSPrivacyAccessedAPICategoryFileTimestamp",
"NSPrivacyAccessedAPITypeReasons": ["C617.1"]
},
{
"NSPrivacyAccessedAPIType": "NSPrivacyAccessedAPICategorySystemBootTime",
"NSPrivacyAccessedAPITypeReasons": ["35F9.1"]
}
]
}
}
}
}
A CA92.1, a C617.1 és a 35F9.1 azt veszi át, amit a React Native és az app Expo-moduljai deklarálnak. Az 1C8F.1 magától a Solystól jön: az app egy App Groupon keresztül oszt meg beállításokat a widgetjével.
Egy csapda, amiről tudnod kell: ha az ios mappád generált, és a git figyelmen kívül hagyja, akkor egy ebbe a mappába kézzel írt PrivacyInfo.xcprivacy soha nem kerül be a buildbe. Az EAS újrafuttatja a prebuildet, és újragenerálja a mappát. 2026. szeptember 9-én az egyik projektemen tapasztaltam: a kézzel írt manifest egy prebuild után eltűnt. A deklarációnak a konfigurációban a helye.
Utolsó pont: a manifest a bináris része. Egy távoli frissítés nem módosítja. Új buildet kell készíteni és újra beküldeni.
Harmadik féltől származó SDK-k saját manifesttel
A legtöbb újabb könyvtár saját manifestet ad. Azoknak az Expo-csomagoknak, amelyek ezeket az API-kat használják, van PrivacyInfo.xcprivacy fájljuk az ios mappájukban, akárcsak a React Native-nek. A gond abból fakad, ahogyan az appodhoz linkelődnek.
Az Expo dokumentációja figyelmeztet: az Apple nem olvassa be helyesen a statikusan linkelt CocoaPods-függőségek összes manifestjét, márpedig az Expo-csomagok ilyenek. Ezért lehet, hogy az indokaikat át kell másolnod az appod konfigurációjába.
A munka csökkentésére az expo-build-properties ios.privacyManifestAggregationEnabled beállítása egyetlen fájlba fésüli össze a CocoaPods-függőségek manifestjeit. Az Expo által a projektjeimen (SDK 57) generált Podfile-ban ez az összefésülés be van kapcsolva, hacsak ki nem kapcsolod.
Az összefésülésnek van egy korlátja: csak azokat a függőségeket látja, amelyek adnak manifestet. Egy régi könyvtár, amelynek nincs, láthatatlan marad. Olvasd el tehát az e-mailben megnevezett fájl elérési útját: ez mutatja meg, hol kell javítani.
| Megnevezett fájl | Hol javítsd |
|---|---|
| Az app futtatható állománya | ios.privacyManifests |
Egy .framework | Frissítsd az SDK-t |
Egy .appex bővítmény | A bővítmény manifestje |
Ellenőrzés küldés előtt
Az Expo azt javasolja, hogy küldés után várd meg az Apple e-mailjét. Működik, de minden oda-vissza kör egy buildbe kerül. Íme a négy ellenőrzés, amit előtte elvégzek.
1. Listázd ki, mit deklarálnak a függőségeid. A projekt gyökeréből:
find node_modules -name PrivacyInfo.xcprivacy -not -path '*/example/*' \
-exec grep -ho "NSPrivacyAccessedAPICategory[A-Za-z]*" {} + | sort | uniq -c
A Solyson 2026. október 15-én a parancs 13 manifestet és négy kategóriát talál: fájldátumok, beállítások, indulás óta eltelt idő és lemezterület. Minden listázott kategóriának meg kell jelennie az app végleges manifestjében, vagy az azt használó framework manifestjében.
2. Keress a saját natív kódodban. Saját modulok, pluginok, targetek, például egy widget: ezt a kódot egyetlen SDK sem deklarálja helyetted.
grep -rlE "UserDefaults|systemUptime|mach_absolute_time|creationDate|modificationDate|volumeAvailableCapacity|activeInputModes" \
--include='*.swift' --include='*.m' --include='*.mm' modules plugins targets
Igazítsd a mappákat a projektedhez. A Solyson ez a keresés hozza elő az App Groupon át megosztott beállításokat, innen jön az 1C8F.1 kód.
3. Olvasd el a generált manifestet. Futtasd az npx expo prebuild -p ios parancsot, majd nyisd meg az ios/<AppodNeve>/PrivacyInfo.xcprivacy fájlt. Figyelem: ez a parancs törölheti, majd újra létrehozhatja az ios mappát. Ha kézzel módosítottál benne valamit, a projekt egy másolatán dolgozz.
4. Ellenőrizd a végleges buildet. Ez az egyetlen bizonyíték, ami számít. Töltsd le az IPA-t a build oldaláról az expo.dev-en, majd futtasd a Maceden:
unzip -q MyApp.ipa -d ipa
find ipa/Payload -name PrivacyInfo.xcprivacy
plutil -p ipa/Payload/*.app/PrivacyInfo.xcprivacy
A második sor kilistázza az összes beágyazott manifestet, az appét és a frameworkökét is. A harmadik az app manifestjét jeleníti meg, ezt vesd össze az 1. lépés listájával.
Mit kell a manifestnek a termékoldaladdal összhangban mondania
A manifest nem önmagában áll. Ha követést vagy gyűjtött adatokat deklarál, az App Store-oldaladnak és az adatvédelmi szabályzatodnak ugyanezt kell mondania. Ha a három eltér, az később emberi elutasításba kerülhet, az 5.1.1-es guideline alapján. Hogy mit kell összehangolni, azt az alkalmazás adatvédelmi szabályzata cikk részletezi.
Küldd be a buildedet kellemetlen meglepetések nélkül
Az ITMS-hibák gyorsan javíthatók, ha tudod, hogyan kell olvasni őket. Az utánuk jövő elutasítások több rálátást igényelnek: a teendők az Apple által elutasított alkalmazás oldalon vannak, a leggyakoribb okok pedig a miért utasítja el az Apple az appokat cikkben.
Hogy küldés előtt átnézd a csomagodat, az Apple Review Kit összegyűjti a checklistemet és Claude Code skilleket, amelyek átnézik a projektedet. Ha elakadt a beküldés, és emberi szemre van szükséged, foglalj velem egy órát: videóhívásban, a te képernyődön nézzük át a projektedet. Ha pedig az első megjelenésedre készülsz, töltsd ki az ingyenes diagnosztikát: sorba rendezi a lépéseket, és elküldi neked az Apple-elutasítás elleni checklistemet.
Gyakori kérdések
Blokkolja az ITMS-91053 a build beküldését?
Az Apple azt írja, hogy 2024. május 1. óta az App Store Connect nem fogad el olyan appokat, amelyek nem írják le ezeknek az API-knak a használatát. Néhány fejlesztő mégis elfogadott buildre kapta meg az e-mailt, figyelmeztetésként. Mindkét esetben javítsd a manifestet a következő build előtt.
Melyik indokkódot válasszam a UserDefaultshoz?
CA92.1-et, ha az app csak a saját beállításait olvassa és írja. Add hozzá az 1C8F.1-et, ha App Groupon keresztül megosztja őket egy widgettel vagy bővítménnyel. A C56D.1 harmadik féltől származó SDK-knak van fenntartva: ne tedd bele az appod manifestjébe.
Át kell másolnom minden SDK manifestjét az app.json-ba?
Nem feltétlenül. Ha a manifestek összefésülése be van kapcsolva, a CocoaPods-függőségek manifestjei a podok telepítésekor egyesülnek. Csak akkor másolj át egy kategóriát, ha hiányzik a végleges manifestből, a valós használatot leíró indokkal.
Kell a widgetemnek vagy a bővítményemnek saját manifest?
Az Apple szerint minden bundle-nek, amely ezeket az API-kat használó futtatható állományt tartalmaz, saját manifest kell. Egy bővítmény külön futtatható állomány, saját bundle-ben: az app manifestje nem fedi le.
Javítható az ITMS-91053 új build nélkül?
Nem. Az adatvédelmi manifest a bináris része. Javítsd a konfigurációt, készíts új buildet, majd teszteld a TestFlightban, mielőtt review-ra küldöd.