Как собрать и выпустить приложение Flutter под iOS без Mac
Flutter хорошо работает на Windows и Linux, пока не нужен iOS. На PC Flutter даже не показывает команду сборки под iOS. Для этого шага нужна macOS, на арендованном Mac или на CI-раннере. Мы прошли весь путь 19 октября 2026 года с Flutter 3.47.7 и Xcode 26.6.
Что работает на Windows и Linux
Код на Dart, тесты виджетов и сборки под Android работают на PC. В нашем тесте новое приложение прошло flutter test на раннерах GitHub с Windows Server 2025 и Ubuntu 24.04. Задача на Ubuntu ещё и собрала отладочный APK для Android. Hot reload в эмуляторе Android работает так же.
Потом мы попросили обе машины собрать iOS. Flutter прячет команды для iOS на любой системе, кроме macOS. Оба раннера вывели одну и ту же строку:
Could not find a subcommand named "ios" for "flutter build".
В списке целей сборки были apk, appbundle, web и десктопная цель самой машины. Ни ios, ни ipa там не было.
Что требует macOS
- flutter build ios и flutter build ipa. В руководстве Flutter по релизу сказано, что нужен Xcode и устройство с macOS.
- Нативные пакеты. С Flutter 3.44 плагины подключаются через Swift Package Manager. Для плагинов, которые его ещё не поддерживают, Flutter берёт CocoaPods. Оба работают внутри сборки Xcode.
- Симулятор iOS. Он входит в Xcode, поэтому работает только на Mac. Варианты описаны в руководстве симулятор iOS на Windows.
- Подпись и загрузка. Сертификаты и профили создаются и используются на Mac.
Установка Flutter на арендованном Mac
На Mac от MacRun уже есть Xcode 27.1 и симулятор iOS 27.1. Xcode 26.6 тоже установлен. Flutter заранее не установлен, его вы ставите сами. У вас есть права администратора и Homebrew. В нашем тесте сработала одна команда. Она поставила Flutter 3.47.7 меньше чем за минуту:
brew install --cask flutter flutter --version
В документации Flutter вместо этого используется архив. Вы распаковываете пакет для macOS в папку, например ~/develop, и добавляете эту строку в ~/.zprofile:
export PATH="$HOME/develop/flutter/bin:$PATH"
Дальше идёт настройка Xcode со страницы Flutter про iOS. Она выбирает Xcode, выполняет задачи первого запуска и показывает лицензию. Потом проверяет платформу iOS и среды симулятора:
sudo sh -c 'xcode-select -s /Applications/Xcode-27.1.app/Contents/Developer && xcodebuild -runFirstLaunch' sudo xcodebuild -license xcodebuild -downloadPlatform iOS flutter doctor -v
На Mac от MacRun Xcode 27.1 лежит в /Applications/Xcode-27.1.app и уже выбран. Xcode 26.6 лежит в /Applications/Xcode.app. На другом Mac используйте путь, который выводит ls -d /Applications/Xcode*.app. На нашем раннере flutter doctor поставил Xcode зелёную галочку и нашёл CocoaPods 1.17.0. Он отметил лицензии Android, но для iOS они не важны.
Сборка и запуск в симуляторе
Клонируйте репозиторий, выполните flutter pub get и соберите под симулятор. В нашем тесте у приложения был один плагин, shared_preferences. Папка Pods не появилась, значит Flutter использовал Swift Package Manager.
flutter build ios --simulator xcrun simctl list devices available xcrun simctl boot "iPhone Duo" xcrun simctl install booted build/ios/iphonesimulator/Runner.app xcrun simctl launch booted com.example.demo
Возьмите имя устройства из списка и свой bundle ID. На MacRun среда iOS 27.1 добавляет устройство iPhone Duo. Через демонстрацию экрана можно запустить flutter run с загруженным симулятором и пользоваться hot reload. Чтобы видеть экран Mac из Windows, следуйте руководству Xcode из Windows.
Workflow, который мы запустили на GitHub Actions
Это задача для macOS из нашего теста. Она создаёт приложение, добавляет плагин и собирает под симулятор. Потом ставит и открывает приложение, собирает релиз и архивирует его без подписи.
name: flutter-guide
on: workflow_dispatch
jobs:
macos:
runs-on: macos-26
steps:
- uses: subosito/flutter-action@v2
with:
channel: stable
cache: true
- run: xcodebuild -version && sw_vers
- run: flutter doctor -v
- run: flutter create demo
- run: flutter pub add shared_preferences
working-directory: demo
- name: Simulator build
run: time flutter build ios --simulator
working-directory: demo
- name: Install and launch in the Simulator
run: |
xcrun simctl list devices available | grep -i iphone | head -5
UDID=$(xcrun simctl list devices available -j | python3 -c "import json,sys; d=json.load(sys.stdin)['devices']; print(next(x['udid'] for k,v in d.items() if 'iOS' in k for x in v if x['name'].startswith('iPhone')))")
echo "UDID=$UDID"
xcrun simctl boot "$UDID"
xcrun simctl bootstatus "$UDID"
xcrun simctl install booted build/ios/iphonesimulator/Runner.app
xcrun simctl launch booted com.example.demo
sleep 10
xcrun simctl io booted screenshot shot.png
ls -la shot.png
working-directory: demo
- name: Release build, no signing
run: time flutter build ios --release --no-codesign
working-directory: demo
- name: Archive, no signing
run: time flutter build ipa --no-codesign
working-directory: demoВся задача заняла 5 минут 39 секунд. Эти строки взяты из её лога:
[✓] Xcode - develop for iOS and macOS (Xcode 26.6) [5.9s] ✓ Built build/ios/iphonesimulator/Runner.app com.example.demo: 14546 ✓ Built build/ios/iphoneos/Runner.app (14.6MB) ✓ Built build/ios/archive/Runner.xcarchive (170.4MB) Codesigning disabled with --no-codesign, skipping IPA.
Сборка под симулятор заняла 48 секунд. Релизная сборка заняла 1 минуту 14 секунд, архив 45 секунд. Важна последняя строка. Без подписи Flutter останавливается на архиве. Для настоящего .ipa нужна ваша команда Apple.
Отправка в TestFlight
Нужна программа Apple Developer Program, она стоит 99 USD в год. Создайте приложение в App Store Connect из любого браузера. На Mac один раз откройте ios/Runner.xcworkspace в Xcode. Выберите свою команду в разделе Signing and Capabilities. Потом соберите .ipa:
flutter build ipa --build-name 1.0.0 --build-number 2
Flutter кладёт архив в build/ios/archive, а .ipa в build/ios/ipa. Загрузите его через Transporter или этой строкой из документации Flutter с API-ключом App Store Connect:
xcrun altool --upload-app --type ios -f build/ios/ipa/*.ipa \ --apiKey your_api_key --apiIssuer your_issuer_id
Шаги с подписью мы не смогли запустить в CI, потому что у теста не было аккаунта Apple. Они взяты из руководства Flutter по релизу. Чтобы проверить на своём iPhone, поставьте сборку из TestFlight. Удалённый Mac не видит телефон, подключённый к вашему PC. Наше руководство по публикации описывает API-ключи и проверку.
Кому не стоит арендовать для этого Mac
Если нужен только .ipa, может хватить облачной сборки. В руководстве Flutter по релизу есть раздел про Codemagic. Личные аккаунты Codemagic получают 500 минут сборки на macOS в месяц бесплатно. Раннер macOS в GitHub Actions выполняет workflow выше с поминутной оплатой. Если вы выпускаете обновления каждую неделю годами, б/у Mac mini со временем может обойтись дешевле.
Арендованный Mac подходит, когда приложение нужно увидеть. Это симулятор, экраны подписи в Xcode или сбой в отладчике. Суточный доступ MacRun стоит $15 за выделенный Mac mini на M6, а неделя стоит $59. Вы платите один раз, и ничего не продлевается. В конце Mac очищается, поэтому сначала отправьте код в репозиторий и сохраните .ipa.
Частые вопросы
Может ли Flutter собрать iOS на Windows?
+
Нет. На Windows и Linux Flutter вообще не предлагает flutter build ios и flutter build ipa. В руководстве Flutter по релизу сказано, что нужно устройство с macOS. Этот шаг закрывает арендованный Mac или CI-раннер на macOS.
Можно ли запустить приложение Flutter в симуляторе iOS из Windows?
+
На самой Windows нельзя, потому что симулятор входит в Xcode. Можно собрать на удалённом Mac и смотреть его симулятор через демонстрацию экрана. Мы поставили и запустили приложение Flutter через xcrun simctl на раннере macOS.
Нужен ли Flutter по-прежнему CocoaPods для iOS?
+
Реже. С Flutter 3.44 Swift Package Manager для iOS включён по умолчанию. Для плагинов, которые его ещё не поддерживают, Flutter берёт CocoaPods. По словам Flutter, реестр CocoaPods станет доступен только для чтения 2 декабря 2026 года.
Можно ли собрать .ipa на Flutter без подписи?
+
Архив без подписи сделать можно. В нашем тесте flutter build ipa --no-codesign создал .xcarchive на 170.4 MB и сообщил, что пропускает IPA. Для настоящего .ipa в TestFlight нужна ваша команда Apple Developer.
Сколько длится сборка Flutter под iOS на Mac?
+
На раннере GitHub macos-26 сборка нового приложения с одним плагином под симулятор заняла 48 секунд. Релизная сборка без подписи заняла 1 минуту 14 секунд. Большие приложения собираются дольше.
Установлен ли Flutter на Mac от MacRun?
+
Нет. Установлены Xcode 27.1, Xcode 26.6 и симулятор iOS 27.1. У вас есть права администратора и Homebrew, а brew install --cask flutter в нашем тесте занял меньше минуты.