Sharing view models with KMM

Aleksa Simic
July 3, 2024
8 min read

Why Kotlin Multiplatform?

Ever since I started my career as an iOS engineer, I always wanted to learn about how Android development works and maybe one day, develop an app for both platforms.

However, I have always felt that I want to master iOS development first, before learning more about any other technology.

And it was just like that, after 7 years of working heavily in the iOS ecosystem, on more than 20 different iOS applications, totally unexpected, I had a chance to dive into Android development just a little bit, thanks to the new piece of technology called Kotlin Multiplatform, or shortly, KMM.

But before having a chance to work with KMM, I had a chance to try out the other cross-platform tools like Flutter and React Native also, and see how they compare to native development, and whether are they interesting enough for me to dive in more and master them.

As for the Flutter, I went through the whole course by Angela Yu, by the way awesome course, and I would recommend it to anyone starting to learn Flutter. It was pretty fun, I am not gonna lie, made a bunch of smaller Flutter apps, and figured out how the UI building itself is pretty similar to SwiftUI and Compose. Because of that, the UI part was pretty easy for me to grasp, but I had a sense that it would take me too much time to learn Dart in-depth to write code in Flutter on a high level so that’s pretty much where my Flutter journey stopped.

As for React Native, my only experience with it was during the transition of a couple of React Native applications to Kotlin Multiplatform. First, it was a pretty difficult process for me to get the project running using all of the scripts and the expo, second, the code for those projects was written pretty badly, they were using JavaScript and not TypeScript, so overall, it just didn’t feel right to me writing that for iOS and Android apps.

Then at some point, I started reading about Kotlin Multiplatform and the main benefits of the framework, when compared to the previously mentioned cross-platform frameworks:

  1. You can share only the business logic and only the pieces of business logic you want
  2. The UI is built natively for iOS and Android, so you get the native performances on mobile devices

That was enough for me to become super interested in KMM, and then slowly to pass on the hype to the rest of my time, and fast forward 6 months after I first heard of KMM, we currently manage 3 client projects that have written by using KMM.

Big companies are adopting KMM

  1. McDonald’s
  2. Netflix
  3. 9gag

That’s the list of companies that are already adopting Kotlin Multiplatform.

You heard that right! I was pretty curious when I found out about this, and I wanted to see how our way of doing Kotlin Multiplatform compares to how these big companies are doing it.

At McDonald’s, the main motivation was reducing the total amount of the code they needed to maintain. Also, one big advantage of KMP they are talking about is having the business logic isolated and unit-tested in one place. They are taking the integration slow, and migrating piece by piece of shared functionality to KMP.

Netflix, on the other hand, has been using it in their app built from scratch Prodicle which they are making to innovate in the area of physical production of TV shows and movies. They emphasize how the communication with the database and support for the offline mode is in one place.

When it comes to 9gag, the interesting thing is that they migrated the whole app to React Native in 2016, but as it grew, they had performance issues so they switched back to native. Then in 2020 when Flutter was gaining a lot of traction, they tried using it but eventually stepped away from it because of a lack of support for ads and Firebase, at least at the time. Then, they decided to give KMP a shot and started integrating it and they suggested starting with sharing some constants, then moving to writing some common utils in KMP, and just after that writing the whole business logic in the shared module. They are using it for network calls, offline mode, sharing resources with moko-resources, and encryption decryption.

Couple of weeks ago, Google announced they are using Kotlin Multiplatform for their Google Docs iOS and Android app. It’s a big proof that they mean serious with KMP and that KMP is here to stay.

Deciding what pieces of logic to share in the KMM shared module

As I stated previously, when using Kotlin Multiplatform, you get to decide which pieces of the business logic you want to place in the shared module and share them between your iOS and Android app.

There are two approaches you can go with in terms of the shared code:

  1. Data layer - Share-only models, repositories, networking, etc.
  2. Data layer and view models - Share everything as above, just with the addition of sharing view models between iOS and Android codebase

We decided to go with the second approach because we want to take as much advantage as we can from KMM. We went through all of the available articles about the sharing view model in KMM and got started. It was way more difficult than we expected.

We spent a couple of days figuring out how to make it work and here are the challenges we faced:

  • Compatibility - you need to figure out what Kotlin and Java versions work with the latest Swift version.
  • Third-party library dependency - if you want to share your view models, KMP strongly relies on mokko-mvvm library which has compatibility issues with Swift 5.9, so you need to figure out a way to make it work. In the end, we made it work by downloading some files from the library and adding them manually to our iOS project.
  • Lack of good documentation on how to share the view model in KMP - when we came to some issues and tried to find a solution online, we were constantly getting the same three articles all over again.

But what a wonderful feeling it was in the end when we made it work. This is the complete tech stack that we are using across all three of our KMM projects right now:

  1. Kotlin Multiplatform for shared module. Things that we shared between the apps:
    1. Models
    2. ViewModels (business logic)
    3. All API and communication with the database logic
    4. Resources (images and strings)
  2. Compose for building UI in Android
  3. SwiftUI for building UI in iOS
  4. Firebase Firestore as a database

Over time, as we saw that we could successfully ship applications using KMM, we got more comfortable trying out different approaches to sharing our view models between the apps:

  • mokko-mvvm (https://github.com/icerockdev/moko-mvvm) - we had a pretty difficult time to make it work properly with SwiftUI. Eventually, we ended up creating the new view models on the iOS side which had the reference to the shared view model.
  • kmm-viewmodel (https://github.com/rickclephas/KMM-ViewModel) - came across this library in one of the comments on my previous KMP posts. I immediately saw it works much better with SwiftUI than mokko-mvvm, and we decided to give it a shot in our second KMP project. Ended up working pretty well for us, without the need for local view model wrappers 🏋️
  • Android native ViewModel - so as Google introduced the support for the Android ViewModels in the KMM, all you need now is to conform the view model you want to share to ViewModel, and you will be able to access it in your iOS codebase. No third-party library is needed anymore. How good is that? We are still at the initial stage of adopting this approach and I will let you know how it goes.

We will keep exploring and pushing boundaries side by side with KMM!

Conclusion

My advice regarding KMP for now is if you want to start quickly, go with the first approach from the above and share only the data layer.

But if your goal is to share as much code as you can in the long run, I would advise you to go with a second approach as we did. More work in the beginning, but will bring more benefits later on in the product development lifecycle. These are the main benefits we had when working with KMM:

  1. Ability to deliver pretty complex projects much faster than previously when we relied only on native iOS and Android
  2. Consistency between Android and iOS platforms because we are sharing everything other than UI, including resources and view models
  3. Keeping the performance high on both platforms because the UI is written natively

Kotlin Multiplatform is just heating up, it’s going to be huge.

Aleksa Simic
Co-Founder & CEO of Aetherius Solutions
Share this post
Trending

The most popular e-books and project templates

iOS engineers from all over the world found these e-books and project templates as the ultimate source of knowledge needed to build and scale their mobile apps

Blog

Latest blogs

Kotlin Multiplatform
Kotlin Multiplatform vs Compose Multiplatform in building production ready mobile applications
iOS
Is MV pattern in SwiftUI ready to replace MVVM?
iOS
Step by step guide for creating feature module targets in iOS apps