https://kotlinlang.org logo
Title
j

James Black

05/03/2022, 10:14 PM
I am using and I am trying to match iOS async/await with coroutines.
Cannot pass function of type '() async -> Void' to parameter expecting synchronous function type
This is the call in iosMain:
actual suspend fun retrieveCurrentForecastByCity(city: String): MonthlyForecast? {
    return weatherRepository.retrieveCurrentForecastByCity(city)
}
This code is the action inside a button, but keeping it simple:
await outfitViewModel.currentWeather(city: city)
let a = outfitViewModel.currentWeatherFlow
I can share the repo, but it doesn't compile right now, but basically I call currentWeather, which is a 'suspend' and everything from there is suspend functions. In Android I can use runBlocking { } and and works. I am using pod 'KMPNativeCoroutinesAsync', '0.12.2' and targeting iOS 15. Missed one variable. This all works fine on the Android side and everything after this call is in my shared project.
var currentWeatherFlow = MutableSharedFlow<MainTemperature>(1)
r

Rick Clephas

05/04/2022, 5:19 AM
What line is giving this error? From your code snippets I am not sure where you are using
KMPNativeCoroutinesAsync
. P.S. you probably shouldn't be using
runBlocking
on Android. It's best to
launch
a coroutine from a (lifecycle) CoroutineScope instead.
j

James Black

05/05/2022, 1:36 AM
This shows where it is, and I am probably not using KMPNativeCoroutinesAsync yet, but it is an option. At the moment I am using runBlocking just so I could verify that my change would work.
r

Rick Clephas

05/05/2022, 5:27 AM
Alright the error you are seeing isn't really related to Kotlin. The reason you are seeing this error is because Button expects the action to be a sync closure. Since you are trying to await the current wheater the closure becomes async. To fix that you can start an async task inside the button action:
Task {
    do {
        let weather = try await outfitViewModel.currentWeather(city: city)
    } catch {
        // Handle the error
    }
}
And with KMPNativeCoroutinesAsync you can also do it like this:
Task {
    let result = await asyncResult(for: outfitViewModel.currentWeather(city: city)
    guard case let .success(weather) = result else { return }
}