D-KMP architecture – official sample

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” becomes more mature)

For more info on the D-KMP Architecture, please read the relevant Medium article.

Note: in order to run the sample you should use the latest Android Studio Canary build.

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

Data sources used by this sample:

other popular KMP libraries for connecting to different data sources:

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

Schermata 2021-06-26 alle 16 53 55

  • 🛠️ 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 MainView.swift file doesn’t need to be modified
  • ✅ 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:

Web (not yet implemented)

  • Compose for Web is still at a very early stage. We’ll give it a bit more time to mature before publishing an app. The web version of SqlDelight (the most popular local database for Kotlin MultiPlatform) is also at a very early stage, as currently the database cannot even be saved persistently. It might take until the end of 2021 before it makes sense to work to a proper Compose for Web app.

GitHub

https://github.com/dbaroncelli/D-KMP-sample