Guida

Compilare l’app iOS di un progetto Kotlin Multiplatform senza Mac

Con Kotlin Multiplatform, quasi tutta la tua app sta nel codice Kotlin condiviso. Puoi scriverlo su Windows o Linux. Il framework iOS e l’app Xcode richiedono comunque macOS. L’abbiamo testato il 19 ottobre 2026, con il template KMP ufficiale di JetBrains. Qui sotto trovi cosa è passato, e una trappola.

Cosa funziona su Windows e Linux

La documentazione di Kotlin dice che puoi lavorare sul codice condiviso e su ogni piattaforma tranne iOS da qualsiasi sistema. L’abbiamo verificato con KMP-App-Template, il template ufficiale del team Kotlin su GitHub. È un’app Compose Multiplatform per Android, iOS, desktop e web. Sui runner Windows e Ubuntu, questo è passato:

./gradlew :shared:compileKotlinJvm :androidApp:assembleDebug

Il codice condiviso è stato compilato per la JVM, e l’app Android è stata compilata. Puoi eseguire allo stesso modo i test Android, desktop e JVM. Scrivi lì la logica e la UI Compose, e verificala su Android.

La trappola: una build verde senza framework iOS

Poi abbiamo chiesto il framework iOS ai runner Windows e Ubuntu. Gradle ha compilato il Kotlin per iOS, poi ha saltato il passaggio di link. Ha comunque segnalato un successo:

> Task :shared:compileKotlinIosSimulatorArm64
> Task :shared:linkDebugFrameworkIosSimulatorArm64 SKIPPED
BUILD SUCCESSFUL in 27s

Non è uscito nessun framework. La pagina di Kotlin sui target supportati spiega perché. Linux e Windows possono creare librerie Kotlin per i target Apple. I binari finali per i target Apple non si possono compilare lì. Anche il passaggio di configurazione avvisava che i test sul simulatore iOS richiedono macOS.

Cosa richiede macOS

  • Il link del framework. L’app iOS importa il tuo codice condiviso come framework, e solo un Mac può linkarlo.
  • Il progetto iosApp. È un normale progetto Xcode. La sua fase di build chiama Gradle per incorporare il framework.
  • I test iOS e il simulatore. Entrambi richiedono Xcode.
  • CocoaPods e altri cinterop. La documentazione di Kotlin dice che richiedono un host macOS anche per le librerie.

I comandi sul Mac

Un Mac MacRun arriva con Xcode 27.1 e Xcode 26.6. Non ha un JDK, quindi installane uno prima. Noi abbiamo usato Zulu JDK 21. Il quickstart di Kotlin dice di aprire Xcode una volta prima della prima build, così può completare il setup. Poi clona il tuo repository e linka il framework per il simulatore:

./gradlew :shared:linkDebugFrameworkIosSimulatorArm64

Poi compila il progetto iosApp per il simulatore. Questi flag sono gli stessi del file di CI del template. CODE_SIGNING_ALLOWED=NO salta la firma, che a una build per il simulatore non serve.

cd iosApp
xcodebuild -project iosApp.xcodeproj -scheme iosApp \
  -configuration Debug -sdk iphonesimulator -arch arm64 \
  -derivedDataPath build CODE_SIGNING_ALLOWED=NO build

Tieni -arch arm64. Il nostro primo tentativo usava invece una destinazione generica del simulatore. Xcode ha chiesto a Gradle anche una slice per il simulatore Intel, e la build è fallita:

Xcode requested target architectures that are not configured in your Gradle build: ios_x64.

Il template definisce solo iosArm64 e iosSimulatorArm64. Anche usare insieme -destination e -arch è fallito. Xcode ha detto che la destinazione implica già l’architettura.

Per aprire l’app, avvia un simulatore e installa la build. Usa il tuo bundle ID. Su MacRun, il runtime iOS 27.1 porta il dispositivo iPhone Duo.

xcrun simctl list devices available
xcrun simctl boot "iPhone Duo"
xcrun simctl install booted "build/Build/Products/Debug-iphonesimulator/KMP App.app"
xcrun simctl launch booted com.jetbrains.kmpapp.KMP-App-Template

Puoi anche aprire iosApp.xcodeproj in Xcode con la condivisione schermo. Imposta il tuo team, poi premi Run. Da Windows, vedi Xcode da Windows per lo schermo remoto.

Il workflow che abbiamo eseguito su GitHub Actions

Questo è il job macOS del nostro test. Fissa il template a un commit, quindi puoi eseguirlo così com’è. Nel tuo repository, fai invece il checkout del tuo codice.

name: kmp-ios
on: workflow_dispatch
env:
  TEMPLATE_SHA: 6b6d09e4f3f5e845116422d59b658791ed6149c6
