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
requestCloseon the active destination’sNavigationHandle. - 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 theEnroUIViewControllerit gives you. If you want a native navigation bar, build it in Compose (the recipes app uses Material 3’sTopAppBareverywhere) or wrap theEnroUIViewControllerinside aUINavigationControllerwhose 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
- Installation for the multi-platform setup.
- Recipes iOS entrypoint — the working
MainViewController()Enro uses for its own runnable iOS recipes.