Compilare e pubblicare un’app Flutter per iOS senza Mac
Flutter gira bene su Windows e Linux, finché non ti serve iOS. Su un PC, Flutter non offre nemmeno il comando di build per iOS. Per quel passaggio ti serve macOS, su un Mac a noleggio o su un runner di CI. Abbiamo provato tutto il percorso il 19 ottobre 2026, con Flutter 3.47.7 e Xcode 26.6.
Cosa funziona su Windows e Linux
Il tuo codice Dart, i widget test e le build Android funzionano tutti su un PC. Nel nostro test, un’app nuova ha passato flutter test sui runner Windows Server 2025 e Ubuntu 24.04 di GitHub. Il job Ubuntu ha anche compilato un APK Android di debug. L’hot reload su un emulatore Android funziona allo stesso modo.
Poi abbiamo chiesto a entrambe le macchine una build iOS. Flutter nasconde i comandi iOS su qualsiasi sistema che non sia macOS. Entrambi i runner hanno stampato la stessa riga:
Could not find a subcommand named "ios" for "flutter build".
La sua lista di target di build offriva apk, appbundle, web e il target desktop del sistema. Non c’erano né ios né ipa.
Cosa richiede macOS
- flutter build ios e flutter build ipa. La guida di Flutter alla release dice che Xcode è necessario, e che devi usare un dispositivo con macOS.
- Pacchetti nativi. Da Flutter 3.44, i plugin arrivano tramite Swift Package Manager. Flutter ripiega su CocoaPods per i plugin che non lo supportano ancora. Entrambi girano dentro la build di Xcode.
- Il simulatore iOS. È incluso in Xcode, quindi gira solo su un Mac. Vedi il simulatore iOS su Windows per le opzioni.
- Firma e upload. Certificati e profili si creano e si usano sul Mac.
Installare Flutter su un Mac a noleggio
Un Mac MacRun arriva con Xcode 27.1 e il simulatore iOS 27.1. È installato anche Xcode 26.6. Flutter non è preinstallato, quindi lo aggiungi tu. Hai i permessi di amministratore e Homebrew. Questo solo comando ha funzionato nel nostro test e ha installato Flutter 3.47.7 in meno di un minuto:
brew install --cask flutter flutter --version
La documentazione di Flutter usa invece un download. Decomprimi il pacchetto per macOS in una cartella come ~/develop, poi aggiungi questa riga a ~/.zprofile:
export PATH="$HOME/develop/flutter/bin:$PATH"
Poi viene il setup di Xcode dalla pagina iOS di Flutter. Seleziona Xcode, esegue le operazioni del primo avvio e mostra la licenza. Poi controlla la piattaforma iOS e i runtime del simulatore:
sudo sh -c 'xcode-select -s /Applications/Xcode-27.1.app/Contents/Developer && xcodebuild -runFirstLaunch' sudo xcodebuild -license xcodebuild -downloadPlatform iOS flutter doctor -v
Su un Mac MacRun, Xcode 27.1 si trova in /Applications/Xcode-27.1.app ed è già selezionato. Xcode 26.6 si trova in /Applications/Xcode.app. Su un altro Mac, usa il percorso che stampa ls -d /Applications/Xcode*.app. Sul nostro runner, flutter doctor ha dato a Xcode la spunta verde e ha trovato CocoaPods 1.17.0. Ha segnalato le licenze Android, che per iOS non contano.
Compilare ed eseguire nel simulatore
Clona il tuo repository, esegui flutter pub get e compila per il simulatore. Nel nostro test l’app aveva un plugin, shared_preferences. Non è comparsa nessuna cartella Pods, quindi Flutter ha usato 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
Usa un nome di dispositivo dalla lista e il tuo bundle ID. Su MacRun, il runtime iOS 27.1 porta il dispositivo iPhone Duo. Con la condivisione schermo puoi anche usare flutter run con un simulatore avviato, per l’hot reload. Da Windows, segui Xcode da Windows per vedere lo schermo del Mac.
Il workflow che abbiamo eseguito su GitHub Actions
Questo è il job macOS del nostro test. Crea un’app, aggiunge un plugin e compila per il simulatore. Poi installa e apre l’app, e compila e archivia una release senza firma.
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: demoL’intero job è durato 5 minuti e 39 secondi. Queste righe vengono dal suo log:
[✓] 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.
La build per il simulatore ha richiesto 48 secondi. La build release ha richiesto 1 minuto e 14 secondi, e l’archivio 45 secondi. L’ultima riga è importante. Senza firma, Flutter si ferma all’archivio. Un vero .ipa richiede il tuo team Apple.
Pubblicare su TestFlight
Ti serve l’Apple Developer Program, che costa 99 USD all’anno. Crea l’app in App Store Connect da qualsiasi browser. Sul Mac, apri una volta ios/Runner.xcworkspace in Xcode. Scegli il tuo team in Signing and Capabilities. Poi compila il .ipa:
flutter build ipa --build-name 1.0.0 --build-number 2
Flutter scrive l’archivio in build/ios/archive e il .ipa in build/ios/ipa. Caricalo con Transporter, oppure con questa riga della documentazione di Flutter e una chiave API di App Store Connect:
xcrun altool --upload-app --type ios -f build/ios/ipa/*.ipa \ --apiKey your_api_key --apiIssuer your_issuer_id
Non abbiamo potuto eseguire i passaggi firmati in CI, perché il nostro test non aveva un account Apple. Vengono dalla guida di Flutter alla release. Per provare sul tuo iPhone, installa la build da TestFlight. Un Mac remoto non vede un telefono collegato al tuo PC. La nostra guida alla pubblicazione copre chiavi API e revisione.
Chi non dovrebbe noleggiare un Mac per questo
Se ti serve solo un .ipa, può bastare una build in cloud. La guida di Flutter alla release ha una sezione su Codemagic. Gli account personali di Codemagic includono 500 minuti di build macOS gratis al mese. Un runner macOS di GitHub Actions esegue il workflow qui sopra, con fatturazione al minuto. Se pubblichi ogni settimana per anni, un Mac mini usato può costare meno nel tempo.
Un Mac a noleggio conviene quando devi vedere l’app. Cioè il simulatore, le schermate di firma di Xcode o un crash nel debugger. Un pass giornaliero MacRun costa $15 per un Mac mini M6 dedicato, e una settimana costa $59. Paghi una volta sola e nulla si rinnova. Alla fine il Mac viene cancellato, quindi prima fai push del codice e salva il tuo .ipa.
Domande frequenti
Flutter può compilare per iOS su Windows?
+
No. Su Windows e Linux, Flutter non offre affatto flutter build ios o flutter build ipa. La guida di Flutter alla release dice che devi usare un dispositivo con macOS. Un Mac a noleggio o un runner di CI macOS copre quel passaggio.
Posso eseguire la mia app Flutter nel simulatore iOS da Windows?
+
Non su Windows stesso, perché il simulatore è incluso in Xcode. Puoi compilare su un Mac remoto e vedere il suo simulatore con la condivisione schermo. Abbiamo installato e avviato un’app Flutter con xcrun simctl su un runner macOS.
Flutter ha ancora bisogno di CocoaPods per iOS?
+
Meno spesso. Da Flutter 3.44, Swift Package Manager è attivo di default per iOS. Flutter ripiega su CocoaPods per i plugin che non lo supportano ancora. Flutter dice che il registro di CocoaPods diventa di sola lettura il 2 dicembre 2026.
Posso compilare un .ipa Flutter senza firma?
+
Puoi archiviare senza firma. Nel nostro test, flutter build ipa --no-codesign ha creato un .xcarchive da 170.4 MB e poi ha detto che saltava l’IPA. Un vero .ipa per TestFlight richiede il tuo team Apple Developer.
Quanto dura una build iOS di Flutter su un Mac?
+
Sul runner macos-26 di GitHub, una build per il simulatore di un’app nuova con un plugin ha richiesto 48 secondi. Una build release senza firma ha richiesto 1 minuto e 14 secondi. Le app più grandi richiedono di più.
Flutter è installato su un Mac MacRun?
+
No. Sono installati Xcode 27.1, Xcode 26.6 e il simulatore iOS 27.1. Hai i permessi di amministratore e Homebrew, e brew install --cask flutter ha richiesto meno di un minuto nel nostro test.