Android Development iOS

Kotlin Multiplatform

July 14, 2022
Kotlin Multiplatform

A few weeks ago I was try­ing my best to inves­ti­gate the plau­si­bil­i­ty of what Kotlin Mul­ti­plat­form Mobile could be. We’ve heard the promis­es of write once every­where” before but they have always been lim­it­ed in flex­i­bil­i­ty and in my opin­ion, nev­er actu­al­ly felt” native in the end. We’ve had expe­ri­ence work­ing with Xam­arin, React Native, and Flut­ter and I’m sure any­one involved with those projects would be a strong advo­cate for con­tin­u­ing to work in any of those frame­works going for­ward. Per­haps that comes down to the spe­cif­ic imple­men­ta­tions, but to get fea­tures unique to plat­forms you end up writ­ing a bunch of plat­form spe­cif­ic code any­way. At the end of the day you are find­ing your­self say­ing… if only I had done this native, this would be so much easier.”

Yet, the more I’ve heard about KMM the more I’ve been excit­ed about the pos­si­bil­i­ty. Large­ly because of what it is not try­ing to do. It’s not try­ing to recre­ate how the view sys­tem works on either plat­form, it’s not try­ing to turn your web­site in a sin­gle web-view, it’s focus­ing itself on the busi­ness log­ic for your app and because of this, I think this has the poten­tial to become a very a pow­er­ful tool.

So, I start­ed play­ing around with a very sim­ple idea. Basi­cal­ly the sim­plest app I could think of. What if I could pull down my cur­rent weath­er fore­cast from the inter­net. Seemed easy enough, but I quick­ly learned that some of the depen­den­cies I’m used to were not going to work in the KMM. No mat­ter. There are already a decent num­ber of libraries avail­able writ­ten specif­i­cal­ly to be com­pat­i­ble with KMM. So I was on my way, and pulling down data and dis­play­ing it came togeth­er pret­ty quick­ly. But where we quick­ly launched into prob­lems was with ViewModels.

Gray Areas #

What can be con­sid­ered busi­ness log­ic” and what is con­sid­ered state” or view state” can be pret­ty sub­jec­tive. After read­ing a bunch of dif­fer­ent blogs, I thought it would be neat to have an event based sys­tem that each plat­form would be able to observe and change the state appro­pri­ate­ly. This quick­ly became annoy­ing hav­ing to use spe­cial libraries to con­vert things like LiveData and ViewModel into a plat­form agnos­tic ver­sions of them­selves, and although it was do-able con­stant­ly felt like I was shoot­ing myself in the foot. The more I thought about how to han­dle this by mov­ing log­ic far­ther up, the less it felt like it made sense to have in my shared code. I ulti­mate­ly start­ed think­ing that the best thing to have shared would be my data lay­er. Pack­ag­ing up all of my API com­mu­ni­ca­tion and mod­els into a sin­gle pack­age they could both use is appeal­ing, but I then learned the down­side of coroutines in iOS.

Asyn­chro­nous Annoy­ance #

Up until this point, I felt like every­thing could be rel­a­tive­ly han­dleable by due dili­gence of a team, work­ing togeth­er and defin­ing lines on what to share and what not to share. But work­ing with suspend fun in iOS proved to be the fea­ture that made me start to ques­tion how help­ful any of this actu­al­ly was.

One of the basic things I wrote ini­tial­ly was a func­tion to pull down the weather.

suspend fun getWeatherForecast(): Forecast {
    return api.getWeatherForecast()
} 

Pret­ty sim­ple. Call­ing this in Android was as sim­ple as cre­at­ing a scope to launch it in.

viewModelScope.launch {
    repository.getWeatherForecast()
}

How­ev­er, when it is cross­ing over into Swift you lose all of the under­stand­ing of what a corou­tine is. You are left with some­thing like

repository.getWeatherForecast { data, error in
    if let forecast = data {
        // do something with the forecast
    }
    if let actualError = error {
        // do something with the error
    }
}

Although, I don’t love writ­ing that every-time, writ­ing a thin wrap­per around all of the API func­tions to make it look nicer or to con­vert into async/await wouldn’t be the end of the world. But, as far as I can tell, you had no real way of inform­ing the corou­tine to stop run­ning. This may not be a game chang­er, but does seem like it could result in some inter­est­ing issues down the line. 

Ulti­mate­ly, I’m not ful­ly out on KMM, though I will say that the use case where it would be suc­cess­ful is prob­a­bly lim­it­ed, at least as a first attempt. Hope­ful­ly with time, we can look back at it again and see what improve­ments have been made. A future where I am only writ­ing busi­ness log­ic tests once is a good one.

Click here if you’d like to look at my sam­ple project.

Scott Schmitz
Scott Schmitz
Software Developer

Stay in the loop with our latest content!

Select the topics you’re interested to receive our new relevant content in your inbox. Don’t worry, we won’t spam you.

Michigan Software Labs Named One of the Country's Best Small and Medium Workplaces by Fortune copy
Press Release

Michigan Software Labs Named One of the Country's Best Small and Medium Workplaces by Fortune copy

October 16, 2020

Michigan Software Labs has been named as one of the 100 Best Small and Medium Workplaces based on an independent survey by consulting firm Great Place to Work® and Fortune Magazine. Michigan Software Labs came in 64 on the list.

Read more
Being Intentional, Flexible and People-Focused in 2021
Team

Being Intentional, Flexible and People-Focused in 2021

October 19, 2020

MichiganLabs co-founder and managing partner, Joshua Hulst, sat down with Chelsea Dubey (Guest Writer) to share his insights for a strong start to the new year and the exciting technology trends that his team is tracking for 2021.

Read more
Using View Model Protocols to manage complex SwiftUI Views
iOS

Using View Model Protocols to manage complex SwiftUI Views

March 11, 2021

Managing complex screens or views that depend on asynchronous services or the need to pull in state from across your app can be tricky to get right. The most common way to address this in SwiftUI is by abstracting that logic into a dedicated view model for that piece of UI.

Read more
View more articles