ITMS-91053: Missing API declaration -virheen korjaus Expolla
Kirjoittaja: Mehdi Azizi
Julkaistu , 8 min
ITMS-91053: buildisi käyttää pakollisen syyn API:a ilmoittamatta sitä. Lisää kategoria ja koodi kohtaan ios.privacyManifests ja tee uusi build.
ITMS-91053 on Applen automaattinen tarkistus, joka tulee sähköpostina sen jälkeen, kun olet toimittanut buildisi. Se kertoo, että sovelluksesi koodi käyttää "pakollisen syyn" API:a (asetukset, tiedostojen päivämäärät, aika käynnistyksestä, levytila tai näppäimistöt) selittämättä tietosuojamanifestissa, miksi. Expossa korjaus tehdään kohdassa ios.privacyManifests: Applen mainitsema kategoria, todellista käyttöäsi kuvaava koodi ja sitten uusi build.
Solysissa, minipelejä sisältävässä herätyskellosovelluksessani, nämä syyt on ilmoitettu sovelluksen konfiguraatiossa. Tässä sen todellinen ilmoitus, komento, joka listaa riippuvuuksiesi käyttämät API:t, ja tarkistus, joka lopulliselle tiedostolle kannattaa tehdä ennen lähettämistä.
Mitä ITMS-91053-virhe tarkoittaa?
Viestin otsikko on "ITMS-91053: Missing API declaration". Sen mukaan buildisi tietyn tiedoston koodi viittaa yhteen tai useampaan API:in, jotka vaativat syyn. Sen jälkeen se listaa kyseiset kategoriat, esimerkiksi NSPrivacyAccessedAPICategoryUserDefaults.
Nämä API:t eivät pyydä käyttäjältä mitään lupaa. Niillä voi kuitenkin tunnistaa laitteen, mitä Apple kutsuu fingerprintingiksi. Se on kiellettyä, vaikka käyttäjä hyväksyisi seurannan. Apple selittää tämän pakollisen syyn API:ita käsittelevällä sivullaan: jokaisen sovelluksen ja jokaisen SDK:n on ilmoitettava, miksi se käyttää niitä.
Sama sivu määrää säännön: 1. toukokuuta 2024 lähtien App Store Connect ei enää hyväksy sovellusta, joka ei kuvaa näitä käyttötapoja manifestissaan. Jotkut kehittäjät ovat kertoneet saaneensa tämän sähköpostin pelkkänä varoituksena hyväksytystä buildista. Älä luota siihen: käsittele sitä esteenä ja korjaa ennen seuraavaa lähetystä.
Kuten muutkaan ITMS-virheet, tämä ei ole reviewerin hylkäys. Kukaan ei ole avannut sovellustasi: Apple analysoi binäärin.
iOS:n privacy manifest: PrivacyInfo.xcprivacy-tiedosto
Tietosuojamanifesti on PrivacyInfo.xcprivacy-niminen tiedosto sovelluksen bundlen juuressa. Applen privacy manifest -dokumentaation mukaan se kuvaa kerätyt tiedot, seurannan ja pakollisen syyn API:t. Viimeksi mainitut menevät taulukkoon NSPrivacyAccessedAPITypes: yksi merkintä per kategoria, tyyppi ja lista syistä.
Ansa on tämä: manifesti kattaa vain oman bundlensa. Apple sanoo sen suoraan: jokaisella näitä API:ita käyttävällä suoritettavalla tiedostolla tai dynaamisella kirjastolla on oltava manifesti omassa bundlessaan. Sovelluksesi manifesti ei kata upotettua frameworkia, eikä SDK voi luottaa sovelluksesi manifestiin.
Älä sekoita sitä Info.plistin teksteihin, joita ITMS-90683 vaatii. Ne näytetään käyttäjälle lupapyynnössä. Manifestia taas lukee vain Apple.
API:iden 5 kategoriaa ja niiden syykoodit
Kategorian koko nimi alkaa NSPrivacyAccessedAPICategory. API:iden ja syiden lista löytyy avaimen NSPrivacyAccessedAPIType sivulta, luettu 15. lokakuuta 2026.
| Kategoria | Tyypillinen API | Yleinen syy |
|---|---|---|
| UserDefaults | UserDefaults | CA92.1 |
| FileTimestamp | creationDate | C617.1 |
| SystemBootTime | systemUptime | 35F9.1 |
| DiskSpace | volumeAvailableCapacityKey | E174.1 |
| ActiveKeyboards | activeInputModes | 54BD.1 |
Koodit, joihin törmäät useimmin:
- CA92.1: sovellus lukee ja kirjoittaa omia asetuksiaan, joihin muut sovellukset eivät pääse.
- 1C8F.1: asetukset jaetaan saman App Groupin widgetin tai laajennuksen kanssa.
- C617.1: sovelluksen kontissa olevien tiedostojen päivämäärät tai koko.
- 3B52.1: käyttäjän valitsemat tiedostot, esimerkiksi dokumenttivalitsimessa.
- 35F9.1: kahden sovelluksen tapahtuman välisen ajan mittaaminen tai ajastimen pyörittäminen.
- E174.1: vapaan tilan tarkistus ennen tiedostojen kirjoittamista, käyttäjälle näkyvällä vaikutuksella.
- 85F4.1: levytilan näyttäminen käyttäjälle.
Ilmoita syy, joka vastaa todellista käyttöäsi, älä sitä, joka näyttää laajimmalta. Apple täsmentää, että näitä API:ita ja niiden tietoja käytetään vain ilmoitettuihin syihin eikä koskaan seurantaan. Kaksi koodia on varattu kolmannen osapuolen SDK:ille: C56D.1 ja 0A2A.1. Ne eivät kuulu sovelluksesi manifestiin.
Privacy manifestin ilmoittaminen Expossa
Expossa et kirjoita tiedostoa itse. Kuvaat sen kohdassa expo.ios.privacyManifests tiedostossa app.json tai app.config, ja prebuild generoi PrivacyInfo.xcprivacy-tiedoston. Tämä on Expon privacy manifest -dokumentaation menetelmä.
Tässä todellinen ote Solysin konfiguraatiosta. Avain sisältää myös seurannan ja kerätyt tiedot, jotka on poistettu tästä:
{
"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 ja 35F9.1 toistavat sen, mitä React Native ja sovelluksen Expo-moduulit ilmoittavat. 1C8F.1 tulee Solysista itsestään: sovellus jakaa asetuksia widgetinsä kanssa App Groupin kautta.
Yksi ansa kannattaa tietää: jos ios-kansiosi on generoitu ja gitin ohittama, siihen käsin kirjoitettu PrivacyInfo.xcprivacy ei koskaan päädy buildiin. EAS ajaa prebuildin uudelleen ja generoi kansion uudestaan. Huomasin tämän yhdessä projektissani 9. syyskuuta 2026: käsin kirjoitettu manifesti oli kadonnut prebuildin jälkeen. Ilmoituksen on oltava konfiguraatiossa.
Viimeinen asia: manifesti on osa binääriä. Etäpäivitys ei muuta sitä. Sinun on tehtävä uusi build ja lähetettävä se uudelleen.
Kolmannen osapuolen SDK:t, joissa on oma manifesti
Useimmat uudet kirjastot tuovat oman manifestinsa. Näitä API:ita käyttävissä Expo-paketeissa on PrivacyInfo.xcprivacy niiden ios-kansiossa, samoin React Nativessa. Ongelma johtuu tavasta, jolla ne linkitetään sovellukseesi.
Expon dokumentaatio varoittaa: Apple ei lue oikein kaikkia staattisesti linkitettyjen CocoaPods-riippuvuuksien manifesteja, ja Expo-paketit linkitetään juuri niin. Niiden syyt on siis ehkä kopioitava sovelluksesi konfiguraatioon.
Tämän työn vähentämiseksi expo-build-properties-asetus ios.privacyManifestAggregationEnabled yhdistää CocoaPods-riippuvuuksien manifestit yhdeksi tiedostoksi. Podfilessa, jonka Expo generoi projekteissani (SDK 57), tämä yhdistäminen on päällä, ellet poista sitä käytöstä.
Yhdistämisellä on rajansa: se näkee vain riippuvuudet, jotka tuovat manifestin. Vanha kirjasto, jolla manifestia ei ole, jää näkymättömiin. Lue siis sähköpostissa mainitun tiedoston polku: se kertoo, mistä korjata.
| Mainittu tiedosto | Mistä korjata |
|---|---|
| Sovelluksen suoritettava | ios.privacyManifests |
.framework | Päivitä SDK |
.appex-laajennus | Laajennuksen manifesti |
Tarkista ennen lähettämistä
Expo ehdottaa, että odotat Applen sähköpostia lähetyksen jälkeen. Se toimii, mutta jokainen kierros maksaa buildin. Tässä neljä tarkistusta, jotka teen etukäteen.
1. Listaa, mitä riippuvuutesi ilmoittavat. Projektin juuresta:
find node_modules -name PrivacyInfo.xcprivacy -not -path '*/example/*' \
-exec grep -ho "NSPrivacyAccessedAPICategory[A-Za-z]*" {} + | sort | uniq -c
Solysissa 15. lokakuuta 2026 komento löytää 13 manifestia ja neljä kategoriaa: tiedostojen päivämäärät, asetukset, aika käynnistyksestä ja levytila. Jokaisen listatun kategorian on löydyttävä sovelluksen lopullisesta manifestista tai sitä käyttävän frameworkin manifestista.
2. Etsi omasta natiivikoodistasi. Omat moduulit, pluginit, kohteet kuten widget: tätä koodia mikään SDK ei ilmoita puolestasi.
grep -rlE "UserDefaults|systemUptime|mach_absolute_time|creationDate|modificationDate|volumeAvailableCapacity|activeInputModes" \
--include='*.swift' --include='*.m' --include='*.mm' modules plugins targets
Mukauta kansiot projektiisi. Solysissa juuri tämä haku paljastaa App Groupin kautta jaetut asetukset, ja siitä tulee koodi 1C8F.1.
3. Lue generoitu manifesti. Aja npx expo prebuild -p ios ja avaa ios/<NomDeTonApp>/PrivacyInfo.xcprivacy. Huomio: tämä komento voi poistaa ja luoda ios-kansion uudelleen. Jos olet tehnyt siihen muutoksia käsin, työskentele projektin kopiolla.
4. Tarkista lopullinen build. Se on ainoa todiste, jolla on merkitystä. Lataa IPA buildin sivulta expo.devissä ja aja Macillasi:
unzip -q MonApp.ipa -d ipa
find ipa/Payload -name PrivacyInfo.xcprivacy
plutil -p ipa/Payload/*.app/PrivacyInfo.xcprivacy
Toinen rivi listaa kaikki upotetut manifestit, sovelluksen ja frameworkien. Kolmas näyttää sovelluksen manifestin, jota verrataan vaiheen 1 listaan.
Mitä manifestin pitää kertoa yhdessä sivusi kanssa
Manifesti ei elä yksin. Jos se ilmoittaa seurantaa tai kerättyjä tietoja, App Store -sivusi ja tietosuojakäytäntösi on kerrottava samaa. Ero näiden kolmen välillä voi myöhemmin maksaa ihmisen tekemän hylkäyksen guidelinen 5.1.1 perusteella. Mitä pitää yhtenäistää, on kerrottu artikkelissa sovelluksen tietosuojakäytäntö.
Lähetä buildisi ilman ikäviä yllätyksiä
ITMS-virheet korjautuvat nopeasti, kun osaa lukea ne. Myöhemmin tulevat hylkäykset vaativat enemmän harkintaa: toimintatapa on sivulla Applen hylkäämä sovellus, ja yleisimmät syyt artikkelissa miksi Apple hylkää sovelluksen.
Jos haluat tarkistaa kokonaisuuden ennen lähettämistä, Apple Review Kit sisältää tarkistuslistani ja Claude Code -skillejä, jotka käyvät projektisi läpi. Jos lähetyksesi jumittaa ja haluat ihmisen näkemyksen, varaa tunti kanssani: käydään projektisi läpi videopuhelussa, sinun näytölläsi. Ja jos valmistelet ensimmäistä julkaisuasi, tee ilmainen diagnoosi: se laittaa vaiheet järjestykseen ja lähettää sinulle tarkistuslistani Applen hylkäysten välttämiseen.
Usein kysytyt kysymykset
Estääkö ITMS-91053 buildini lähettämisen?
Apple kirjoittaa, että 1. toukokuuta 2024 lähtien App Store Connect ei enää hyväksy sovelluksia, jotka eivät kuvaa näiden API:iden käyttöään. Jotkut kehittäjät ovat silti saaneet sähköpostin hyväksytystä buildista varoituksena. Kummassakin tapauksessa korjaa manifesti ennen seuraavaa buildia.
Mikä syykoodi UserDefaultsille?
CA92.1, jos sovellus lukee ja kirjoittaa vain omia asetuksiaan. Lisää 1C8F.1, jos se jakaa ne widgetin tai laajennuksen kanssa App Groupin kautta. C56D.1 on varattu kolmannen osapuolen SDK:ille: älä laita sitä sovelluksesi manifestiin.
Pitääkö jokaisen SDK:n manifesti kopioida app.jsoniin?
Ei välttämättä. Jos manifestien yhdistäminen on päällä, CocoaPods-riippuvuuksien manifestit kootaan podien asennuksen yhteydessä. Kopioi kategoria vain, jos se puuttuu lopullisesta manifestista, ja käytä syytä, joka kuvaa todellista käyttöä.
Tarvitseeko widgetini tai laajennukseni oman manifestin?
Applen mukaan jokaisella bundlella, joka sisältää näitä API:ita käyttävän suoritettavan tiedoston, on oltava oma manifesti. Laajennus on erillinen suoritettava tiedosto omassa bundlessaan: sovelluksen manifesti ei kata sitä.
Voiko ITMS-91053:n korjata ilman uutta buildia?
Ei. Tietosuojamanifesti on osa binääriä. Korjaa konfiguraatio, tee uusi build ja testaa se TestFlightissa ennen kuin lähetät sen arvioitavaksi.