# ITMS-90683: исправить Missing purpose string в Expo

> ITMS-90683 Missing purpose string: почему Apple отклоняет билд, какой ключ добавить в app.json в Expo и как найти недостающие ключи до отправки.

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


ITMS-90683 это автоматический отказ Apple: он приходит на почту вскоре после отправки билда, ещё до любой ручной проверки. Он значит, что в твоём файле 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/ru/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/ru/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/ru/expertise/app-rejected-by-apple), а самые частые причины в статье [почему Apple отклоняет приложение](https://devoria.fr/ru/blog/otkaz-apple-app-store-prichiny).

Чтобы проверить всё перед отправкой, в [Apple Review Kit](https://devoria.fr/ru/kits/review-apple) собраны мой чеклист и skills для Claude Code, которые просматривают твой проект. Если отправка застряла и нужен живой взгляд, [забронируй час со мной](https://devoria.fr/ru/coaching): разберём твой проект по видеосвязи, прямо на твоём экране. А если готовишь первый релиз, [пройди бесплатную диагностику](https://devoria.fr/ru/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/ru/kits/review-apple): Мой чек-лист для ревью App Store, исправленные отказы Apple, заметки для ревьюера и два skills для Claude Code, которые проверяют твоё приложение. 29 €.

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