# D-KMP-sample
**Repository Path**: AndroidTony/D-KMP-sample
## Basic Information
- **Project Name**: D-KMP-sample
- **Description**: https://gitee.com/AndroidTony/D-KMP-sample.git
- **Primary Language**: Unknown
- **License**: Apache-2.0
- **Default Branch**: main
- **Homepage**: https://juejin.cn/post/6955015172343726111
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2021-10-12
- **Last Updated**: 2021-10-12
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 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](#web-not-yet-implemented)*)
For more info on the D-KMP Architecture, please read the relevant [Medium article](https://danielebaroncelli.medium.com/the-future-of-apps-declarative-uis-with-kotlin-multiplatform-d-kmp-part-1-3-c0e1530a5343).
**Note**: in order to run the sample you should use the latest **Android Studio** [Canary build](https://developer.android.com/studio/preview).
## 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:
- **webservices** (using [Ktor Http Client](https://ktor.io/docs/client.html))
- **local db** (using [SqlDelight](https://github.com/cashapp/sqldelight))
- **local settings** (using [MultiplaformSettings](https://github.com/russhwolf/multiplatform-settings))
#### other popular KMP libraries for connecting to different data sources:
- **realtime db** (using [Firestore](https://github.com/GitLiveApp/firebase-kotlin-sdk))
- **graphQL** (using [Apollo GraphQL](https://github.com/apollographql/apollo-android))
- **device bluetooth** (using [Kable]( https://github.com/JuulLabs/kable))
- etc...
## 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
- :hammer_and_wrench: 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):
- _screen_**Events.kt**, where the event functions for that screen are defined
- _screen_**Init.kt**, where the initialization settings for that screen are defined
- _screen_**State.kt**, where the data class of the state for that screen is defined
- :hammer_and_wrench: in the **NavigationSettings.kt** file in the **screens** folder, you should define your level 1 navigation and other settings
- :hammer_and_wrench: in the **ScreenEnum.kt** file in the **screens** folder, you should define the enum with all screens in your app
- :white_check_mark: the **ScreenInitSettings.kt** file in the **screens** folder doesn't need to be modified
- :white_check_mark: 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
- :white_check_mark: also **DKMPViewModelForAndroid.kt** in _androidMain_ and **DKMPViewModelForIos.kt** in _iosMain_ don't need to be modified
#### Data Layer
- :hammer_and_wrench: in the **datalayer/functions** folder: create a file for each repository function to be called by the ViewModel's StateReducers
- :hammer_and_wrench: in the **datalayer/objects** folder: create a file for each data class used by the repository functions
- :hammer_and_wrench: in the **datalayer/sources** folder: create a folder for each datasource, where the datasource-specific functions (called by the repository functions) are defined
- :white_check_mark: the **datalayer/Repository.kt** file should be modified only in case you want to add an extra datasource
### PLATFORM-SPECIFIC CODE:
### Android
- :white_check_mark: the **App.kt** file doesn't need to be modified
- :white_check_mark: the **MainActivity.kt** file doesn't need to be modified
- **The composables are used by both Android and Desktop apps:**
- :hammer_and_wrench: the **Level1BottomBar.kt** and **Level1NavigationRail.kt** files in the **navigation/bars** folder should be modified to custom the Navigation bars items
- :white_check_mark: the **TopBar.kt** file in the **navigation/bars** folder doesn't need to be modified
- :white_check_mark: the **OnePane.kt** and **TwoPane.kt** files in the **navigation/templates** folder don't need to be modified
- :white_check_mark: the **HandleBackButton.kt** file in the **navigation** folder doesn't need to be modified
- :white_check_mark: the **Router.kt** file in the **navigation** folder doesn't need to be modified
- :hammer_and_wrench: in the **ScreenPicker.kt** file in the **navigation** folder, you should define the screen composables in your app
- :hammer_and_wrench: in the **screens** folder: create a folder for each screen of the app, containing all composables for that screen
- :white_check_mark: the **MainComposable.kt** file doesn't need to be modified
### iOS
- :hammer_and_wrench: the **Level1BottomBar.swift** and **Level1NavigationRail.swift** files in the **composables/navigation/bars** folder should be modified to custom the Navigation bars items
- :white_check_mark: the **TopBar.swift** file in the **composables/navigation/bars** folder doesn't need to be modified
- :white_check_mark: the **OnePane.swift** and **TwoPane.swift** files in the **composables/navigation/templates** folder don't need to be modified
- :white_check_mark: the **Router.swift** file in the **composables/navigation** folder doesn't need to be modified
- :hammer_and_wrench: in the **ScreenPicker.swift** file in the **views/navigation** folder, you should define the screen composables in your app
- :hammer_and_wrench: in the **views/screens** folder: create a folder for each screen of the app, containing all SwiftUI views for that screen
- :white_check_mark: the **MainView.swift** file doesn't need to be modified
- :white_check_mark: the **App.swift** file doesn't need to be modified
- :white_check_mark: the **AppObservableObject.swift** file doesn't need to be modified
### Desktop
- :white_check_mark: 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](#android) above
### 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.