# EAS Submit iOS: как опубликовать приложение Expo в App Store

> EAS Submit отправляет iOS-билд в App Store Connect, и он появляется в TestFlight. Отправку на ревью ты делаешь сам в App Store Connect.

Оригинальная страница: [EAS Submit iOS: как опубликовать приложение Expo в App Store](https://devoria.fr/ru/blog/eas-submit-ios-publish-expo-app-store)
Автор: [Mehdi Azizi](https://devoria.fr/ru/mehdi-azizi)
Опубликовано: 2026-10-25
Последняя правка контента: 2026-10-25


`eas submit --platform ios` отправляет твой iOS-билд в App Store Connect, где он появляется в TestFlight после обработки на стороне Apple. **Команда не отправляет приложение на ревью Apple: выбрать билд и отправить его на ревью нужно самому в App Store Connect.** Чтобы всё автоматизировать, ей нужен номер карточки приложения (`ascAppId`) и API-ключ App Store Connect.

Я публикую свои iOS-приложения, в том числе Solys, TradaZen и Nolera, через Expo, EAS Build и EAS Submit. Этот гайд опирается на [документацию Expo по отправке iOS](https://docs.expo.dev/submit/ios/), перечитанную 25 октября 2026 года. Если у тебя нет Mac, весь путь описан в статье [как опубликовать iOS-приложение без Mac](https://devoria.fr/ru/blog/publish-ios-app-without-mac-expo-eas). Здесь сосредоточимся на отправке.

## Что нужно до первой команды

Expo называет три обязательных условия:

- **Платный аккаунт Apple Developer.** Цена и регистрация описаны в статье [аккаунт разработчика Apple](https://devoria.fr/ru/blog/akkaunt-razrabotchika-apple-cena).
- **Bundle identifier** в `ios.bundleIdentifier`. Согласно [справочнику по конфигурации Expo](https://docs.expo.dev/versions/latest/config/app/), ты придумываешь его сам, но он должен быть уникальным в App Store.
- **Установленный EAS CLI**, затем `eas login` со своим аккаунтом Expo.

Ещё нужен подписанный продакшн-билд. EAS Build собирает его с сертификатом и профилем, которыми управляет за тебя, как объясняется в статье сертификат и provisioning profile для iOS.

### Карточка в App Store Connect: ты или EAS?

EAS Submit отправляет бинарник в приложение, которое уже должно существовать в App Store Connect.

**Можно создать её самому.** [Справка Apple](https://developer.apple.com/help/app-store-connect/create-an-app-record/add-a-new-app) описывает окно New App: платформа, название, основной язык, bundle identifier, SKU и доступ пользователей. Нужна роль Account Holder, Admin или App Manager.

**А можно доверить создание EAS при первой отправке.** Согласно [странице Expo о TestFlight](https://docs.expo.dev/submit/testflight/), `eas submit` создаёт карточку, когда ты отправляешь первый билд. Согласно [справочнику по eas.json](https://docs.expo.dev/eas/json/), если указать `ascAppId`, этот шаг пропускается. Название берётся из `appName`, а если его нет, из `name` в твоей конфигурации. Основной язык берётся из `language`, по умолчанию это `en-US`. **Если приложение сначала выходит на французском, укажи `language` до первой отправки.**

Потом скопируй номер карточки в `ascAppId`. Expo подсказывает, где его найти: открой приложение в App Store Connect, затем App Information. Это поле Apple ID в разделе General Information. **Это число, а не твой bundle identifier.**

## Почему API-ключ, а не Apple ID

EAS Submit подключается к Apple либо через твой Apple ID, либо через API-ключ App Store Connect.

Apple ID упирается в двухфакторную аутентификацию, которую [Apple требует](https://developer.apple.com/support/authentication/) от всех пользователей App Store Connect: вход должен подтвердить человек. Пароль приложения, переданный в `EXPO_APPLE_APP_SPECIFIC_PASSWORD`, обходит этот шаг, но [Expo считает его менее безопасным](https://github.com/expo/fyi/blob/main/apple-app-specific-password.md), чем API-ключ, который у Expo является методом по умолчанию и рекомендуемым. **Ключ позволяет аутентифицироваться без всякого участия человека, а значит, автоматизировать отправку.**

Получить его можно двумя путями:

- **Пусть EAS управляет ключом.** Запусти `eas credentials --platform ios`, выбери профиль `production`, войди в свой аккаунт Apple и выбери «App Store Connect: Manage your API Key».
- **Используй свой ключ.** В App Store Connect: Users and Access, вкладка Integrations, App Store Connect API, Team Keys, затем Generate API Key. Нужен аккаунт с ролью Admin, а [гайд Expo](https://github.com/expo/fyi/blob/main/creating-asc-api-key.md) даёт ключу роль Admin.

Во втором случае запиши Key ID, который показан в списке активных ключей, и Issuer ID, [вверху страницы Integrations](https://developer.apple.com/documentation/appstoreconnectapi/generating-tokens-for-api-requests). А главное, сохрани файл `.p8`: [скачать его можно только один раз](https://developer.apple.com/documentation/appstoreconnectapi/creating-api-keys-for-app-store-connect-api), и Apple не хранит копию.

> По словам Apple, ключ с ролью Admin может создавать и удалять пользователей твоего аккаунта. Apple просит никогда не хранить ключ в репозитории с кодом.

## Минимальный eas.json, который можно скопировать

Все значения выдуманные: замени их на свои.

```json
{
  "cli": {
    "appVersionSource": "remote"
  },
  "build": {
    "production": {
      "autoIncrement": true
    }
  },
  "submit": {
    "production": {
      "ios": {
        "ascAppId": "1234567890",
        "appleTeamId": "ABCDE12345",
        "ascApiKeyPath": "./keys/AuthKey_XXXXXXXXXX.p8",
        "ascApiKeyIssuerId": "your-issuer-id",
        "ascApiKeyId": "XXXXXXXXXX"
      }
    }
  }
}
```

- **`appVersionSource` и `autoIncrement`**: серверы EAS хранят номер билда и увеличивают его при каждом продакшн-билде. [Expo рекомендует этот удалённый режим](https://docs.expo.dev/build-reference/app-versions/) начиная с EAS CLI 12.
- **`ascAppId`**: номер твоей карточки. Без него неинтерактивный режим падает с ошибкой.
- **`appleTeamId`**: идентификатор твоей команды в Apple Developer.
- **`ascApiKeyPath`, `ascApiKeyIssuerId`, `ascApiKeyId`**: твой API-ключ. Все три поля принимают переменные окружения. Добавь папку `keys` в `.gitignore`.

Поле `appleId` нужно, только если ты входишь через Apple ID. Если EAS уже управляет твоим ключом, убери и три поля `ascApiKey`. В моих трёх приложениях, которые я перепроверил 25 октября, продакшн-профиль отправки содержит только `ascAppId`, плюс `appleTeamId` у Solys: никаких ключей в файле.

## Запускаем билд, потом отправку

```bash
eas build --platform ios --profile production
eas submit --platform ios
```

Без дополнительных опций `eas submit` предлагает выбрать билд для отправки и при первом запуске спрашивает твой Apple ID. Профиль отправки `production` используется по умолчанию, если он есть. В [справочнике EAS CLI](https://docs.expo.dev/eas/cli/) перечислены опции, которые избавляют от выбора:

| Опция            | Что делает                     |
| ---------------- | ------------------------------ |
| `--latest`       | Отправляет последний iOS-билд  |
| `--id`           | Отправляет конкретный билд EAS |
| `--path`         | Отправляет локальный файл .ipa |
| `--url`          | Отправляет архив по ссылке     |
| `--groups`       | Добавляет во внутреннюю группу |
| `--what-to-test` | Заполняет «What to test»       |

Чтобы связать всё в одну цепочку, добавь `--auto-submit` к команде билда. Согласно [странице Expo об автоматической отправке](https://docs.expo.dev/build/automate-submissions/), готовый билд уходит в EAS Submit с профилем отправки, который называется так же, как профиль билда. Чтобы выбрать другой: `--auto-submit-with-profile=имя`. **Билд уходит в TestFlight, а не на ревью.**

В CI добавь `--non-interactive` и токен `EXPO_TOKEN`. Тогда команда ничего не сможет у тебя спросить: ей нужен `ascAppId` в профиле и API-ключ, либо тот, что EAS привязал к приложению, либо твой в трёх полях `ascApiKey`.

## Что происходит после отправки

**1. Apple обрабатывает билд.** Он должен пройти эту обработку, прежде чем появится в App Store Connect, и по её окончании [Apple присылает тебе письмо](https://developer.apple.com/help/app-store-connect/manage-builds/upload-builds). По словам Expo, обычно проходит 10-15 минут, прежде чем билд виден в TestFlight.

**2. Экспортное соответствие.** Статус Missing Compliance означает, что не хватает твоей декларации о шифровании. App Store Connect задаёт эти вопросы для каждой новой версии, если только Info.plist уже не отвечает на них. В Expo ключ называется `ios.config.usesNonExemptEncryption`:

```json
{
  "expo": {
    "ios": {
      "config": {
        "usesNonExemptEncryption": false
      }
    }
  }
}
```

Согласно [Apple](https://developer.apple.com/documentation/security/complying-with-encryption-export-regulations), `false` подходит, если твоё приложение, включая библиотеки, не использует шифрование вообще или использует только освобождённое от требований. Системное шифрование, например HTTPS через URLSession, как правило, таким и является. **Указывай `false`, только если это правда для твоего приложения: декларация накладывает на тебя обязательства.** Как и любой ключ Info.plist, она требует нового билда.

**3. TestFlight.** Когда билд в статусе Ready to Submit, [по данным Apple](https://developer.apple.com/help/app-store-connect/reference/app-build-statuses), его можно дать внутренним тестировщикам, отправить на бета-ревью для внешних или на ревью App Store. Поле `groups` в профиле добавляет его в твои внутренние группы. Всё остальное в статье [TestFlight: как тестировать приложение](https://devoria.fr/ru/blog/testflight-testirovanie-iphone-prilozheniya).

## Отправка билда это не отправка на ревью

[Expo прямо пишет](https://docs.expo.dev/submit/introduction/): билд из TestFlight не публикуется в App Store автоматически. EAS Submit не заполняет ни карточку, ни скриншоты. В App Store Connect остаётся четыре действия, описанных в [справке Apple об отправке на ревью](https://developer.apple.com/help/app-store-connect/manage-submissions-to-app-review/submit-an-app):

1. **Заполни обязательные метаданные** версии.
2. **Выбери билд** в разделе Build версии.
3. **Нажми «Add for Review».** Версия переходит в статус Ready for Review, но на ревью пока ничего не ушло.
4. **Нажми «Submit for Review».** Статус меняется на In Review, когда ревью начинается.

## Частые ошибки и как их исправить

| Ошибка               | Причина                       | Исправление               |
| -------------------- | ----------------------------- | ------------------------- |
| ITMS-90189           | Номер билда уже занят         | `autoIncrement`           |
| ITMS-90062 или 90186 | Версия уже закрыта            | Поднять `version`         |
| «Set ascAppId»       | Нет `ascAppId` в CI           | Добавить `ascAppId`       |
| «API Keys cannot»    | Ключ не привязан              | `eas credentials`         |
| ITMS-90683           | Нет purpose string            | `ios.infoPlist`           |
| ITMS-91053           | Неполный манифест             | `ios.privacyManifests`    |
| ITMS-90725           | Слишком старый iOS SDK        | Обновить Expo SDK         |
| Missing Compliance   | Шифрование не задекларировано | `usesNonExemptEncryption` |

По словам Expo, уже использованный номер билда это частая причина отказа при отправке: подробности в статье номер билда и версия. У трёх ошибок есть отдельные гайды: [ITMS-90683 в Expo](https://devoria.fr/ru/blog/itms-90683-missing-purpose-string-expo), [ITMS-91053 в Expo](https://devoria.fr/ru/blog/itms-91053-missing-api-declaration-expo) и ITMS-90725.

Два сообщения в кавычках выдаёт EAS, и исправляются они в его конфигурации. Missing Compliance можно решить и ответами на вопросы в App Store Connect. **Для всех остальных строк исправление затрагивает бинарник: пересобери билд и отправь его заново.** Удалённое обновление не меняет ни Info.plist, ни манифест, ни номера.

## Отправь первое приложение без лишних проб и ошибок

Команда это лишь один шаг. [iOS Kit](https://devoria.fr/ru/kits/ios) основан на стартовом коде моих приложений, включая подписки, и ведёт тебя через четыре этапа до App Store в твоём темпе.

Если готовишь свой первый релиз, [пройди бесплатную диагностику](https://devoria.fr/ru/diagnostic): она покажет, что тебя на самом деле тормозит, и пришлёт мой чек-лист против отказов Apple. Про карточку, скриншоты и прохождение ревью каждый этап разобран на странице [как опубликовать приложение в App Store](https://devoria.fr/ru/expertise/publish-app-on-app-store).

## Частые вопросы

### Как опубликовать приложение Expo в App Store?

Собери продакшн-билд через EAS Build, затем отправь его командой `eas submit --platform ios`. После обработки на стороне Apple он появится в TestFlight. Дальше в App Store Connect заполни карточку, выбери этот билд в версии и нажми «Add for Review», а затем «Submit for Review».

### EAS Submit отправляет моё приложение на ревью Apple?

Нет. EAS Submit отправляет бинарник в App Store Connect, и билд попадает в TestFlight. На ревью ты отправляешь вручную в App Store Connect, когда карточка заполнена и билд выбран.

### Где найти ascAppId моего приложения?

В App Store Connect открой приложение, затем App Information. Это поле Apple ID в разделе General Information. Это число, не путай его с bundle identifier.

### Нужен ли Apple ID, чтобы пользоваться eas submit?

При первом запуске команда его спросит. Потом, с `ascAppId` в профиле и API-ключом App Store Connect, она может работать без участия человека, даже в CI. API-ключ у Expo является методом по умолчанию и рекомендуемым.

### Сколько ждать, пока билд появится в TestFlight?

По словам Expo, обработка у Apple обычно занимает 10-15 минут, а по её окончании Apple присылает письмо. Если билд застрял в статусе Missing Compliance, ответь на вопросы о шифровании, а затем задекларируй его в конфигурации для следующих билдов.


## Твой проект

[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 €.
