This is the official sample of the D-KMP architecture, presenting a simple master/detail app, for Android, iOS and Desktop.
(the Web version will be added at a later stage, when "Compose for Web" and "Kotlin/Wasm" become more mature)
- it uses the latest declarative UI toolkits: Compose for Android and SwiftUI for iOS
- it fully shares the ViewModel (including navigation logic and data layer) via Kotlin MultiPlatform
- coroutine scopes are cancelled/reinitialized automatically, based on the current active screens and the app lifecycle (using LifecycleObserver on Android and the SwiftUI lifecycle on iOS)
- it implements the MVI pattern and the unidirectional data flow
- it implements the CQRS pattern, by providing Command functions (via Events and Navigation) and Query functions (via StateProviders)
- it uses Kotlin's StateFlow to trigger UI layer recompositions
- the navigation state is processed in the shared code, and then exposed to the UI layer:
- on SwiftUI it seamlessly integrates with the new iOS 16 navigation patterns (NavigationStack and/or NavigationSplitView)
- on Compose it's a "remembered" data class which works on any platform (unlike Jetpack Navigation, which only works on Android)
you can find more info on these articles:
- D-KMP sample now leverages iOS 16 navigation (february 2023)
- The future of apps: Declarative UIs with Kotlin MultiPlatform (D-KMP) (november 2020)
- webservices (using Ktor Http Client)
- local db (using SqlDelight)
- local settings (using MultiplaformSettings)
- realtime db (using Firestore)
- graphQL (using Apollo GraphQL)
- device bluetooth (using Kable)
- etc...
If you want to create your own app using the D-KMP Architecture, here are the instructions you need:
- 🛠️ in the viewmodel/screens folder: create a folder for each screen of the app, containing these 3 files (as shown in the sample app structure above):
- screenEvents.kt, where the event functions for that screen are defined
- screenInit.kt, where the initialization settings for that screen are defined
- screenState.kt, where the data class of the state for that screen is defined
- 🛠️ in the NavigationSettings.kt file in the screens folder, you should define your level 1 navigation and other settings
- 🛠️ in the ScreenEnum.kt file in the screens folder, you should define the enum with all screens in your app
- ✅ the ScreenInitSettings.kt file in the screens folder doesn't need to be modified
- ✅ the 6 files in the viewmodel folder (DKMPViewModel.kt, Events.kt, Navigation.kt, ScreenIdentifier.kt, StateManager.kt, StateProviders.kt) don't need to be modified
- ✅ also DKMPViewModelForAndroid.kt in androidMain and DKMPViewModelForIos.kt in iosMain don't need to be modified
- 🛠️ in the datalayer/functions folder: create a file for each repository function to be called by the ViewModel's StateReducers
- 🛠️ in the datalayer/objects folder: create a file for each data class used by the repository functions
- 🛠️ in the datalayer/sources folder: create a folder for each datasource, where the datasource-specific functions (called by the repository functions) are defined
- ✅ the datalayer/Repository.kt file should be modified only in case you want to add an extra datasource
- ✅ the App.kt file doesn't need to be modified
- ✅ the MainActivity.kt file doesn't need to be modified
- The composables are used by both Android and Desktop apps:
- 🛠️ the Level1BottomBar.kt and Level1NavigationRail.kt files in the navigation/bars folder should be modified to custom the Navigation bars items
- ✅ the TopBar.kt file in the navigation/bars folder doesn't need to be modified
- ✅ the OnePane.kt and TwoPane.kt files in the navigation/templates folder don't need to be modified
- ✅ the HandleBackButton.kt file in the navigation folder doesn't need to be modified
- ✅ the Router.kt file in the navigation folder doesn't need to be modified
- 🛠️ in the ScreenPicker.kt file in the navigation folder, you should define the screen composables in your app
- 🛠️ in the screens folder: create a folder for each screen of the app, containing all composables for that screen
- ✅ the MainComposable.kt file doesn't need to be modified
- 🛠️ the Level1BottomBar.swift and Level1NavigationRail.swift files in the composables/navigation/bars folder should be modified to custom the Navigation bars items
- ✅ the TopBar.swift file in the composables/navigation/bars folder doesn't need to be modified
- ✅ the OnePane.swift and TwoPane.swift files in the composables/navigation/templates folder don't need to be modified
- ✅ the Router.swift file in the composables/navigation folder doesn't need to be modified
- 🛠️ in the ScreenPicker.swift file in the views/navigation folder, you should define the screen composables in your app
- 🛠️ in the views/screens folder: create a folder for each screen of the app, containing all SwiftUI views for that screen
- ✅ the App.swift file doesn't need to be modified
- ✅ the AppObservableObject.swift file doesn't need to be modified
- ✅ the main.kt file doesn't need to be modified
- The composables are used by both Android and Desktop apps:
- look at the description on the Android section above
- The best technology to implement a Web App in Kotlin will be Compose for Web backed by Kotlin/Wasm. However Kotlin/Wasm is still at a very early stage: the first version was just released in February 2023, with Kotlin 1.8.20.
- Compose For Web and Kotlin/Wasm will allow us to build Compose projects seamlessly for the Web, using the same composables we are already using for the Desktop and Android.