Read more about the 2-year reserach on our blog: Developing an Ecommerce App in Kotlin Multiplatform: A Use Case
Charts presents lines of code for each platform and common modules. It was counted using Statistic AS plugin. What is not included in measurement:
- Test and build folders - for instance iOS
Pods
. - Comments and blank lines.
Repository cloning time might be extended because of the 3D models used in the application, which are stored locally.
Open the root folder in Android Studio and a proper configuration should be detected. You should be able to run the project in a selected emulator.
If you haven't yet, install CocoaPods:
sudo gem install cocoapods
Then, inside directory "iosApp", run:
pod install
Then in XCode open the "iosApp" folder and a proper configuration should be detected. You should be able to run the project in a selected emulator.
In Android Studio in the project view right click on "androidApp" module and select Run 'All Tests'
In XCode from the app menu select Product > Test
In Android Studio in the project view, open a specific common module, open commonTest directory,
right click on a specific test file and select "Run *filename*
"
Project is composed of the following modules:
-
common - both Android and iOS apps always access common part via common module. This module is an umbrella module which aggregates all other modules, initializes a dependency graph and exposes a single factory called
Provider
. -
commonData - common data is one of so-called plugin modules. This type of module utilise a Dependency Inversion Principle by providing an implementation for some interfaces exposed by the domain module.
-
commonResources - stores all shared images, fonts, colors and strings. Those resources are exposed with Moko. Because of Moko limitations, it is currently not under common module.
-
commonDomain - domain is the brain of our application. It handles the application state and performs business logic operations on it. To provide a better scalability we divide implementation of the domain into 4 main building blocks: States, Stores, Services, and Queries.
-
buildSrc - stores Kotlin dependencies used both on Android and iOS modules.
-
androidApp - produces executable Android application
-
iosApp - produces executable iOS application
The project uses shared resources aggregated in commonResources
module.
For more information about sharing resources, head to moko-resources library.
To add a new multiplatform string head to commonResources/src/commonMain/resources/MR/base/strings.xml
To use the string in an Android composable, use dev.icerock.moko.resources.compose.stringResource
, example:
Text(text = stringResource(MR.strings.common_skip))
To use the string in SwiftUI:
LocalizedStringKey(MR.strings().common_skip.resourceId)
To add a new font head to commonResources/src/commonMain/resources/MR/fonts
New fonts should follow the existing Name-Type
naming convention.
Below you can find a full diagram which presents a high lever structure of the KMM Architecture.
It is a simple unit which has only one responsibility - keeping an application state. Store should have the simplest api possible, like getState
and setState
.
Our domain can be split into many stores. It is a good practice to make each store be responsible for only one type of data, like SettingsStore
, AuthStore
, ProductsStore
. This way we can follow a Single Responsibility Principle and improve readability of our code.
This unit is responsible for performing handling user intents and updating the state accordingly. We call it a writing business logic.
We can have multiple services responsible for different parts of our business logic. Services can use stores to read current application state and update it.
Services also have access to other units like data sources or system APIs (Navigation, Preferences etc)
Service is a one half of Unidirectional Data Flow. It handles user intentions and performs state updates based on them. Query is second half of the UDF cycle. It helps us define a reading business logic of our application.
It allows us to filter or transform the domain data to prepare it for displaying to the user. Thanks to the Query we can keep a single source of truth in the Store and transform it into multiple dervied states.
This library is available as open source under the terms of the MIT License.