jobs:
  macos:
    runs-on: macos-26
    steps:
      - uses: actions/checkout@v4
        with:
          repository: Kotlin/KMP-App-Template
          ref: ${{ env.TEMPLATE_SHA }}
      - uses: actions/setup-java@v4
        with:
          distribution: zulu
          java-version: 21
      - run: xcodebuild -version && sw_vers && java -version
      - name: Link the iOS simulator framework
        run: time ./gradlew :shared:linkDebugFrameworkIosSimulatorArm64
      - name: Build the iosApp for the Simulator
        run: |
          time xcodebuild -project iosApp.xcodeproj -scheme iosApp \
            -configuration Debug -sdk iphonesimulator -arch arm64 \
            -derivedDataPath build CODE_SIGNING_ALLOWED=NO build
        working-directory: iosApp
      - name: Install and launch in the Simulator
        run: |
          APP=$(ls -d build/Build/Products/Debug-iphonesimulator/*.app | head -1)
          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')))")
          xcrun simctl boot "$UDID"
          xcrun simctl bootstatus "$UDID"
          xcrun simctl install booted "$APP"
          xcrun simctl launch booted com.jetbrains.kmpapp.KMP-App-Template
          sleep 10
          xcrun simctl io booted screenshot shot.png && ls -la shot.png
        working-directory: iosApp

Il job è durato 6 minuti e 35 secondi. Il link di Gradle ha richiesto 4 minuti e 7 secondi su un runner a freddo, soprattutto per scaricare la toolchain Kotlin/Native. Il passaggio xcodebuild ha richiesto 26 secondi. Queste righe vengono dal log:

Xcode 26.6
Build version 17F113
openjdk version "21.0.12" 2026-07-21 LTS
BUILD SUCCESSFUL in 4m 4s
263M	shared/build/bin/iosSimulatorArm64/debugFramework/Shared.framework
** BUILD SUCCEEDED **
 59M	build/Build/Products/Debug-iphonesimulator/KMP App.app
com.jetbrains.kmpapp.KMP-App-Template: 26325

L’ultima riga è l’app in esecuzione nel simulatore. Il nostro test ha usato Xcode 26.6, perché l’immagine di GitHub non ha Xcode 27. Su un Mac MacRun puoi fare lo stesso con sudo xcode-select -s /Applications/Xcode.app, che lì è Xcode 26.6.

Pubblicare su TestFlight

La build di release avviene nel progetto iosApp, come per qualsiasi app iOS. Imposta il tuo team in Xcode, archivia e carica su App Store Connect. La nostra guida alla pubblicazione copre firma, chiavi API e revisione. Non abbiamo testato questi passaggi, perché il nostro runner non aveva un account Apple. Per un iPhone vero, installa da TestFlight. Un Mac remoto non vede un telefono collegato al tuo PC.

Chi non dovrebbe noleggiare un Mac per questo

Se ti serve solo una build per dimostrare che iOS compila ancora, usa la CI. Il workflow qui sopra gira su un runner macOS di GitHub Actions, con fatturazione al minuto. Gli account personali di Codemagic includono 500 minuti di build macOS gratis al mese. Se lavori su iOS ogni giorno, un Mac tuo può costare meno nell’arco di un anno.

Noleggia un Mac quando devi vedere l’app iOS. Cioè la UI Compose su un vero schermo iOS, un crash in Xcode o un problema di firma. 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 tuo lavoro su git.

Domande frequenti

Posso compilare l’app iOS di un progetto Kotlin Multiplatform su Windows?

+

No. La documentazione di Kotlin dice che i binari finali per i target Apple non si possono compilare su Linux o Windows. Codice condiviso, Android e target JVM lì si compilano senza problemi. Il framework iOS e l’app Xcode richiedono un Mac.

Perché Gradle dice BUILD SUCCESSFUL per iOS su Windows?

+

Su Linux e Windows Gradle salta i task di link Apple invece di fallire. Nel nostro test, linkDebugFrameworkIosSimulatorArm64 ha stampato SKIPPED, e Gradle ha comunque segnalato un successo. Non è stato prodotto nessun framework.

Posso scrivere UI Compose Multiplatform su Windows?

+

Sì. Nel nostro test, il codice condiviso del template è stato compilato per la JVM e la sua app Android è stata compilata su Windows. Ti serve un Mac solo per compilare ed eseguire la UI su iOS.

Come si risolve "Xcode Requested Architecture Not Configured in Gradle"?

+

Compila per una sola architettura. Abbiamo passato -sdk iphonesimulator -arch arm64 a xcodebuild, come fa la CI del template KMP. Una destinazione generica del simulatore chiedeva anche x86_64, che il template non definisce.

Quanto dura una build iOS di Kotlin Multiplatform?

+

Sul runner macos-26 di GitHub, il link del framework per il simulatore del template ha richiesto circa 4 minuti su un runner a freddo. La build Xcode di iosApp ha poi richiesto 26 secondi.

Su un Mac MacRun è installato un JDK?

+

No. Sono installati Xcode 27.1, Xcode 26.6 e il simulatore iOS 27.1. Hai i permessi di amministratore e Homebrew, quindi installi tu il JDK e tutto quello che ti serve.

Guide correlate