React Native 0.86: облачная сборка iOS в 2026

React Native 0.86: облачная сборка iOS в 2026

React Native 0.86: облачная сборка iOS в 2026

Облачная сборка iOS для React Native 0.86 лучше всего работает по двухсредной схеме: JavaScript и TypeScript остаются на Windows или Linux, а установка iOS-зависимостей, Xcode, симулятор, Archive, подпись и загрузка выполняются на удалённом Mac. Такой подход подходит проектам с нативными модулями, CocoaPods или прямыми изменениями Xcode.

Эта инструкция рассчитана на три группы:

  • независимых разработчиков, пишущих React Native на Windows или Linux;
  • сопровождающих проект с нативными модулями и сложным Podfile;
  • небольшие команды, которым нужна постоянно восстанавливаемая iOS-среда, а не разовая ручная сборка.

Последовательность важнее конкретной команды. Сначала фиксируется окружение. Затем восстанавливаются зависимости. После этого проверяются Debug, Release Archive и App Store Connect. React Native 0.86 имеет стабильный официальный релиз от 9 июня 2026 года, поэтому версию проекта нужно сверять с lock-файлами и документацией, а не с автоматически установленным шаблоном. (официальная страница React Native 0.86)

Последняя проверка этой инструкции выполнена 15 августа 2026 года по официальному релизу React Native 0.86, документации по настройке окружения и материалам Apple для распространения приложений.

Локальный код против удалённой нативной среды

В локальной системе остаются редактор, Git, JavaScript-код, TypeScript, тесты интерфейса и Android-часть. На удалённый Mac передаются только исходники и файлы, необходимые для воспроизводимой iOS-сборки.

На Mac выполняются:

  • установка Xcode и Command Line Tools;
  • восстановление Ruby- и CocoaPods-зависимостей;
  • запуск iOS Simulator;
  • компиляция нативных модулей;
  • создание Release Archive;
  • проверка Bundle ID, Entitlements и подписи;
  • загрузка сборки в App Store Connect.

Это не просто вопрос удобства. Есть несколько ограничений.

Во-первых, Xcode и iOS Simulator не являются обычными кроссплатформенными инструментами. Windows или Linux могут оставаться рабочим местом для кода, но не заменяют macOS при сборке нативной части.

Во-вторых, проект с React Native Framework может скрывать часть нативной настройки, но это не отменяет iOS-инструменты, если нужны собственные модули, изменённый Podfile, push-уведомления, платежи, App Clips или прямые правки Xcode-проекта. Официальная документация React Native отдельно описывает установку окружения для проектов с нативным кодом. (документация React Native по окружению)

В-третьих, удалённое окружение должно сохранять состояние. Если после каждого подключения приходится заново устанавливать Node, CocoaPods, сертификаты и симуляторы, это не строительная инфраструктура, а временная сессия. Для редких релизов такой вариант допустим. Для частых сборок — нет.

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

  • доступ к Git-репозиторию;
  • роль в Apple Developer Program;
  • наличие нужного Bundle ID;
  • запись приложения в App Store Connect;
  • package.json и lock-файл JavaScript-зависимостей;
  • Gemfile, Podfile и Podfile.lock;
  • схему сборки и целевую конфигурацию;
  • способ хранения сертификатов или API Key;
  • ожидаемый канал: Debug, TestFlight или публикация в App Store.

Если собственного Mac нет, полезно заранее сравнить стоимость аренды Mac в России с покупкой отдельного компьютера. Сравнивать следует не только цену устройства, но и срок использования, постоянное питание, обновления, удалённый доступ и время восстановления среды.

Решающий список: какую схему выбрать

