Ratgeber

Die iOS-App eines Kotlin-Multiplatform-Projekts ohne Mac bauen

Bei Kotlin Multiplatform steckt der Großteil Ihrer App in gemeinsamem Kotlin-Code. Den können Sie unter Windows oder Linux schreiben. Das iOS-Framework und die Xcode-App brauchen trotzdem macOS. Wir haben das am 19. Oktober 2026 mit dem offiziellen KMP-Template von JetBrains getestet. Unten steht, was durchlief, und eine Falle.

Was unter Windows und Linux funktioniert

Laut Kotlin-Doku können Sie auf jedem System am gemeinsamen Code und an jeder Plattform außer iOS arbeiten. Das haben wir mit KMP-App-Template geprüft, dem offiziellen Template des Kotlin-Teams auf GitHub. Es ist eine Compose-Multiplatform-App für Android, iOS, Desktop und Web. Auf Runnern mit Windows und Ubuntu lief das durch:

./gradlew :shared:compileKotlinJvm :androidApp:assembleDebug

Der gemeinsame Code wurde für die JVM kompiliert, und die Android-App wurde gebaut. Tests für Android, Desktop und JVM laufen genauso. Schreiben Sie dort Ihre Geschäftslogik und Ihre Compose-UI, und prüfen Sie sie auf Android.

Die Falle: ein grüner Build ohne iOS-Framework

Dann haben wir die Runner mit Windows und Ubuntu um das iOS-Framework gebeten. Gradle kompilierte das Kotlin für iOS und übersprang dann den Link-Schritt. Trotzdem meldete es Erfolg:

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

Es kam kein Framework heraus. Die Seite von Kotlin zur Zielunterstützung erklärt den Grund. Linux und Windows können Kotlin-Bibliotheken für Apple-Ziele erzeugen. Fertige Binärdateien für Apple-Ziele lassen sich dort nicht bauen. Der Configure-Schritt warnte außerdem, dass Tests im iOS-Simulator macOS brauchen.

Was macOS braucht

  • Das Linken des Frameworks. Die iOS-App bindet Ihren gemeinsamen Code als Framework ein, und nur ein Mac kann es linken.
  • Das Projekt iosApp. Es ist ein normales Xcode-Projekt. Seine Build-Phase ruft Gradle auf, um das Framework einzubetten.
  • iOS-Tests und der Simulator. Beide brauchen Xcode.
  • CocoaPods und anderes cinterop. Laut Kotlin-Doku brauchen sie selbst für Bibliotheken einen macOS-Host.

Die Befehle auf dem Mac

Ein Mac von MacRun hat Xcode 27.1 und Xcode 26.6. Ein JDK ist nicht dabei, installieren Sie also zuerst eins. Wir haben Zulu JDK 21 genutzt. Laut Kotlin-Schnellstart sollen Sie Xcode vor dem ersten Build einmal öffnen, damit es die Einrichtung abschließt. Dann klonen Sie Ihr Repo und linken das Simulator-Framework:

./gradlew :shared:linkDebugFrameworkIosSimulatorArm64

Dann bauen Sie das Projekt iosApp für den Simulator. Diese Flags entsprechen der CI-Datei des Templates. CODE_SIGNING_ALLOWED=NO überspringt die Signierung, die ein Simulator-Build nicht braucht.

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

Behalten Sie -arch arm64. Unser erster Versuch nutzte stattdessen ein generisches Simulator-Ziel. Xcode verlangte dann von Gradle auch eine Simulator-Variante für Intel, und der Build schlug fehl:

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

Das Template definiert nur iosArm64 und iosSimulatorArm64. Auch -destination und -arch zusammen schlugen fehl. Xcode meldete, dass das Ziel die Architektur bereits festlegt.

Um die App zu öffnen, starten Sie einen Simulator und installieren den Build. Nehmen Sie Ihre eigene Bundle-ID. Bei MacRun bringt die Laufzeit für iOS 27.1 das Gerät iPhone Duo mit.

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

Sie können iosApp.xcodeproj auch über die Bildschirmfreigabe in Xcode öffnen. Setzen Sie Ihr Team und klicken Sie auf Run. Von Windows aus finden Sie unter Xcode von Windows aus alles zum entfernten Bildschirm.

Der Workflow, den wir auf GitHub Actions ausgeführt haben

Das ist der macOS-Job aus unserem Test. Er legt das Template auf einen Commit fest, also können Sie ihn so ausführen, wie er ist. In Ihrem eigenen Repo checken Sie stattdessen Ihren Code aus.

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

