iOS

Enro runs on iOS through Compose Multiplatform. Installation has two pieces: a Swift call into the generated installNavigationController extension at app launch, and a Kotlin entry point that hands the Swift app a UIViewController to display.

Installation

From Swift

In your UIApplicationDelegate, call installNavigationController on your NavigationComponent once at launch. KSP generates a .shared accessor on the component object so it’s reachable from Swift:

import UIKit
import shared

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        MyComponent.shared.installNavigationController(
            application: application,
        )
        return true
    }
}

The shared accessor (and the installNavigationController extension on it) is generated by Enro’s KSP processor whenever the iOS target is present.

From Kotlin

Expose a UIViewController for your Swift app to embed. The canonical pattern uses EnroUIViewController { }, which wires up a Compose host with the navigation context Enro needs:

@Suppress("unused") // called from Swift
fun MainViewController(): UIViewController = EnroUIViewController {
    val container = rememberNavigationContainer(
        backstack = backstackOf(Home.asInstance()),
    )
    NavigationDisplay(state = container)
}

In Swift, instantiate it and use it as your root view controller — typically embedded in a UIHostingController for a SwiftUI app, or set directly as the window’s root for a UIKit app:

import UIKit
import shared

class ViewController: UIViewController {
    override func loadView() {
        let kotlinVc = MainViewControllerKt.MainViewController()
        addChild(kotlinVc)
        view = kotlinVc.view
        kotlinVc.didMove(toParent: self)
    }
}

(SwiftUI users can wrap the Kotlin view controller in UIViewControllerRepresentable — same idea.)

What Enro provides on iOS

  • A real backstack tied to the destination tree. The system back gesture on iOS calls requestClose on the active destination’s NavigationHandle.
  • Saved state for the backstack across app suspension and process death, via the platform’s standard restoration hooks.
  • The full common API: NavigationKey, NavigationKey.WithResult<T>, navigationHandle<T>(), registerForNavigationResult, NavigationDisplay, scene strategies, plugins, decorators.

Notes

  • Enro doesn’t replace UINavigationController — it owns its own backstack inside the EnroUIViewController it gives you. If you want a native navigation bar, build it in Compose (the recipes app uses Material 3’s TopAppBar everywhere) or wrap the EnroUIViewController inside a UINavigationController whose bar you drive in Swift.
  • The destination types you can use on iOS are the same Composable destinations you use everywhere else. There is no Fragment/Activity story to migrate — iOS has always been Compose Multiplatform-only.

See also


This site uses Just the Docs, a documentation theme for Jekyll.