Navigation is processed in the shared-code, but binds to the iOS NavigationStack path
The D-KMP sample was first released in early 2021, following the D-KMP architecture concept, where both ViewModel and DataLayer are written as Kotlin Multiplatform shared-code, and the UI layer is implemented using Declarative UI frameworks (Compose and SwiftUI).
One of the main features of the D-KMP sample is the navigation being defined in the shared-code, with the support for multiple vertical backstacks, which work out of the box on any platform (the vertical backstack can be enabled/disabled for a specific root screen, with a simple flag).
D-KMP Navigation on SwiftUI
Until now, advanced navigation on iOS has been problematic, because SwiftUI had very inflexible navigation patterns, requiring hacks to achieve any customization.
The latest D-KMP sample is now leveraging the new iOS 16 navigation patterns, which fixed several navigation issues and made the code a lot cleaner.
The UI states are remembered by placing all NavigationStacks under a ZStack, where only the active one is visible (opacity=1). The caching of the data states is instead managed in the shared-code.
D-KMP Navigation on Compose
The D-KMP sample runs Compose Multiplatform. For this reason, it’s not using Jetpack Navigation, which only works on Android’s Jetpack Compose, but a navigation implementation that works on any platform.
The navigation pattern is pretty simple. The “Router” composable “remembers” the navigation state, whose value comes from the shared-code, similarly to how it happens for iOS.
Each navigation function changes the navigation state, triggering a recomposition of the UI layer, which then presents the new destination screen.
The UI state of the screens in the multiple vertical backstacks are remembered using the “rememberSaveableStateHolder()” Compose function. As for iOS, the caching of the data states is managed in the shared-code.
The full D-KMP sample is available on GitHub: