EAS Submit iOS: как опубликовать приложение Expo в App Store
Автор: Mehdi Azizi
Опубликовано , 8 мин
EAS Submit отправляет iOS-билд в App Store Connect, и он появляется в TestFlight. Отправку на ревью ты делаешь сам в App Store Connect.
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, перечитанную 25 октября 2026 года. Если у тебя нет Mac, весь путь описан в статье как опубликовать iOS-приложение без Mac. Здесь сосредоточимся на отправке.
Что нужно до первой команды
Expo называет три обязательных условия:
- Платный аккаунт Apple Developer. Цена и регистрация описаны в статье аккаунт разработчика Apple.
- Bundle identifier в
ios.bundleIdentifier. Согласно справочнику по конфигурации Expo, ты придумываешь его сам, но он должен быть уникальным в App Store. - Установленный EAS CLI, затем
eas loginсо своим аккаунтом Expo.
Ещё нужен подписанный продакшн-билд. EAS Build собирает его с сертификатом и профилем, которыми управляет за тебя, как объясняется в статье сертификат и provisioning profile для iOS.
Карточка в App Store Connect: ты или EAS?
EAS Submit отправляет бинарник в приложение, которое уже должно существовать в App Store Connect.
Можно создать её самому. Справка Apple описывает окно New App: платформа, название, основной язык, bundle identifier, SKU и доступ пользователей. Нужна роль Account Holder, Admin или App Manager.
А можно доверить создание EAS при первой отправке. Согласно странице Expo о TestFlight, eas submit создаёт карточку, когда ты отправляешь первый билд. Согласно справочнику по 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 требует от всех пользователей App Store Connect: вход должен подтвердить человек. Пароль приложения, переданный в EXPO_APPLE_APP_SPECIFIC_PASSWORD, обходит этот шаг, но Expo считает его менее безопасным, чем 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 даёт ключу роль Admin.
Во втором случае запиши Key ID, который показан в списке активных ключей, и Issuer ID, вверху страницы Integrations. А главное, сохрани файл .p8: скачать его можно только один раз, и Apple не хранит копию.
По словам Apple, ключ с ролью Admin может создавать и удалять пользователей твоего аккаунта. Apple просит никогда не хранить ключ в репозитории с кодом.
Минимальный eas.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 рекомендует этот удалённый режим начиная с EAS CLI 12.ascAppId: номер твоей карточки. Без него неинтерактивный режим падает с ошибкой.appleTeamId: идентификатор твоей команды в Apple Developer.ascApiKeyPath,ascApiKeyIssuerId,ascApiKeyId: твой API-ключ. Все три поля принимают переменные окружения. Добавь папкуkeysв.gitignore.
Поле appleId нужно, только если ты входишь через Apple ID. Если EAS уже управляет твоим ключом, убери и три поля ascApiKey. В моих трёх приложениях, которые я перепроверил 25 октября, продакшн-профиль отправки содержит только ascAppId, плюс appleTeamId у Solys: никаких ключей в файле.
Запускаем билд, потом отправку
eas build --platform ios --profile production
eas submit --platform ios
Без дополнительных опций eas submit предлагает выбрать билд для отправки и при первом запуске спрашивает твой Apple ID. Профиль отправки production используется по умолчанию, если он есть. В справочнике EAS CLI перечислены опции, которые избавляют от выбора:
| Опция | Что делает |
|---|---|
--latest | Отправляет последний iOS-билд |
--id | Отправляет конкретный билд EAS |
--path | Отправляет локальный файл .ipa |
--url | Отправляет архив по ссылке |
--groups | Добавляет во внутреннюю группу |
--what-to-test | Заполняет «What to test» |
Чтобы связать всё в одну цепочку, добавь --auto-submit к команде билда. Согласно странице Expo об автоматической отправке, готовый билд уходит в EAS Submit с профилем отправки, который называется так же, как профиль билда. Чтобы выбрать другой: --auto-submit-with-profile=имя. Билд уходит в TestFlight, а не на ревью.
В CI добавь --non-interactive и токен EXPO_TOKEN. Тогда команда ничего не сможет у тебя спросить: ей нужен ascAppId в профиле и API-ключ, либо тот, что EAS привязал к приложению, либо твой в трёх полях ascApiKey.
Что происходит после отправки
1. Apple обрабатывает билд. Он должен пройти эту обработку, прежде чем появится в App Store Connect, и по её окончании Apple присылает тебе письмо. По словам Expo, обычно проходит 10-15 минут, прежде чем билд виден в TestFlight.
2. Экспортное соответствие. Статус Missing Compliance означает, что не хватает твоей декларации о шифровании. App Store Connect задаёт эти вопросы для каждой новой версии, если только Info.plist уже не отвечает на них. В Expo ключ называется ios.config.usesNonExemptEncryption:
{
"expo": {
"ios": {
"config": {
"usesNonExemptEncryption": false
}
}
}
}
Согласно Apple, false подходит, если твоё приложение, включая библиотеки, не использует шифрование вообще или использует только освобождённое от требований. Системное шифрование, например HTTPS через URLSession, как правило, таким и является. Указывай false, только если это правда для твоего приложения: декларация накладывает на тебя обязательства. Как и любой ключ Info.plist, она требует нового билда.
3. TestFlight. Когда билд в статусе Ready to Submit, по данным Apple, его можно дать внутренним тестировщикам, отправить на бета-ревью для внешних или на ревью App Store. Поле groups в профиле добавляет его в твои внутренние группы. Всё остальное в статье TestFlight: как тестировать приложение.
Отправка билда это не отправка на ревью
Expo прямо пишет: билд из TestFlight не публикуется в App Store автоматически. EAS Submit не заполняет ни карточку, ни скриншоты. В App Store Connect остаётся четыре действия, описанных в справке Apple об отправке на ревью:
- Заполни обязательные метаданные версии.
- Выбери билд в разделе Build версии.
- Нажми «Add for Review». Версия переходит в статус Ready for Review, но на ревью пока ничего не ушло.
- Нажми «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, ITMS-91053 в Expo и ITMS-90725.
Два сообщения в кавычках выдаёт EAS, и исправляются они в его конфигурации. Missing Compliance можно решить и ответами на вопросы в App Store Connect. Для всех остальных строк исправление затрагивает бинарник: пересобери билд и отправь его заново. Удалённое обновление не меняет ни Info.plist, ни манифест, ни номера.
Отправь первое приложение без лишних проб и ошибок
Команда это лишь один шаг. iOS Kit основан на стартовом коде моих приложений, включая подписки, и ведёт тебя через четыре этапа до App Store в твоём темпе.
Если готовишь свой первый релиз, пройди бесплатную диагностику: она покажет, что тебя на самом деле тормозит, и пришлёт мой чек-лист против отказов Apple. Про карточку, скриншоты и прохождение ревью каждый этап разобран на странице как опубликовать приложение в 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, ответь на вопросы о шифровании, а затем задекларируй его в конфигурации для следующих билдов.