Руководство

Как собрать приложение React Native под iOS без Mac

Большая часть работы с React Native отлично идёт на Windows или Linux. Сборка под iOS нет. CocoaPods и xcodebuild требуют macOS, поэтому на этот один шаг вы берёте Mac взаймы. Ниже workflow GitHub Actions, который это делает. Мы запустили его 2 октября 2026 года, и он собрал React Native 0.87.1 в Xcode 26.6.

Что работает на Windows и Linux

Ваш код на JavaScript и TypeScript, Metro и Jest работают на любом компьютере. В нашем тесте свежесозданное приложение прошло свой тест Jest на раннере ubuntu-24.04 от GitHub и на его раннере windows-2025. Оба использовали Node 22. Android-приложение тоже можно собрать и запустить на любой из этих систем. Документация React Native описывает настройку Android для Windows и для Linux.

Про iOS та же документация говорит прямо. На страницах настройки для Windows и Linux сказано, что для сборки проектов с нативным кодом под iOS нужен Mac. Вместо этого там предлагают Expo Go. Он запускает ваш JavaScript на настоящем iPhone во время разработки. Это покрывает экраны и логику. Но приложение, которое можно выпустить, так не получить.

Что требует macOS

  • pod install. Проект iOS подтягивает React Native и его нативные зависимости через CocoaPods. На этом же шаге работает Codegen.
  • xcodebuild. Xcode и iOS SDK существуют только для macOS. На странице системных требований Xcode Apple указывает для Xcode 26.6 macOS Tahoe 26.2 или новее.
  • Симулятор. Он входит в Xcode, так что тоже работает только на Mac.
  • Подпись и загрузка. Эта часть описана в статье о публикации приложения iOS без Mac.

Workflow, который мы запустили

Он создаёт новое приложение командой с reactnative.dev. Он прогоняет тесты на Linux и Windows. Затем собирает iOS на раннере macos-26. Флаги init взяты из документации React Native CLI. Они выбирают npm, пропускают вопрос про pods и не настраивают git. Положите файл в .github/workflows/rn-ios.yml и запустите его на вкладке Actions.