Этот список нужно пройти до установки инструментов. Каждый пункт ведёт к конкретному решению.

  • [ ] Если основная работа выполняется в JavaScript или TypeScript, а iOS-сборка нужна только перед релизом, выбирайте локальную разработку плюс временный удалённый Mac.
  • [ ] Если проект содержит собственные нативные модули, изменённый Podfile или прямые правки Xcode, выбирайте полноценный удалённый Mac с графическим доступом и SSH.
  • [ ] Если Archive выполняется несколько раз в неделю, не ограничивайтесь разовой сессией: нужна сохраняемая среда и повторяемый способ восстановления.
  • [ ] Если требуется ручная работа в Xcode или iOS Simulator, подключайте VNC или другой графический удалённый доступ.
  • [ ] Если основной процесс состоит из повторяемых команд, логов и скриптов, обязательно используйте SSH.
  • [ ] Если после отключения теряются Pods, сертификаты или настройки Xcode, не принимайте среду для постоянного CI-процесса, пока не исправлена её персистентность.
  • [ ] Если требуются USB-подключение к физическому iPhone, локальные датчики или периферия, возвращайтесь к собственному Mac либо заранее подтверждайте поддержку такого сценария.
  • [ ] Если проект не проходит Debug, не переходите к подписи и App Store Connect: сначала классифицируйте ошибку зависимостей, компиляции, линковки или запуска.

Итоговое правило простое: при наличии хотя бы одного нативного модуля и необходимости самостоятельно управлять Xcode выбирайте удалённый Mac с root-доступом, графическим подключением и SSH; если нужен только редкий финальный Archive, достаточно временной среды.

Первый час: фиксируем инструментальную базу

React Native 0.86 не даёт универсального списка версий для каждого проекта. Конкретные значения нужно читать из package.json, Gemfile, Podfile, документации используемых модулей и текущих требований Xcode. Нельзя механически переносить версии из чужого проекта.

На удалённом Mac сначала откройте терминал и зафиксируйте базовое состояние:

sw_vers
xcodebuild -version
xcode-select -p
node --version
ruby --version
git --version

Затем выберите активный каталог разработчика:

sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
xcodebuild -runFirstLaunch

Проверьте результат:

xcode-select -p
xcodebuild -version

Путь и версия должны соответствовать установленному Xcode. Если команда в интерактивном терминале проходит, а сборка из SSH не видит node, причина часто находится в переменных окружения. React Native рекомендует использовать .xcode.env, где можно явно задать NODE_BINARY и отделить Xcode-скрипты от случайного состояния оболочки. (документация React Native по настройке iOS)

Пример проверки:

cat ios/.xcode.env
which node
printenv PATH

Если проект использует менеджер версий Node, путь должен быть доступен и обычному shell-скрипту Xcode. Нельзя полагаться только на загрузку .zshrc: графический Xcode и неинтерактивный SSH-процесс могут получить разные переменные.

Далее проверьте Ruby-зависимости:

cd /path/to/<PROJECT_DIR>
bundle check || bundle install

Все значения в этой команде являются заполнителями. <PROJECT_DIR> нужно заменить на путь проекта, но не на локальный путь с Windows или Linux.

Для CocoaPods используйте зафиксированную версию из проекта:

cd ios
bundle exec pod --version
bundle exec pod install

Официальная интеграционная документация React Native для шаблона 0.86 также показывает связку Gemfile, bundle install и bundle exec pod install. (инструкция React Native по интеграции)

Закончите первый час сохранением отчёта:

{
  date
  sw_vers
  xcodebuild -version
  node --version
  ruby --version
  bundle exec pod --version
  git rev-parse --short HEAD
} | tee /tmp/<BUILD_ENV_REPORT>.txt

В отчёте не должно быть токенов, приватных ключей и паролей. Зато должны остаться версия коммита, версия Xcode, Node, Ruby и CocoaPods. Это основа для восстановления.

Чистая синхронизация вместо переноса кешей

Наиболее безопасная передача проекта — через Git. Сначала на локальной машине проверьте статус:

git status
git ls-files package-lock.json yarn.lock pnpm-lock.yaml Gemfile.lock ios/Podfile.lock

В проекте обычно используется один основной lock-файл JavaScript-зависимостей. Не следует запускать три разных менеджера пакетов только потому, что они установлены на Mac. Выберите способ, который уже используется в репозитории.

На удалённой системе:

git clone <REPOSITORY_URL> <PROJECT_DIR>
cd <PROJECT_DIR>
git checkout <COMMIT_OR_BRANCH>

Затем восстановите зависимости соответствующей командой:

npm ci

или:

yarn install --frozen-lockfile

или:

pnpm install --frozen-lockfile

После этого восстановите iOS-зависимости:

cd ios
bundle install
bundle exec pod install
cd ..

Не копируйте между системами:

  • node_modules;
  • ios/Pods;
  • ios/build;
  • DerivedData;
  • старые .xcarchive;
  • локальные файлы с абсолютными путями;
  • сертификаты и ключи внутри репозитория.

Причина не только в размере. Эти каталоги содержат результаты разрешения зависимостей, архитектурные артефакты и пути к конкретному окружению. Перенос может создать ложное ощущение исправности, а ошибка появится уже на Release Archive.

После установки проверьте Podfile и скрипты:

grep -R "<LOCAL_PATH>\|/Users/\|/home/" ios package.json scripts 2>/dev/null

Если найден абсолютный путь, замените его на переменную окружения, относительный путь или настройку проекта. Особое внимание уделите script_phase, генерации кода и вызовам Node.

Для диагностики полезно различать три результата:

  • JavaScript-пакеты не разрешились — проблема менеджера пакетов или lock-файла;
  • pod install не завершился — проблема Ruby, CocoaPods, Podfile или нативной зависимости;
  • Pods установились, но Xcode не собирает — проблема компиляции, линковки, конфигурации или подписи.

Эти уровни нельзя смешивать. Успешный pod install не доказывает, что приложение готово к Archive.

Первый Debug: проверяем путь от Metro до симулятора

Debug-сборка нужна до публикации. Она показывает, что исходники, Metro, генерация кода, нативные модули и схема Xcode работают вместе.

Сначала запустите Metro в отдельной SSH-сессии:

cd <PROJECT_DIR>
npx react-native start --reset-cache

--reset-cache не следует применять при каждой ошибке. Один раз он помогает исключить устаревший кеш. Постоянное удаление кешей маскирует проблемы с импортами, версиями или генерацией файлов.

В другой сессии выберите схему и симулятор:

npx react-native run-ios \
  --scheme "<APP_SCHEME>" \
  --simulator "<SIMULATOR_NAME>"

Названия <APP_SCHEME> и <SIMULATOR_NAME> заменяются значениями из проекта. Нельзя вставлять в команду чужие Bundle ID или названия устройств.

Графический удалённый рабочий стол удобен для:

  • выбора схемы;
  • просмотра настроек Signing & Capabilities;
  • запуска и остановки симулятора;
  • проверки логов Xcode;
  • работы с Organizer.

SSH лучше использовать для повторяемых команд:

  • установки зависимостей;
  • запуска Metro;
  • очистки и сборки;
  • формирования логов;
  • повторного запуска после обрыва соединения.

Это разные режимы работы. VNC или браузерный доступ не заменяет SSH, а SSH не всегда удобен для визуальной настройки Xcode.

Если Debug не запускается, сохраняйте лог по этапам:

npx react-native run-ios \
  --scheme "<APP_SCHEME>" \
  --simulator "<SIMULATOR_NAME>" \
  2>&1 | tee /tmp/<DEBUG_LOG>.txt

Классификация должна быть следующей:

  1. Зависимости — пакет не найден, Pod не разрешён, несовместимый lock-файл.
  2. Компиляция — ошибка Objective-C, Swift, C++ или сгенерированного кода.
  3. Линковка — отсутствующий фреймворк, символ или архитектура.
  4. Запуск — приложение собрано, но не стартует на симуляторе или не подключается к Metro.

Только после прохождения Debug имеет смысл переходить к подписи. Иначе ошибки подписи будут смешаны с ошибками исходного проекта.

Release Archive и App Store Connect: четыре разных результата

Release-путь следует принимать поэтапно. «Приложение загружено» не равно «сборка обработана», а «сборка обработана» не равно «версия отправлена на проверку».

