iOS Story

The iOS Story: Compose Multiplatform Without Xcode Here

Kotlin/Native links iOS binaries with Apple's toolchain, so the iOS target needs a Mac with Xcode 10 . What follows comes from JetBrains' documentation and template and was not run here. The shared module packages its iOS targets as a framework:

shared/build.gradle.kts: the iOS targets (not run here)Groovy
kotlin {
    listOf(iosArm64(), iosSimulatorArm64()).forEach { target ->
        target.binaries.framework {
            baseName = "Shared"                     // import Shared in Swift
            isStatic = true
        }
    }
}

An Xcode build phase runs ./gradlew :shared:embedAndSignAppleFrameworkForXcode to compile the Kotlin for the architecture Xcode is building. To share the UI as well, the template keeps an App() composable in commonMain, iosMain wraps it in a UIViewController, and SwiftUI hosts that:

iosMain/MainViewController.kt: Compose inside UIKit (not run here)Kotlin
fun MainViewController() = ComposeUIViewController { App() }
iosApp/ContentView.swift: the SwiftUI side (not run here)Kotlin
struct ComposeView: UIViewControllerRepresentable {
    func makeUIViewController(context: Context) -> UIViewController {
        MainViewControllerKt.MainViewController()
    }
    func updateUIViewController(_ controller: UIViewController, context: Context) {}
}

Top-level Kotlin functions reach Swift as members of a class named after the file, hence MainViewControllerKt. Compose 234 on iOS draws with Skia 351,502 into a Metal view, not with UIKit controls, though scrolling, text input and accessibility follow iOS conventions. suspend functions and Flows arrive as completion handlers, which the open-source SKIE (https://github.com/touchlab/SKIE 1,329 ) and KMP-NativeCoroutines 1,327 (https://github.com/rickclephas/KMP-NativeCoroutines 1,327 ) libraries turn into Swift async functions and AsyncSequences.