KMM Writing Shareable Code

Codeangi
5 min readFeb 21, 2023

Kotlin Multiplatform Mobile is in Beta. Language features and tooling may change in future Kotlin versions.

Optional code sharing brings out many new opportunities to developers, as we get to choose precisely how much we want to share. In any typical application regardless of the platform, core data layer remains almost the same, CRUD operations in local or over the network will result in similar DTO across platforms, leveraging on this we can determine a modular approach to make such transactions as a shared library. Similarly the Utility functions and business logic itself can be written in Kotlin and can be exposed via APIs for applications to consume.

Although there is scope for more sharable components, popular choice is to play it safe and keep presentation and UI logic at the helm of platform-native code.

Where do we start?

When we create a new KMM project via Android Studio, the project will contain some basic code integrated already, this is enough to give us an idea of how KMM shared module is written.

The first thing we notice here is the different source sets {androidMain, commonMain, and iosMain}, these folders are created based on our target-platforms, defined in build.gradle.kts file of the shared module/KMM Library. If we target more than just iOS and Android corresponding source-sets will be created for each of the targets.

Respective source-sets will contain platform-specific implementation and or “actual”(Platform.kt file) members for each of the “expect” members declared in the commonMain source-set**(Platform.kt file)**.

How to Configure Sourcesets in KMM?

In order to generate source-sets we need to add respective targets in build.gradle.kts file of the shared module/KMM Library, here we see android and iOS targets defined, there is also support for different architecture offered by iOS such as X64, ARM, etc.. developers can optionally choose what architecture is supported (based on Kotlin/Native compatibility). Android and iOS templates are automatically added by Android Studio when we create a KMM project.

Each of the targets will have a corresponding sourceSet associated with it here we can define library/module dependency on each of the sourceSets, optionally developers can even have TestSourceSets for maintaining Unit tests for functions in each of the sourceSets.

here iosX64Main, iosArm64Main, and iosSimulatorArm64Main are combined into iosMain sourceSet as they share similar dependencies in this scope.

How to share logic between platforms in KMM?

commonMain sourceSet contains all the shared implementations, common for all the target platforms. Here we write APIs/functions and expose them for consumption by the target application. When we create a KMM project in android studio, the template will contain an example implementation of a shared method:

As we can see in the above example, greeting() method returns a string composition, which has a value obtained from Platform().platform ;

What are expect & actual in KMM?

Class Platform Which is declared as an “expect” class inside the commonMain Platform.kt class, an expect keyword illustrates respective declaration will have an “actualimplementation in all the target sourceSets, this helps us to connect Platform-specific code to the common code.

expect & actual” are required when we intend to use any system/platform specific functionality such as httpClient, database drivers. “expect & actual” methodology also helps to connect exclusive implementation of Kotlin/Native, Kotlin/JVM, Kotlin/JS into common use-cases.

as we can see in the above example, class Platform’s actual implementation is required for both androidMain and iosMain sourceSets as we have an expect declaration in commonMain sourceSet.

Using KMM library as a platform-native library:

Shared functionality can be exposed for consumption via public properties via classes inside the commonMain sourceSet. Generated code is basically a library, now we have option to use the generated KMM library as a regular platform-native library on to the target application. Following are the some of popular way of publishing as platform-native library.

Android:- Publishing KMM library to Maven Repo

Maven is a popular distribution channel for android, in order to publish our library using Maven repo, we need to add maven-publish plugin to build.gradle.kts file of the shared module/KMM Library.

Once added and gradle sync is successful, we can click on gradle options from the Android Studio to choose whether to publish to a local maven repo or a remote one.

How to use the published KMM library Android?

Once published to a Maven repository, we can add a dependency in build.gradle file of the target android application, and consume exposed functionality wherever necessary.

iOS- Publishing KMM library as a Swift package

One of the popular distribution methods for iOS is to export the library as a swift package and import into application project from GitHub.

Popular way for exporting KMM library into a swift package involves a plugin https://github.com/ge-org/multiplatform-swiftpackage through which we can create a swift package. once we add the plugin, we can configure and customize some of the swift package data such as name, version and output directory etc..

Once multiplatform-swift package is added and configured, synchronise the project and using gradle options from Android Studio, we can create a Swift package which will be generated inside pre-defined output directory. Once swift package is generated, we can upload into any distribution channels like github and in Xcode we can import the package via URL.

How to Use it in iOS?

One Package dependency is added in Xcode, we can import the said library on to our swift file and use exposed functionality.

If you found it helpful, these are the related articles:
1. Getting the settings right: setting up for KMM
2. Networking in KMM
3. KMM: Whats on the plate

--

--