# ITMS-91053: memperbaiki Missing API declaration di Expo

> ITMS-91053: build kamu memakai API dengan alasan wajib tanpa mendeklarasikannya. Tambahkan kategori dan kodenya di ios.privacyManifests, lalu build ulang.

Halaman asli: [ITMS-91053: memperbaiki Missing API declaration di Expo](https://devoria.fr/id/blog/itms-91053-missing-api-declaration-expo)
Penulis: [Mehdi Azizi](https://devoria.fr/id/mehdi-azizi)
Terbit: 2026-10-25
Revisi konten terakhir: 2026-10-25


ITMS-91053 adalah pemeriksaan otomatis dari Apple, yang dikirim lewat e-mail setelah [build kamu dikirim](https://devoria.fr/id/blog/eas-submit-ios-publikasi-app-expo-app-store). Isinya: kode app kamu memakai API "dengan alasan wajib" (preferensi, tanggal file, waktu sejak perangkat menyala, ruang disk, atau keyboard) tanpa menjelaskan alasannya di privacy manifest. **Di Expo, perbaikannya dilakukan di `ios.privacyManifests`: kategori yang disebut Apple, kode yang menggambarkan penggunaan kamu yang sebenarnya, lalu build baru.**

Di Solys, alarm dengan mini-game buatan saya, alasan-alasan ini dideklarasikan di konfigurasi app. Berikut deklarasi aslinya, perintah untuk melihat apa saja yang dipakai dependensi kamu, dan pemeriksaan file final sebelum dikirim.

## Apa arti error ITMS-91053?

Judul pesannya "ITMS-91053: Missing API declaration". Pesan ini menyebut bahwa kode di file tertentu dalam build kamu merujuk ke satu atau beberapa API yang membutuhkan alasan. Lalu ia mencantumkan kategori yang bermasalah, misalnya `NSPrivacyAccessedAPICategoryUserDefaults`.

API ini tidak meminta izin apa pun ke pengguna. Tapi API ini bisa dipakai untuk mengenali perangkat, yang Apple sebut fingerprinting. Itu dilarang, bahkan kalau pengguna menyetujui pelacakan. Apple menjelaskannya di halaman tentang [API dengan alasan wajib](https://developer.apple.com/documentation/bundleresources/describing-use-of-required-reason-api): setiap app dan setiap SDK harus mendeklarasikan alasan memakainya.

Halaman yang sama menetapkan aturannya: **sejak 1 Mei 2024, App Store Connect tidak lagi menerima app yang tidak menjelaskan penggunaan ini di manifest-nya.** Beberapa developer melaporkan e-mail ini cuma sebagai peringatan, pada build yang tetap diterima. Jangan mengandalkan itu: anggap saja ini pemblokir dan perbaiki sebelum pengiriman berikutnya.

Seperti error ITMS lainnya, ini bukan penolakan dari reviewer. Tidak ada orang yang membuka app kamu: Apple menganalisis binernya.

## Privacy manifest iOS: file PrivacyInfo.xcprivacy

Privacy manifest adalah file bernama `PrivacyInfo.xcprivacy`, yang diletakkan di root bundle app. Menurut [dokumentasi Apple tentang privacy manifest](https://developer.apple.com/documentation/bundleresources/privacy-manifest-files), file ini menjelaskan data yang dikumpulkan, pelacakan, dan API dengan alasan wajib. API tersebut masuk ke array `NSPrivacyAccessedAPITypes`: satu entri per kategori, berisi tipenya dan daftar alasannya.

Jebakannya: **satu manifest hanya mencakup bundle-nya sendiri.** Apple menuliskannya: setiap executable atau library dinamis yang memakai API ini harus punya manifest di bundle-nya. Manifest app kamu tidak mencakup framework yang disertakan, dan sebuah SDK tidak bisa mengandalkan manifest app kamu.

Jangan sampai tertukar dengan kalimat di Info.plist yang diwajibkan oleh [ITMS-90683](https://devoria.fr/id/blog/itms-90683-missing-purpose-string-expo). Kalimat itu ditampilkan ke pengguna saat meminta izin. Sementara manifest hanya dibaca oleh Apple.

## 5 kategori API dan kode alasannya

Nama lengkap kategori diawali dengan `NSPrivacyAccessedAPICategory`. Daftar API dan alasannya ada di halaman key [NSPrivacyAccessedAPIType](https://developer.apple.com/documentation/bundleresources/app-privacy-configuration/nsprivacyaccessedapitypes/nsprivacyaccessedapitype), dibaca pada 15 Oktober 2026.

| Kategori        | API umum                     | Alasan umum |
| --------------- | ---------------------------- | ----------- |
| UserDefaults    | `UserDefaults`               | CA92.1      |
| FileTimestamp   | `creationDate`               | C617.1      |
| SystemBootTime  | `systemUptime`               | 35F9.1      |
| DiskSpace       | `volumeAvailableCapacityKey` | E174.1      |
| ActiveKeyboards | `activeInputModes`           | 54BD.1      |

Kode yang paling sering kamu temui:

- **CA92.1**: app membaca dan menulis preferensinya sendiri, yang tidak bisa diakses app lain.
- **1C8F.1**: preferensi yang dibagikan dengan widget atau ekstensi dalam App Group yang sama.
- **C617.1**: tanggal atau ukuran file yang disimpan di container app.
- **3B52.1**: file yang dipilih pengguna, misalnya lewat pemilih dokumen.
- **35F9.1**: mengukur waktu antara dua kejadian di app, atau menjalankan timer.
- **E174.1**: memeriksa ruang kosong sebelum menulis file, dengan efek yang terlihat oleh pengguna.
- **85F4.1**: menampilkan ruang disk ke pengguna.

**Deklarasikan alasan yang sesuai dengan penggunaan kamu yang sebenarnya, bukan yang kelihatannya paling luas.** Apple menegaskan bahwa API ini dan datanya hanya boleh dipakai untuk alasan yang dideklarasikan, dan tidak pernah untuk pelacakan. Dua kode khusus untuk SDK pihak ketiga: C56D.1 dan 0A2A.1. Keduanya tidak boleh ada di manifest app kamu.

## Mendeklarasikan privacy manifest di Expo

Di Expo, kamu tidak menulis file itu sendiri. Kamu mendeskripsikannya di `expo.ios.privacyManifests`, di app.json atau app.config, dan prebuild akan menghasilkan `PrivacyInfo.xcprivacy`. Ini cara yang dijelaskan di [dokumentasi Expo tentang privacy manifest](https://docs.expo.dev/guides/apple-privacy/).

Berikut cuplikan asli dari konfigurasi Solys. Key ini juga berisi pelacakan dan data yang dikumpulkan, yang di sini saya hapus:

```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, dan 35F9.1 mengikuti apa yang dideklarasikan React Native dan modul Expo di app ini. 1C8F.1 berasal dari Solys sendiri: app ini berbagi pengaturan dengan widget-nya lewat App Group.

Satu jebakan yang perlu kamu tahu: kalau folder `ios` kamu di-generate dan diabaikan oleh git, **`PrivacyInfo.xcprivacy` yang ditulis manual di folder itu tidak akan pernah masuk ke build.** EAS menjalankan ulang prebuild dan membuat ulang folder itu. Saya mengalaminya di salah satu proyek saya pada 9 September 2026: manifest yang ditulis manual hilang setelah prebuild. Deklarasinya harus ada di konfigurasi.

Poin terakhir: manifest adalah bagian dari biner. Update jarak jauh tidak mengubahnya. Kamu harus build ulang dan mengirimnya lagi.

## SDK pihak ketiga yang membawa manifest sendiri

Sebagian besar library terbaru menyertakan manifest-nya. Paket Expo yang memakai API ini punya `PrivacyInfo.xcprivacy` di folder `ios`-nya, begitu juga React Native. Masalahnya ada pada cara paket-paket itu ditautkan ke app kamu.

Dokumentasi Expo mengingatkan: Apple tidak membaca dengan benar semua manifest dari dependensi CocoaPods yang ditautkan secara statis, dan itulah kasus paket Expo. Jadi kamu mungkin perlu menyalin alasan-alasannya ke konfigurasi app kamu.

Untuk mengurangi pekerjaan ini, pengaturan `ios.privacyManifestAggregationEnabled` dari [expo-build-properties](https://docs.expo.dev/versions/latest/sdk/build-properties/) menggabungkan manifest dependensi CocoaPods menjadi satu file. Di Podfile yang di-generate Expo pada proyek-proyek saya (SDK 57), penggabungan ini aktif, kecuali kamu menonaktifkannya.

Penggabungan ini punya batas: ia hanya melihat dependensi yang menyertakan manifest. Library lama yang tidak punya manifest tetap tidak terlihat. **Jadi baca path file yang disebut di e-mail**: path itu menunjukkan di mana harus memperbaiki.

| File yang disebut        | Tempat memperbaiki     |
| ------------------------ | ---------------------- |
| Executable app           | `ios.privacyManifests` |
| Sebuah `.framework`      | Update SDK-nya         |
| Sebuah ekstensi `.appex` | Manifest ekstensi itu  |

## Periksa sebelum mengirim

Expo menyarankan untuk menunggu e-mail dari Apple setelah pengiriman. Itu berhasil, tapi setiap bolak-balik memakan satu build. Ini empat pemeriksaan yang saya lakukan sebelumnya.

**1. Daftar apa yang dideklarasikan dependensi kamu.** Dari root proyek:

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

Di Solys, pada 15 Oktober 2026, perintah ini menemukan 13 manifest dan empat kategori: tanggal file, preferensi, waktu sejak perangkat menyala, dan ruang disk. Setiap kategori yang muncul harus ada di manifest final app, atau di manifest framework yang memakainya.

**2. Cari di kode native kamu sendiri.** Modul buatan sendiri, plugin, target seperti widget: kode ini tidak dideklarasikan oleh SDK mana pun untuk kamu.

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

Sesuaikan foldernya dengan proyek kamu. Di Solys, pencarian inilah yang memunculkan preferensi yang dibagikan lewat App Group, makanya ada kode 1C8F.1.

**3. Baca manifest yang di-generate.** Jalankan `npx expo prebuild -p ios`, lalu buka `ios/<NamaAppKamu>/PrivacyInfo.xcprivacy`. Hati-hati: perintah ini bisa menghapus lalu membuat ulang folder `ios`. Kalau kamu pernah mengubahnya secara manual, kerjakan di salinan proyek.

**4. Periksa build final.** Hanya ini bukti yang benar-benar berarti. Unduh IPA dari halaman build di expo.dev, lalu jalankan di Mac kamu:

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

Baris kedua menampilkan semua manifest yang disertakan, milik app dan milik framework. Baris ketiga menampilkan manifest app, untuk dibandingkan dengan daftar dari langkah 1.

## Apa yang harus diceritakan manifest bersama halaman app kamu

Manifest tidak berdiri sendiri. Kalau manifest mendeklarasikan pelacakan atau data yang dikumpulkan, halaman App Store dan kebijakan privasi kamu harus menyatakan hal yang sama. Perbedaan di antara ketiganya bisa berujung penolakan oleh manusia, berdasarkan [guideline 5.1.1](https://devoria.fr/id/blog/guideline-5-1-1-penolakan-app-store). Apa saja yang harus diselaraskan dijelaskan di [kebijakan privasi aplikasi](https://devoria.fr/id/blog/kebijakan-privasi-aplikasi-ios-app-store).

## Kirim build kamu tanpa kejutan

Error ITMS cepat diperbaiki kalau kamu tahu cara membacanya. Penolakan yang datang setelahnya butuh pandangan lebih luas: langkah-langkahnya ada di halaman [aplikasi ditolak Apple](https://devoria.fr/id/expertise/aplikasi-ditolak-apple), dan alasan yang paling sering ada di [kenapa Apple menolak app](https://devoria.fr/id/blog/aplikasi-ditolak-apple-penyebab-solusi).

Untuk memeriksa proyek kamu sebelum dikirim, [Apple Review Kit](https://devoria.fr/id/kits/review-apple) berisi checklist saya dan skill Claude Code yang meninjau proyek kamu. Kalau pengirimanmu macet dan kamu ingin dilihat langsung oleh orang, [pesan satu jam dengan saya](https://devoria.fr/id/coaching): kita bahas proyek kamu lewat video call, di layar kamu. Dan kalau kamu sedang menyiapkan rilis pertama, [ikuti diagnostik gratis](https://devoria.fr/id/diagnostic): diagnostik ini menyusun langkah-langkahnya secara berurutan dan mengirimkan checklist anti-penolakan Apple saya.

## Pertanyaan umum

### Apakah ITMS-91053 memblokir pengiriman build saya?

Apple menulis bahwa sejak 1 Mei 2024, App Store Connect tidak lagi menerima app yang tidak menjelaskan penggunaan API ini. Tapi beberapa developer menerima e-mail ini pada build yang tetap diterima, sebagai peringatan. Dalam kedua kasus, perbaiki manifest sebelum build berikutnya.

### Kode alasan apa yang dipilih untuk UserDefaults?

CA92.1 kalau app hanya membaca dan menulis preferensinya sendiri. Tambahkan 1C8F.1 kalau app membagikannya dengan widget atau ekstensi lewat App Group. C56D.1 khusus untuk SDK pihak ketiga: jangan masukkan ke manifest app kamu.

### Apakah manifest setiap SDK harus disalin ke app.json?

Tidak selalu. Kalau penggabungan manifest aktif, manifest dependensi CocoaPods digabungkan saat pod diinstal. Salin sebuah kategori hanya kalau kategori itu tidak ada di manifest final, dengan alasan yang menggambarkan penggunaan sebenarnya.

### Apakah widget atau ekstensi saya butuh manifest sendiri?

Menurut Apple, setiap bundle yang berisi executable yang memakai API ini harus punya manifest sendiri. Ekstensi adalah executable terpisah, di bundle-nya sendiri: manifest app tidak mencakupnya.

### Bisakah ITMS-91053 diperbaiki tanpa build ulang?

Tidak. Privacy manifest adalah bagian dari biner. Perbaiki konfigurasinya, build ulang, lalu uji di [TestFlight](https://devoria.fr/id/blog/testflight-cara-tes-aplikasi-iphone) sebelum mengirimnya untuk review.


## Proyekmu

[Apple Review Kit](https://devoria.fr/id/kits/review-apple): Checklist review App Store yang kupakai, penolakan Apple yang sudah kuperbaiki, catatan untuk penguji, dan dua skill Claude Code yang meninjau aplikasimu. 29 €.

[iOS Kit](https://devoria.fr/id/kits/ios): Bikin aplikasi iPhone dengan Claude Code: starter code aplikasiku, skill yang memeriksa kerjanya, plus Apple Review Kit, App Store Screenshots Kit, dan ASO Kit. 129,99 €.
