Kotlin Multiplatform: ready, steady, …

Yev Kanivets
May 4, 2020 · 5 min read

There are dozens of cross-platform technologies, which promise you "write-once run-anywhere" experience out of the box without any considerable drawbacks. But in the end, we all know it's not 100% true.

Image for post
Image for post

To be honest, there are only a few viable solutions for cross-platform application development when it comes to the mobile world: React Native, Flutter and Kotlin Multiplatform.

The latter is the youngest player in the field, but the most promising one. It's super-flexible, concentrates on sharing business-logic, ensures native UI/UX, and enables native development experience.

In this article, I want to share our migration journey of native iOS and Android apps to Kotlin Multiplatform. I'll emphasize both, pros and cons, of chosen technology + some workarounds for bugs we've faced in the process.

Briefing

Codeforces WatchR is an open-source mobile client for Codeforces platform, where thousands of programmers compete in weekly algorithmic challenges. There are both, iOS and Android apps, which are available in stores.

Image for post
Image for post

Codeforces API is far from being mobile-first, so a lot of business-logic happens directly on devices, which includes, but not limited to — caching server data, merging data sets, extra-features not supported by the server.

This is the perfect use case for Kotlin Multiplatform, which allows sharing business-logic in the form of a library (Android) or framework (iOS) compiled to binaries, flawlessly executed by native platforms.

Migration has been done in multiple steps:

Starting

We are huge fans of Redux pattern, which perfectly works with Kotlin Multiplatform. But unfortunately, the library we are used to (ReKotlin) hasn't been yet ported to KMP (you can't just use Android libs in KMP project).

So along with the basic setup of modules and Gradle scripts, we were forced to copy/paste official ReKotlin code, which is thankfully 100% Kotlin without any dependency on Android-specific stuff. Publishing your own KMP library is a tedious task, so it was decided to go with the simplest solution.

I won't describe project setup in details, because there are already many great starter projects and articles on the topic. For example, KaMPKit from Touchlab or kotlin-multiplatform-template from Guillermo Orellana.

Speeding up

As mentioned previously, it's not possible to use Android libraries in KMP module out of the box, but there are already many alternatives, which have covered about 100% of our needs.

Some of the core libraries are developed and supported by JetBrains, other ones — by the community. The full list of what's available up to date can be found here: https://github.com/AAkira/Kotlin-Multiplatform-Libraries.

KMP database library SQLDelight is probably one of the best solutions, which I worked with on Android. It allows you to write almost pure SQL code, which then used to generate 100% Kotlin class wrappers.

Example of SQLDelight-specific file

In our case, 100% of database code is written in a common module and shared between iOS / Android. Using Kotlin libraries in Swift has many caveats, so I would recommend to hide them behind your custom interfaces.

Ktor is a nice alternative to Retrofit even though it's quite different and you need to get used to it. But again, if you hide 3rd parties behind your custom interfaces (repository in this case), changing the networking library is an easy task.

Breakthrough

Once the database and network levels were migrated to KMP, we had a chance to move the business-logic. With Redux all your business-logic should be located in Action or Request (for async code) classes.

Not that easy! We actually needed to move all Redux to common module (store, state, middleware, etc.), not just actions. There we had some code relying on Android-specific classes, which took us a few days to decouple.

That's it! We've moved all we wanted to KMP module. It's time to bind shared code to iOS project: copy/paste it as sub-folder of Android app, configure Kotlin XCode Sync and CocoaPods Gradle plugins, import it in Swift. Voilà.

Defeat?!

"Nothing works" was the first phrase I've heard from our iOS dev, which tried to reuse the common KMP module. I've checked and nothing really worked!

Image for post
Image for post

But why? What's a problem? Can we fix it?

There were a few problems actually, which we were able to fix in 2 days:

  • Kotlin/Native initialises global variables in alphabetical order, which is quite painful with Redux where you have store, middleware and reducers declared as global variables. As a workaround we needed to add z to package name of store to make sure it's initialised in the last turn.

But at the end, it was rather the victory with a great benefit of consistency between our previously inconsistent apps.

Finish line

Image for post
Image for post
Android's UI is written in XML, iOS's — in Swift -> code sharing is well above 30%

Kotlin Multiplatform is a young, but very promising technology, which can bring many advantages for your development team. But you need to make sure that you have enough time and knowledge to tackle challenges.

Android dev experience won't be changed a lot. iOS devs will need some time to adapt, learn some Kotlin programming and dig deeper into how Kotlin -> ObjC -> Swift conversion works :)

xorum.io

Engaging #EdTech solutions for Mobile (iOS | Android | KMP) and Web (Kotlin | Ktor)

Yev Kanivets

Written by

Professional Mobile Engineer since 2014, passionated by #EdTech, learning and teaching. Competitive programming enthusiast. Marathon Finisher.

xorum.io

xorum.io

Engaging #EdTech solutions for Mobile (iOS | Android | Kotlin Multiplatform) and Web (Kotlin | Ktor | Vue.js)

Yev Kanivets

Written by

Professional Mobile Engineer since 2014, passionated by #EdTech, learning and teaching. Competitive programming enthusiast. Marathon Finisher.

xorum.io

xorum.io

Engaging #EdTech solutions for Mobile (iOS | Android | Kotlin Multiplatform) and Web (Kotlin | Ktor | Vue.js)

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store