Проверьте схему и Release-конфигурацию в Xcode. Затем выполните Archive через интерфейс или командой:

xcodebuild \
  -workspace "ios/<WORKSPACE_NAME>.xcworkspace" \
  -scheme "<APP_SCHEME>" \
  -configuration Release \
  -archivePath "/tmp/<APP_NAME>.xcarchive" \
  archive

Если проект использует .xcodeproj, замените параметр -workspace на -project. Для React Native с CocoaPods обычно требуется workspace, но это нужно подтверждать структурой ios.

После Archive проверьте наличие результата:

test -d "/tmp/<APP_NAME>.xcarchive" && echo "Archive exists"

Apple описывает Archive как сборку, которую Xcode сохраняет в Organizer для последующей валидации, экспорта или загрузки. Перед публикацией можно выполнить Validate App, а затем выбрать распространение через TestFlight и App Store. (документация Apple по распространению приложений)

Перед загрузкой проверьте:

  • Bundle ID совпадает с записью приложения;
  • версия приложения соответствует планируемому релизу;
  • build number ещё не использовался для этой версии;
  • Entitlements соответствуют включённым возможностям;
  • выбрана правильная команда разработчика;
  • сертификат и provisioning profile относятся к нужному приложению;
  • в Archive нет лишних конфигураций или тестовых секретов.

Apple указывает, что Bundle ID и номер версии используются для связи загруженной сборки с записью приложения в App Store Connect, а build string идентифицирует конкретную сборку. (требования Apple к загружаемым сборкам)

Порядок проверки:

  1. Archive создан.
  2. Archive прошёл Validate App.
  3. Экспорт или загрузка завершились без ошибки.
  4. Сборка появилась в App Store Connect.
  5. Обработка Apple завершилась.
  6. Сборка выбрана для версии приложения.
  7. Только после этого можно переходить к отправке на App Review.

Для ручной загрузки достаточно Organizer и пункта Distribute App. Для автоматизации можно использовать Transporter или App Store Connect API. Секреты должны храниться отдельно от исходного кода, а роль ключа — ограничиваться необходимыми операциями.

Пример команды оставляйте только с заполнителями:

xcrun altool \
  --upload-app \
  -f "/tmp/<APP_ARCHIVE>.ipa" \
  -t ios \
  -u "<APPLE_ACCOUNT>" \
  -p "<APP_SPECIFIC_SECRET>"

Конкретный метод зависит от политики команды и текущей поддержки инструментов. Секрет нельзя записывать прямо в shell history, Git, CI-конфигурацию или общий текстовый файл.

Статусы App Store Connect также нужно читать буквально. Processing означает, что Apple ещё обрабатывает загрузку. Complete означает готовность сборки к тестированию. Failed требует просмотра ошибки и повторной загрузки после исправления. (описание статусов загрузки Apple)

Первая неделя: превращаем разовую сборку в устойчивую систему

После первого успешного Archive нельзя сразу считать среду готовой. Выполните минимум пять проверок.

Холодный запуск

Отключите сессию и заново войдите на удалённый Mac. Проверьте, что Git, Node, Ruby, CocoaPods и Xcode доступны без ручного редактирования профиля.

Повторное восстановление

Удалите только производные каталоги, но сохраните исходники и lock-файлы:

rm -rf node_modules ios/Pods
npm ci
cd ios
bundle exec pod install

Затем повторите Debug и Archive. Если результат зависит от случайно сохранённого кеша, среда ещё не воспроизводима.

Incremental-сборка

Измените небольшой файл JavaScript и повторите Debug. Затем измените нативный файл или конфигурацию и снова выполните сборку. Так обнаруживаются скрытые зависимости и скрипты, которые не запускаются при обычном изменении интерфейса.

Переподключение

Прервите SSH-сессию во время длительной команды и подключитесь снова. Команда должна либо продолжиться через устойчивый терминальный сеанс, либо корректно завершиться с сохранённым логом. Нельзя считать процесс надёжным, если единственный экземпляр лога остаётся в закрытом окне.

