Kotlin Multiplatform enables you to maintain a single code base for your business logic across mobile platforms (Android and iOS). This is very interesting because there are not many tools out there that helps to unify business logic across platforms.
What did we build?
We built a simple Expense Tracker Application using KMM, Jetpack Compose, and SwiftUI. The KMM module stores the expenses in a local database and exposes an interface for the iOS and Android apps. Here are some of our findings:
Interoperability issues between Objective-C, Swift and Kotlin
As the Kotlin compiler creates an iOS framework with Objective-C bindings for the underlying Kotlin code it causes several problems. For example, Kotlin enum are translated to an Objective-C object with the cases added as properties.

For the enum above values()
returns a KotlinArray<Category>
, which does not conform to Sequence
. This can be fixed by converting the KotlinArray
to List
on the Kotlin side using this approach.
enum class Category {
GROCERY,
UTILITY,
RENT,
TRANSPORTATION,
DINE_OUT,
ENTERTAINMENT;
companion object {
fun getAsList(): List<Category> {
return values().toList()
}
}
}
We can use an extension on KotlinArray but we cannot use generics in that extension as KotlinArray
uses some lightweight generics in Objective-C which cannot be used with Swift. So we wrote an helper class that converts KotlinArray
to Array<AnyObject>
using Generics:
import shared
import Foundation
class KotlinArrayHelper<T> where T: AnyObject {
static func convert(_ kotlinArray: KotlinArray<T>) -> [T] {
let size = kotlinArray.size
var swiftArray: [T] = []
for i in 0 ..< size {
if let item = kotlinArray.get(index: i) {
swiftArray.append(item)
}
}
return swiftArray
}
}
Redundant Protocol Conformance for SwiftUI
When using SwiftUI, we had to add redundant protocol conformance to Expense so that we can use it to bind to a List.
import shared
extension Expense: Identifiable {}
Library Dead-code Elimination
We used kotlinx-datetime and explored if we could make an Instance
object from epoch milliseconds. We could not create an Instance object from epoch milliseconds on the iOS side as the tooling had stripped the required constructor function. The recommended solution is to export the library, but this might increase the compilation time and the binary size. Learn more about this here.
Limited Coroutine support in iOS
Working with coroutines from Swift is tricky as out of the box suspend
functions do not have cancellation support, and Flow only has collect
function. To solve this we used KMP-NativeCoroutines that converts Kotlin Coroutine to swift equivalents i.e. async-await or Combine.
Like all cross-platform frameworks, KMM has its pros and cons.
It took a significant amount of time and effort to set up initially. When compared to other cross-platform mobile frameworks, community support is not very substantial, and there are no established guidelines for project architecture or design. However, with a collaborative and cross-functional team, we were able to share much of the business logic using proper abstractions.
KMM’s performance is comparable to that of a native app, and the development experience for Android developers is similar to that of developing a native Android app, though it may be unfamiliar to iOS developers at first.
Conclusion
As a relatively new framework, the tooling, community, and best practices around KMM are not yet well-developed. Nonetheless, as more developers and companies adopt KMM, these areas are expected to improve.
KMM can be a good fit if the mobile development team is cross-functional and exposed to Android and iOS. Also, expertise in Android is required as the tooling and the ecosystem is very similar to native Android development. Many companies like Careem, Netflix, Square, etc. are using KMM in production, but we recommend that teams should build a small application in KMM before committing to the framework.
Special thanks to @kalpeshp03 who worked on this project with me.
References
- Netflix Tech
- Careem
- Kotlin Multiplatform Mobile Case Studies
- Create a Kotlin/Multiplatform library with Swift
- What We Learned Using KMM For iOS
Hi! I’m Ibrahim, an ex-operations executive turned innovative iOS developer. Currently, I’m creating cutting-edge experiences @TarkaLabs and love to geek out on the latest tech stacks.