# ITMS-90683: як виправити Missing purpose string в Expo

> ITMS-90683 Missing purpose string: чому Apple відхиляє твій білд, який ключ додати в app.json з Expo і як знайти відсутні ключі до надсилання.

Оригінальна сторінка: [ITMS-90683: як виправити Missing purpose string в Expo](https://devoria.fr/uk/blog/itms-90683-missing-purpose-string-expo)
Автор: [Mehdi Azizi](https://devoria.fr/uk/mehdi-azizi)
Опубліковано: 2026-10-09
Останнє оновлення змісту: 2026-10-09


ITMS-90683 це автоматична відмова Apple: вона приходить на e-mail невдовзі після надсилання білда, ще до будь-якої перевірки людиною. Вона означає, що у твоєму файлі Info.plist бракує фрази, яка пояснює, навіщо застосунку доступ до чутливих даних. **Виправлення зводиться до двох дій: додати ключ, названий у повідомленні, до `ios.infoPlist`, а потім зробити новий білд.**

Я отримав її на Solys, моєму будильнику з міні-іграми, через дані, які застосунок навіть не використовує. Ось що означає повідомлення, чому воно приходить і як його уникнути.

## Що означає помилка ITMS-90683?

Повне повідомлення називається «ITMS-90683: Missing purpose string in Info.plist». У ньому сказано, що код твого застосунку звертається до API, яке працює з чутливими даними (фото, камера, мікрофон, геолокація, контакти), а твій Info.plist не містить відповідного ключа з описом. Повідомлення називає цей ключ, наприклад `NSPhotoLibraryUsageDescription`.

Ця фраза-опис називається «purpose string». Це текст, який iOS показує у вікні запиту дозволу. Apple пише про це у своїй документації щодо [доступу до захищених ресурсів](https://developer.apple.com/documentation/uikit/requesting-access-to-protected-resources): App Review відхиляє застосунки, чий код звертається до цих ресурсів без purpose string.

Це не відмова рев'юера. Перевірка автоматична і спрацьовує під час доставки білда, до потрапляння на перевірку, як [ITMS-91053](https://devoria.fr/uk/blog/itms-91053-missing-api-declaration-expo) для маніфесту конфіденційності. Білд відкидається, і треба надіслати новий.

## Чому Apple відмовляє, хоча твій застосунок не використовує ці дані

Саме це й дивує. **Apple аналізує код, що міститься у твоєму білді, а не те, що застосунок робить насправді.** Якщо бібліотека, яку ти підключаєш, містить звернення до фототеки, ключ вимагається, навіть якщо жоден екран ніколи не просить доступу до фото. Повідомлення Apple саме це уточнює: стороння бібліотека чи SDK може звертатися до цих API, і purpose string однаково обов'язковий.

Мій випадок, 26 вересня 2026 року. Прибираючи конфігурацію Solys, я видалив ключ `NSPhotoLibraryUsageDescription`, адже застосунок не торкається жодного фото. Наступний білд відхилили з ITMS-90683. Причина: дві бібліотеки Expo, які використовує застосунок, `expo-image` і `expo-file-system`, містять код, що звертається до фототеки. Попередній білд проходив, бо ключ ще був на місці.

**Висновок**: ключ опису не видаляють «бо ним не користуються». Його видаляють лише тоді, коли жодна бібліотека в білді більше не звертається до цього API.

## Найпоширеніші ключі

- `NSPhotoLibraryUsageDescription`: читання або запис фото.
- `NSPhotoLibraryAddUsageDescription`: додавання фото без читання.
- `NSCameraUsageDescription`: камера.
- `NSMicrophoneUsageDescription`: мікрофон.
- `NSLocationWhenInUseUsageDescription`: геолокація під час використання.
- `NSContactsUsageDescription`: контакти.
- `NSUserTrackingUsageDescription`: рекламне відстеження ([App Tracking Transparency](https://devoria.fr/uk/blog/guideline-5-1-2-third-party-ai-att-data-sharing)).

Apple описує кожен ключ у документації, наприклад [NSPhotoLibraryUsageDescription](https://developer.apple.com/documentation/bundleresources/information-property-list/nsphotolibraryusagedescription): він обов'язковий, щойно застосунок використовує API, яке читає чи записує у фототеку.

## Як виправити ITMS-90683 у застосунку на Expo

1. **Знайди ключ, названий у листі від Apple.** Повідомлення дає його точну назву.
2. **Додай його у свою конфігурацію**, у `ios.infoPlist`, як вказано в [документації Expo про дозволи](https://docs.expo.dev/guides/permissions/):

```json
{
  "expo": {
    "ios": {
      "infoPlist": {
        "NSPhotoLibraryUsageDescription": "Solys не має доступу до твоїх фото. Цей дозвіл ніколи не запитується."
      }
    }
  }
}
```

3. **Зроби новий білд.** Expo це уточнює: зміна Info.plist не проходить через віддалене оновлення, потрібен новий бінарник.
4. **Надішли білд** в Apple, а потім вибери його у своїй версії.

Пастка, якщо твій застосунок перекладено: файли локалізації перекладають ключ, але не оголошують його. Ключ спершу має існувати в `ios.infoPlist` (або в конфігурації відповідного плагіна). Інакше застосунок може впасти під час першого виклику.

## Яку фразу написати, якщо застосунок не використовує ці дані?

Apple вимагає точного, корисного і конкретного опису. Якщо застосунок справді використовує дані, скажи одним реченням, навіщо: «Застосунок використовує камеру, щоб сканувати штрихкод твого квитка».

Якщо ключ потрібен лише через бібліотеку, Apple пропонує два рішення: написати фразу або прибрати код, що звертається до даних. Коли цей код у бібліотеці, просто прибрати його не вийде. Тож для Solys я написав правду: «Solys не має доступу до твоїх фото. Цей дозвіл ніколи не запитується». Це прагматичний вибір: наступний білд пройшов доставку, але я не можу обіцяти, що Apple завжди прийматиме таку фразу.

## Як знайти відсутні ключі до надсилання

З кореня проєкту ця команда виводить файли бібліотек, чий iOS-код звертається до API, за якими найпильніше стежать:

```bash
grep -rlE "PHPhotoLibrary|AVCaptureDevice|CLLocationManager|CNContactStore|EKEventStore|ATTrackingManager" \
  node_modules/*/ios node_modules/@*/*/ios
```

Кожна назва відповідає типу даних: `PHPhotoLibrary` для фото, `AVCaptureDevice` для камери й мікрофона, `CLLocationManager` для геолокації, `CNContactStore` для контактів, `EKEventStore` для календаря, `ATTrackingManager` для відстеження. Для кожного результату перевір, що відповідний ключ опису є у твоїй конфігурації.

Ця сітка ловить випадки, з якими я стикався. Вона не замінює читання листа від Apple, який лишається єдиним надійним списком, як і для непублічних API в ITMS-90338. Після тієї відмови я роблю цю перевірку перед кожним білдом: вона займає кілька секунд, а відмова ITMS-90683 коштує білд і час на його повторення.

## Як надіслати білд без неприємних сюрпризів

ITMS-90683 виправляється швидко, коли вмієш його читати, так само як ITMS-90725, що стосується версії Xcode. Відмови, які приходять далі, від рев'юера, потребують більше уваги: порядок дій описано на сторінці [застосунок відхилено Apple](https://devoria.fr/uk/expertise/app-rejected-by-apple), а найчастіші причини в статті [чому Apple відхиляє застосунок](https://devoria.fr/uk/blog/vidmova-apple-app-store-prychyny).

Щоб перевірити все перед надсиланням, [Apple Review Kit](https://devoria.fr/uk/kits/review-apple) містить мій чекліст і скіли Claude Code, які переглядають твій проєкт. Якщо надсилання застрягло і ти хочеш живого погляду, [забронюй годину зі мною](https://devoria.fr/uk/coaching): розберемо твій проєкт по відео, на твоєму екрані. А якщо готуєш свій перший реліз, [пройди безкоштовну діагностику](https://devoria.fr/uk/diagnostic): вона розставить кроки по порядку і надішле тобі мій чекліст проти відмов Apple.

## Поширені запитання

### ITMS-90683 це відмова App Review?

Не в сенсі рев'юера-людини. Це автоматична перевірка білда під час доставки, до потрапляння на перевірку, як ITMS-90717 для іконки. Ніхто не відкривав твій застосунок. Білд відкидається: треба виправити Info.plist і надіслати новий.

### Чому Apple вимагає ключ для даних, які мій застосунок не використовує?

Бо Apple аналізує код у білді, а не поведінку застосунку. Якщо вбудована бібліотека звертається до фототеки чи камери, ключ опису обов'язковий, навіть якщо жоден екран ніколи не просить такого доступу.

### Чи можна виправити ITMS-90683 віддаленим оновленням?

Ні. Відсутній ключ знаходиться в Info.plist, який є частиною бінарника. Віддалене оновлення не змінює цей файл: треба зробити новий білд і надіслати його в Apple.

### Куди додати NSPhotoLibraryUsageDescription у проєкті Expo?

У конфігурацію застосунку, у `ios.infoPlist`, з фразою, що описує використання. Деякі бібліотеки також мають окреме налаштування у своєму плагіні, яке може додавати інші ключі, наприклад фоновий режим. В обох випадках ключ має існувати в базовій конфігурації, а не лише у файлах перекладу.

### Чи треба видаляти невикористані ключі опису?

Лише якщо жодна бібліотека в білді більше не звертається до відповідного API. Інакше наступне надсилання відхилять з ITMS-90683. Перш ніж видаляти ключ, пошукай назву API в iOS-коді своїх залежностей.


## Твій проєкт

[Apple Review Kit](https://devoria.fr/uk/kits/review-apple): Чекліст для review App Store, яким я користуюся, мої виправлені відмови Apple, нотатки для тестувальника і два skills Claude Code, що перевіряють твій застосунок. 29 €.

[iOS Kit](https://devoria.fr/uk/kits/ios): Створи застосунок для iPhone з Claude Code: стартовий код моїх застосунків, skills, що перевіряють його роботу, а також Apple Review Kit, App Store Screenshots Kit і ASO Kit. 129,99 €.