Повторная подпись

Проверьте, что секреты не лежат в рабочем каталоге после загрузки:

find <PROJECT_DIR> -type f \
  \( -name "*.p8" -o -name "*.p12" -o -name "*.mobileprovision" \)

Команда приведена только как проверка мест хранения. Она не заменяет аудит доступа.

Для каждой недели полезно сохранять короткий акт приёмки:

  • коммит проекта;
  • версии инструментов;
  • способ восстановления Node-зависимостей;
  • способ восстановления Pods;
  • результат Debug;
  • результат Archive;
  • результат Validate App;
  • результат загрузки;
  • время обработки App Store Connect;
  • способ удаления временных секретов;
  • команда отката к предыдущему рабочему коммиту.

Если публикации происходят только перед релизом, выбирайте среду, которая быстро выдаётся и восстанавливается из Git. Если сборки выполняются несколько раз в неделю, выбирайте постоянно доступный Mac с сохранением окружения и root-доступом. Если нужна ручная настройка Xcode, необходим графический доступ. Если основной процесс — повторяемые команды, обязательно нужен SSH. Если проект требует физического iPhone, USB или локального отладочного оборудования, удалённая схема может оказаться неудобной, и локальный Mac будет практичнее.

Для команд, которым нужен именно постоянно доступный узел, варианты аренды Mac для сборки стоит оценивать после успешного Archive, а не до него. Сначала подтверждается работоспособность проекта. Потом выбирается длительность окружения.

Частые ошибки, которые выглядят как проблема React Native

Ошибка «Module not found» после клонирования обычно означает, что зависимости не восстановлены из правильного lock-файла. Повторная установка другой версией менеджера пакетов может изменить дерево зависимостей.

Ошибка после pod install часто связана с тем, что команда была выполнена не через bundle exec. Тогда используется глобальная версия CocoaPods, а не версия проекта.

Пустая переменная NODE_BINARY проявляется как сбой скрипта Xcode. В интерактивном терминале Node найден, но Xcode запускает другую оболочку.

Archive может проходить на Debug и падать на Release, потому что Release включает другую подпись, оптимизацию, скрипты и набор Entitlements.

Загрузка может завершиться успешно, но сборка не появится сразу. App Store Connect сначала обрабатывает бинарный файл. Этот статус нельзя интерпретировать как готовность к App Review.

Когда удалённый Mac лучше, а когда нет

Для Windows или Linux удалённый Mac закрывает главный разрыв между локальной разработкой и macOS-инструментами. Он позволяет не переносить весь редактор и весь проект в удалённую сессию. Локально остаётся быстрый цикл работы с JavaScript, а Mac используется там, где он действительно необходим.

Однако у схемы есть ограничения:

  • задержка влияет на визуальную работу с Simulator;
  • физическое подключение iPhone может быть невозможно;
  • неправильная настройка доступа создаёт риск для сертификатов;
  • временный тариф неудобен для постоянной команды;
  • без сохранения окружения каждый релиз превращается в повторную установку.

Покупка собственного Mac лучше подходит тем, кто ежедневно тестирует устройство, подключает периферию, работает с локальными датчиками или годами поддерживает один тяжёлый проект. Удалённая аренда рациональнее для периодических релизов, распределённых команд и случаев, когда покупка компьютера ради одной iOS-сборки не оправдана.

Итоговый выбор стоит делать после прохождения цепочки «Debug → Archive → Validate App → обработка App Store Connect». Если текущий Windows/Linux-процесс не даёт доступа к Xcode, зависит от ручного переноса каталогов, теряет состояние после отключения и требует повторной установки инструментов, он плохо подходит для долгой поддержки iOS-проекта. В таком сценарии аренда Mac через SFTPMAC даёт более управляемую альтернативу: удалённый Mac с root-доступом, сочетанием VNC и SSH и возможностью держать среду доступной между релизами. Для временного тестирования достаточно короткого периода, а для частых сборок важнее постоянство окружения, чем минимальная цена одной сессии.