name: rn-ios
on: workflow_dispatch
jobs:
  test-linux:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/setup-node@v7
        with:
          node-version: 22
      - run: npx @react-native-community/cli@latest init RNDemo --pm npm --install-pods false --skip-git-init true
      - run: npm test
        working-directory: RNDemo
  test-windows:
    runs-on: windows-latest
    steps:
      - uses: actions/setup-node@v7
        with:
          node-version: 22
      - run: npx @react-native-community/cli@latest init RNDemo --pm npm --install-pods false --skip-git-init true
      - run: npm test
        working-directory: RNDemo
  build-ios:
    runs-on: macos-26
    steps:
      - uses: actions/setup-node@v7
        with:
          node-version: 22
      - run: sudo xcode-select -s /Applications/Xcode_26.6.app
      - run: xcodebuild -version && node -v && ruby -v
      - run: npx @react-native-community/cli@latest init RNDemo --pm npm --install-pods false --skip-git-init true
      - run: node -p "require('react-native/package.json').version"
        working-directory: RNDemo
      - run: bundle install
        working-directory: RNDemo/ios
      - run: bundle exec pod install
        working-directory: RNDemo/ios
      - name: Build for the iOS Simulator (Debug)
        run: |
          xcodebuild -workspace RNDemo.xcworkspace -scheme RNDemo \
            -configuration Debug -sdk iphonesimulator \
            -destination 'generic/platform=iOS Simulator' \
            -derivedDataPath build build
        working-directory: RNDemo/ios
      - name: Build for the iOS Simulator (Release, JS bundled)
        run: |
          xcodebuild -workspace RNDemo.xcworkspace -scheme RNDemo \
            -configuration Release -sdk iphonesimulator \
            -destination 'generic/platform=iOS Simulator' \
            -derivedDataPath build build
        working-directory: RNDemo/ios
      - run: ls -la build/Build/Products/Release-iphonesimulator/RNDemo.app/main.jsbundle && du -sh build/Build/Products/*-iphonesimulator/RNDemo.app
        working-directory: RNDemo/ios

В своём репозитории замените шаг init на checkout вашего кода и установку его пакетов. Остальное не меняется. Замените RNDemo на имя своего workspace и схемы.

Что вывел запуск

Эти строки скопированы из журнала задачи build-ios. Вся задача на macOS заняла 2 минуты 42 секунды.

Xcode 26.6
Build version 17F113
v22.23.2
0.87.1
Pod install took 43 [s] to run
Pod installation complete! There are 87 dependencies from the Podfile and 86 total pods installed.
** BUILD SUCCEEDED **
Welcome to Metro v0.87.1
** BUILD SUCCEEDED **
-rw-r--r--  1 runner  staff  1268567 Oct  2 04:02 build/Build/Products/Release-iphonesimulator/RNDemo.app/main.jsbundle
154M	build/Build/Products/Debug-iphonesimulator/RNDemo.app
 38M	build/Build/Products/Release-iphonesimulator/RNDemo.app

Сборка Debug заняла около 39 секунд, сборка Release около 35. Это быстро, потому что React Native 0.87 скачивает предсобранное ядро. Журнал pod install прямо об этом пишет. Старые версии компилируют гораздо больше нативного кода, так что там сборки будут дольше.

Зачем собирать дважды? Приложение Debug загружает JavaScript из Metro во время работы. Сборка Release упаковывает JavaScript в приложение как main.jsbundle, здесь это 1.27 MB. Если сборка Release прошла, значит, компилируются и ваш бандл, и ваш нативный код.

Запуск на каждый pull request

Workflow выше запускается вручную. Чтобы ловить поломки iOS до слияния, измените строку триггера, чтобы он запускался и на pull request:

on:
  pull_request:
  workflow_dispatch:

Когда сборка падает, журнал получается длинным. У нас он превысил 18 000 строк для двух маленьких сборок. Ищите в журнале "error:" и читайте первое совпадение. Последующие ошибки часто лишь следствие первой. Если падает pod install, сначала посмотрите на Podfile и на нативные зависимости.

Сколько это стоит

GitHub округляет время каждой задачи вверх до минуты. Наша задача на macOS вышла на 3 минуты. По ставке $0.062 за минуту из справочника цен на раннеры GitHub в октябре 2026 года это около 19 центов. Публичные репозитории ничего не платят за стандартные раннеры. Если сборок несколько в неделю, это самый дешёвый способ собрать iOS.

На Expo есть и другой путь. EAS Build собирает iOS в облаке Expo. Бесплатный план включает 15 сборок iOS в месяц в очереди с низким приоритетом. Дальше сборка iOS среднего размера стоит $2, по данным expo.dev/pricing в октябре 2026 года.

Где CI уже не хватает

Задача CI доказывает, что приложение компилируется. Показать вам приложение она не может. Сборка для симулятора запускается только в симуляторе iOS, а ему нужен экран Mac. Когда нативный модуль ломается только на iOS, нужен открытый Xcode. Нужны точки останова и симулятор, по которому можно кликать. Об этом читайте в статье о работе в Xcode из Windows через удалённый Mac.

К тому же hosted раннер каждый раз стартует пустым. Каждый запуск заново скачивает пакеты Node, gems и pods. В нашем запуске к задаче на macOS было приложено ещё и уведомление GitHub. В нём говорилось, что задачи на macOS arm64 могут дольше ждать в очереди из-за нехватки мощностей.

Кому не стоит арендовать для этого Mac

Если вы собираете проект несколько раз в неделю, оставайтесь на hosted раннерах или EAS. Выделенный Mac окупается примерно при 2,242 минутах macOS в месяц по базовой ставке GitHub. Ещё он окупается, когда вам нужен экран. Если ни то, ни другое не про вас, арендованный Mac это лишние траты.

Если вы всё же перешли эту границу, тот же workflow работает на self-hosted раннере macOS. Измените runs-on и укажите xcode-select на ваш Xcode. Pods и derived data остаются прогретыми между запусками. Тарифы на M6 смотрите на странице цен.

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

Можно ли собрать приложение React Native под iOS на Windows?

+

Писать и тестировать его на Windows можно, но для сборки под iOS нужна macOS. В документации React Native сказано, что для сборки проектов с нативным кодом под iOS нужен Mac. Этот шаг закрывает облачный Mac или CI-раннер.

Можно ли запустить симулятор iOS на Windows?

+

Нет. Симулятор входит в Xcode, а Xcode работает только на macOS. Симулятор удалённого Mac можно смотреть через удалённый рабочий стол. Или во время разработки используйте Expo Go на настоящем iPhone.

Сколько длится сборка React Native под iOS в GitHub Actions?

+

В нашем запуске в октябре 2026 года новое приложение на React Native 0.87.1 собиралось 2 минуты 42 секунды за всю задачу на macOS. Сюда вошли pod install и две сборки для симулятора, Debug и Release. Большие приложения собираются дольше.

Нужен ли аккаунт Apple Developer для сборки под симулятор?

+

Нет. Наш workflow собрал приложение для симулятора без всякой подписи. Платная программа Apple Developer Program нужна, чтобы подписать приложение для устройства, TestFlight или App Store.

Похожие руководства