Build number в App Store Connect: версия и номер сборки
Автор: Mehdi Azizi
Опубликовано , 8 мин
Версию видят твои клиенты, а build number идентифицирует каждую загрузку. Пара должна быть уникальной: в Expo номер сборки за тебя поднимает EAS.
Build number в App Store Connect означает номер сборки: ключ CFBundleVersion, который идентифицирует каждую загрузку. Версия, CFBundleShortVersionString, это номер, который твои клиенты видят в App Store. Apple требует, чтобы пара «версия + номер сборки» была уникальной: один номер сборки используется для одной версии только один раз.
В Expo версию ты задаёшь сам, а EAS может увеличивать номер сборки при каждом production-билде. В этом гайде разберём оба номера, правила Apple, ошибки ITMS-90062 и ITMS-90189 и что проверить, если твоя сборка не появляется.
Я публикую свои iOS-приложения через Expo и EAS, среди них Solys, TradaZen и Nolera. Настройки ниже взяты из их файлов eas.json.
Версия и номер сборки: в чём разница?
Твоё приложение идентифицируют два ключа Info.plist. Документация Apple по CFBundleShortVersionString описывает его как версию, видимую пользователю: три целых числа через точку, например 10.14.1. Документация по CFBundleVersion говорит о версии сборки: от одного до трёх целых чисел, только цифры и точки.
| Элемент | Ключ iOS | Кто видит | Поле Expo |
|---|---|---|---|
| Версия | CFBundleShortVersionString | Твои клиенты | version |
| Номер сборки | CFBundleVersion | Ты и Apple | ios.buildNumber |
Вымышленный пример: для версии 1.4.0 ты во время тестов отправляешь сборки 12, 13 и 14, а потом выбираешь одну из них для ревью. Справка App Store Connect формулирует так: версия привязывает сборку к карточке приложения, а номер сборки идентифицирует её во всей системе.
Правила увеличения номеров у Apple
- Пара должна быть уникальной. Согласно документации Xcode Cloud, App Store Connect требует уникальную комбинацию версии и номера сборки. Поэтому приложение для iPhone может начать с 1 для новой версии. Приложение для Mac не может: его номер должен всегда расти.
- Одобренная версия закрыта. Как только Apple одобрила версию 1.4.0, добавить к ней сборку уже нельзя. Следующая должна иметь номер выше.
- Каждое число сравнивается как целое. 1.10 идёт после 1.9, потому что 10 больше 9. Версию 1.9, отправленную после одобренной 1.20, отклонят.
Мой совет: держи целочисленный номер сборки, который всегда растёт, и не сбрасывай его на 1. Сброс на 1 на iPhone разрешён, но номер, уникальный на всю жизнь приложения, избавляет от путаницы между двумя сборками в TestFlight. Так у меня и выходит в приложениях в удалённом режиме: счётчик продолжается от версии к версии.
Управление версией и сборкой в Expo и EAS
Страница Expo о версиях, обновлённая 25 сентября 2026 года, разделяет роли. Версия (version в app.json) остаётся за тобой: ты меняешь её, когда готовишь новый релиз. Номер сборки (ios.buildNumber) можно доверить EAS. Кстати, Expo называет забытое увеличение номера частой причиной отказа при загрузке.
Всё настраивается в eas.json:
{
"cli": {
"appVersionSource": "remote"
},
"build": {
"production": {
"autoIncrement": true
}
}
}
"remote": номер сборки хранят серверы EAS. Это рекомендуемое поведение начиная с EAS CLI 12. Счётчик стартует со значения из твоей конфигурации или с 1, после чегоios.buildNumberигнорируется."local": источником истины служит твоя конфигурация. СautoIncrementEAS меняетios.buildNumberв твоём файле, и это изменение нужно коммитить после каждого билда.autoIncrement: справочник eas.json принимаетtrueили"buildNumber"для сборки и"version", чтобы поднять последнюю цифру версии. Expo уточняет, что в удалённом режиме"version"не поддерживается.
У меня TradaZen и Nolera работают в remote. Solys осталась в local: её номер сборки живёт в app.json, и каждый production-билд поднимает его в файле. Оба варианта работают, но удалённый режим убирает риск забытого коммита.
Систему дополняют две команды. eas build:version:set инициализирует удалённый счётчик: введи последний номер, отправленный в Apple. eas build:version:sync копирует удалённые значения в твой проект, пригодится, если однажды будешь собирать через Xcode. С EAS Update удалённый режим не работает с политикой nativeVersion: Expo советует appVersion.
ITMS-90062: версия уже одобрена
Сообщение выглядит так (номера вымышленные):
ERROR ITMS-90062: This bundle is invalid. The value for key
CFBundleShortVersionString [1.4.0] in the Info.plist file must
contain a higher version than that of the previously approved
version [1.4.0].
Apple уже одобрила версию 1.4.0: добавить к ней сборку больше нельзя. Подними версию в app.json, например до 1.4.1, и запусти билд заново. Изменить только номер сборки недостаточно.
Если ошибка повторяется, хотя version уже обновлена, поищи поле ios.version. Согласно справочнику конфигурации Expo, для iOS оно имеет приоритет над version. То же лечение подходит для родственной ошибки ITMS-90186, «Invalid Pre-Release Train», которая сообщает, что версия закрыта для новых сборок.
ITMS-90189: Redundant Binary Upload
Здесь проблема в номере сборки:
ERROR ITMS-90189: Redundant Binary Upload. You've already uploaded
a build with build number '12' for version number '1.4.0'.
Пара 1.4.0 (12) у Apple уже есть. В Expo чаще всего встречаются четыре причины:
- В используемом профиле нет
autoIncrement. Если ты создаёшь отдельный профиль для TestFlight, как у Nolera, добавь туда эту опцию. - Удалённый счётчик отстаёт. Ты перешёл на
remoteпосле ручных загрузок: запустиeas build:version:setс последним номером, известным Apple. - В локальном режиме забыли коммит. Следующий билд стартует со старого номера.
- Ты повторно отправляешь тот же бинарник. В
eas submitвыбирай новую сборку, а не старую.
Исправление всегда одно: новый билд с номером выше.
«No builds available»: сборка не появляется
Сборка ушла, но карточка приложения её не предлагает. Проверяй в таком порядке.
- Она ещё обрабатывается. Apple обрабатывает каждую сборку перед показом и присылает письмо по окончании. Expo обычно говорит о 10-15 минутах. По словам Apple, если обработка длится больше 24 часов, нужно открыть тикет в Feedback Assistant.
- Она ждёт твоей декларации о шифровании. Это статус Missing Compliance, подробнее ниже.
- Версия не совпадает. Сборка 1.4.1 не попадёт в карточку, подготовленную под 1.5.0 в App Store Connect. Выровняй их.
- За это время вышла версия. Согласно справке о выборе сборки, тогда список показывает только сборки, загруженные после этого релиза.
- Сборку не видит тестировщик. В приложении TestFlight «no builds available» часто означает, что сборка не входит ни в одну группу, ждёт бета-ревью или истекла. Подробности в статье TestFlight для тестирования приложения для iPhone.
Статусы, которые нужно знать
Статусы, которые чаще всего объясняют отсутствие сборки, по списку Apple. Processing и Failed в нём нет: это статусы загрузки, описанные в отслеживании сборок.
| Статус | Что означает | Что делать |
|---|---|---|
| Processing | Apple обрабатывает сборку | Ждать письма |
| Failed | Ошибка при обработке | Прочитать ошибку, отправить заново |
| Missing Compliance | Шифрование не задекларировано | Ответить или Info.plist |
| Invalid Binary | Загрузка не по правилам | Исправить, новый билд |
| Expired | Прошло 90 дней | Новый билд |
| Ready to Submit | Готова к тесту или ревью | Добавить в группу |
Задекларировать шифрование раз и навсегда
Без ключа ITSAppUsesNonExemptEncryption Apple задаёт вопросы о соответствии при каждой новой версии. В Expo поле называется ios.config.usesNonExemptEncryption:
{
"expo": {
"ios": {
"config": {
"usesNonExemptEncryption": false
}
}
}
}
false означает: шифрования нет или есть только освобождённое от требований. Apple уточняет, что встроенное в систему шифрование, например HTTPS-соединения, обычно освобождено, и что ответ распространяется и на твои библиотеки. Все три мои приложения декларируют false. Ставь false, только если это правда для твоего приложения: за декларацию отвечаешь ты.
Можно ли изменить номер уже отправленной сборки?
Нет. Номер записан в подписанном бинарнике: чтобы его исправить, нужен новый билд.
Изменить можно сборку, привязанную к твоей версии. Apple разрешает одну сборку на версию, но заменять её можно сколько угодно раз до отправки на ревью:
- Открой версию в App Store Connect, раздел Build.
- Наведи курсор на текущую сборку и нажми кнопку удаления, знак минус.
- Нажми кнопку добавления, знак плюс, выбери нужную сборку и сохрани.
Удаление сборки из версии не удаляет её из твоего аккаунта. Если версия уже на ревью, сначала отзови отправку: ревью начнётся с нуля.
Перед следующей загрузкой
Номер сборки лишь одна из проверок при загрузке. Образ сборки может вызвать ITMS-90725, а у подписи свои ловушки, о них в статье сертификат разработчика iOS и provisioning profile. Вся цепочка от билда до TestFlight описана в статье опубликовать iOS-приложение без Mac, а сроки ревью в статье сроки проверки в App Store. Все шаги собраны на странице опубликовать приложение в App Store.
Если готовишь первый релиз, пройди бесплатную диагностику: она покажет, что блокирует твой проект, и пришлёт мой чек-лист против отказов Apple. Чтобы создать приложение, подключить подписки и опубликовать его, iOS & Android Kit ведёт по пути из четырёх шагов со стартовым кодом моих приложений, в твоём темпе.
Частые вопросы
В чём разница между версией и build number в App Store Connect?
Версия это публичный номер твоего релиза, например 1.4.0. Build number идентифицирует конкретный бинарник, отправленный в Apple для этой версии. Для одной версии можно отправить несколько сборок, у каждой свой номер.
Нужно ли менять номер сборки при каждой загрузке?
Да, в рамках одной версии. Apple отклоняет повторную загрузку с той же парой «версия + номер сборки», это ошибка ITMS-90189. В EAS об этом заботится autoIncrement при каждом production-билде.
Должен ли номер сборки начинаться с 1 для каждой версии?
Это не обязательно. На iPhone Apple принимает более низкий номер для новой версии, потому что уникальной должна быть только пара. Счётчик, который всегда растёт, проще отслеживать.
Как изменить build number в App Store Connect?
Номер уже отправленной сборки изменить нельзя. Зато можно заменить сборку, привязанную к версии, в разделе Build карточки, пока она не на ревью. Для нового номера сделай новый билд.
Почему моя сборка не появляется в App Store Connect?
Чаще всего она ещё обрабатывается или ждёт декларации о шифровании. Проверь также, что её версия совпадает с версией в карточке. Если обработка длится больше 24 часов, Apple просит открыть тикет.