Der Job dauerte 6 Minuten 35 Sekunden. Das Linken mit Gradle dauerte auf einem kalten Runner 4 Minuten 7 Sekunden, vor allem wegen des Downloads der Kotlin/Native-Toolchain. Der Schritt mit xcodebuild dauerte 26 Sekunden. Diese Zeilen stammen aus dem 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

Die letzte Zeile ist die App, die im Simulator läuft. Unser Lauf nutzte Xcode 26.6, weil das Image von GitHub kein Xcode 27 hat. Auf einem Mac von MacRun stellen Sie dasselbe mit sudo xcode-select -s /Applications/Xcode.app ein, denn dort ist das Xcode 26.6.

An TestFlight ausliefern

Der Release-Build passiert im Projekt iosApp, wie bei jeder iOS-App. Setzen Sie Ihr Team in Xcode, archivieren Sie und laden Sie zu App Store Connect hoch. Unser Leitfaden zum Veröffentlichen erklärt Signierung, API-Schlüssel und die Prüfung. Diese Schritte haben wir nicht getestet, denn unser Runner hatte kein Apple-Konto. Für ein echtes iPhone installieren Sie über TestFlight. Ein Remote-Mac sieht kein Telefon, das an Ihrem PC hängt.

Wer dafür keinen Mac mieten sollte

Wenn Sie nur einen Build brauchen, der zeigt, dass iOS noch kompiliert, nutzen Sie CI. Der Workflow oben läuft auf einem macOS-Runner von GitHub Actions, minutengenau abgerechnet. Persönliche Konten bei Codemagic enthalten 500 kostenlose macOS-Build-Minuten im Monat. Wenn Sie jeden Tag an iOS arbeiten, kann ein eigener Mac über ein Jahr günstiger sein.

Mieten Sie einen Mac, wenn Sie die iOS-App sehen müssen. Also die Compose-UI auf einem echten iOS-Bildschirm, einen Absturz in Xcode oder ein Problem mit der Signierung. Ein Tagespass von MacRun kostet $15 für einen dedizierten M6 Mac mini, eine Woche kostet $59. Sie zahlen einmal, und nichts verlängert sich. Der Mac wird am Ende gelöscht, also pushen Sie Ihre Arbeit vorher nach git.

Häufige Fragen

Kann ich die iOS-App eines Kotlin-Multiplatform-Projekts unter Windows bauen?

+

Nein. Laut Kotlin-Doku lassen sich fertige Binärdateien für Apple-Ziele unter Linux und Windows nicht bauen. Gemeinsamer Code, Android und JVM-Ziele bauen dort problemlos. Das iOS-Framework und die Xcode-App brauchen einen Mac.

Warum meldet Gradle unter Windows BUILD SUCCESSFUL für iOS?

+

Gradle überspringt die Apple-Link-Aufgaben unter Linux und Windows, statt fehlzuschlagen. In unserem Test gab linkDebugFrameworkIosSimulatorArm64 SKIPPED aus, und Gradle meldete trotzdem Erfolg. Es entstand kein Framework.

Kann ich Compose-Multiplatform-UI unter Windows schreiben?

+

Ja. In unserem Test wurde der gemeinsame Code des Templates unter Windows für die JVM kompiliert, und seine Android-App wurde gebaut. Einen Mac brauchen Sie nur, um die UI auf iOS zu bauen und auszuführen.

Was hilft gegen "Xcode Requested Architecture Not Configured in Gradle"?

+

Bauen Sie für eine Architektur. Wir haben xcodebuild -sdk iphonesimulator -arch arm64 übergeben, wie es die CI des KMP-Templates selbst tut. Ein generisches Simulator-Ziel verlangte auch x86_64, das im Template nicht definiert ist.

Wie lange dauert ein iOS-Build mit Kotlin Multiplatform?

+

Auf GitHubs Runner macos-26 dauerte das Linken des Simulator-Frameworks des Templates auf einem kalten Runner etwa 4 Minuten. Der Xcode-Build von iosApp dauerte danach 26 Sekunden.

Ist auf einem Mac von MacRun ein JDK installiert?

+

Nein. Xcode 27.1, Xcode 26.6 und der Simulator für iOS 27.1 sind installiert. Sie haben Admin-Rechte und Homebrew, also installieren Sie das JDK und alles andere, was Sie brauchen.

Passende Ratgeber