More and more people are coding with Kotlin. According to recent MongoDB research, Kotlin is the second-fastest-growing language when it comes to GitHub projects and discussions on Stack Overflow.
It's easy to understand why. Kotlin is pragmatic, modern, and statically-typed. It's winning the hearts of not just Android developers, but backend developers and, increasingly, Java developers too.
Matthew Bartos is X-Team's Kotlin guru. He's been handling Kotlin projects on both the backend and mobile side. In this article, he explores Kotlin's ambition to conquer more platforms.
You may think of Kotlin as a Java-like JVM language, but JVM is only one of its available targets. Kotlin can be compiled/transpiled to JavaScript (and work with React) and to native platform code with Kotlin/Native. This means that Kotlin to iOS, MacOS, Linux, Windows, or even WebAssembly is possible.
Kotlin/Native lets you create an executable, a static or dynamic library with C headers, or an Apple framework. It can also use existing C, Swift, or Objective-C libraries.
In this article, I will create an Android + iOS multiplatform project. But you don't have to stop there, because you can do all of the following with Kotlin:
No, this is not just another Flutter. I understand that developers have mixed opinions about multiplatform mobile frameworks. While sharing code between platforms is generally considered as time-saving and convenient, a shared UI is only considered a good choice for early-stage projects where designs don't need to be pixel-perfect.
Multiplatform Kotlin is probably the closest-to-native app development approach.
In previous articles, I've written about my experience with Multi-OS Engine. It's a similar concept to Kotlin Multiplatform, but it uses a bundled ART VM for translating JVM code to native iOS code. This means that even a simple iOS app is very heavy. But with Kotlin/Native, you get light, native LLVM iOS bytecode.
Multiplatform Kotlin lets you share the logic between the platforms, not the UI.
The typical Kotlin Multiplatform Mobile (KMM) project consists of 3 modules:
Kotlin Multiplatform Mobile is a set of tools that make it easier to create Android + iOS multiplatform apps. Just keep in mind that KMM is in alpha development and still somewhat unstable. When you install the official KMM plugin and create a new project, it'll automatically set up these modules:
androidMain
commonMain
commonTest
iosMain
Following the MVP pattern, the app should have three layers of code:
You want to keep your Model and Presenter in the shared common
module and implement Views in both Android and iOS, where you want them to stay as small as possible.
You cannot use Android's ViewModel
or LiveData
in the shared common
module, because it's written in Java. You also cannot use RxJava nor Retrofit. This module needs to contain pure Kotlin code, which complicates things a little bit.
But Kotlin Multiplatform has a solution for that in the form of two new keywords: expect
and actual
, which can easily be understood as declaration
and implementation
.
In your shared common
module, you can declare classes and functions marked with expect
. Then you need to properly implement them in both your androidMain
and iosMain
modules. For example:
common
expect val uiDispatcher: CoroutineContext
androidMain
actual val uiDispatcher: CoroutineContext
get() = Dispatchers.Main
iosMain
actual val uiDispatcher: CoroutineContext
get() = IosMainDispatcher
IosMainDispatcher
is your custom class, which uses: dispatch_async(dispatch_get_main_queue())
By extracting your logic to the shared common
module, you're now able to write blazing-fast unit tests that can cover a lot of successful and unsuccessful use cases. Use mocked API responses and create scenarios that will cover both platforms at the same time!
Kotlin Multiplatform holds a lot of promise, but it's still in its early days.
Pros (+)
Cons (-)
common
moduleAny #Kotlin fans here? What do you like about it?
— X-Team (@xteam) September 24, 2020