Skip to content

D-KMP Architecture official sample: it uses a shared KMP ViewModel and Navigation for Compose and SwiftUI apps.

License

Notifications You must be signed in to change notification settings

dbaroncelli/D-KMP-sample

Repository files navigation

D-KMP architecture - official sample

This is the official sample of the D-KMP architecture, where "D" stands for Declarative UI and "KMP" stands for Kotlin MultiPlatform. It presents a simple master/detail app, for Android, iOS and Desktop.
The business logic is fully shared (and written in Kotlin). The UI is platform-specific: Compose for Android and Desktop, SwiftUI for iOS.

UPDATE MAY 2025:
Please notice that the D-KMP architecture was conceived in 2020, when nobody expected that Compose would have become a first-class UI toolkit also for iOS.
Since May 2025, Compose MultiPlatform is stable and production-ready for Android, iOS and Desktop, so sharing both the business logic and the UI using Compose MultiPlatform (CMP) has become the preferred KMP solution.
All information about writing apps with Compose MultiPlatform can be found on the official CMP website by JetBrains.
This repository about the D-KMP architecture will be kept online, but it won't be updated anymore.

Key features of the D-KMP architecture:

  • 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:

Data sources used by this sample:

these are other data sources, not used by this sample, for which popular KMP libraries exist:

Instructions to write your own D-KMP app:

If you want to create your own app using the D-KMP Architecture, here are the instructions you need:

SHARED CODE:

View Model

  • 🛠️ 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

Data Layer

  • 🛠️ 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



PLATFORM-SPECIFIC CODE:

Android

Schermata 2021-06-26 alle 16 54 32

Schermata 2021-06-26 alle 17 03 13

  • ✅ 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

iOS

ios-files

  • 🛠️ 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

Desktop

Schermata 2021-06-26 alle 16 54 15

Schermata 2021-06-26 alle 17 03 13

  • ✅ the main.kt file doesn't need to be modified
  • The composables are used by both Android and Desktop apps: