rickclephas / KMP-ObservableViewModel

Library to use AndroidX/Kotlin ViewModels with SwiftUI
MIT License
569 stars 29 forks source link

KMM viewModelScope.coroutineScope.launch body never called #55

Closed nathanfallet closed 8 months ago

nathanfallet commented 8 months ago

Hi! I just switch to KMM ViewModel to make multiplatform viewmodels, and I encountered this weird issue:

On Android, to dispatch network requests I normally use:

viewModelScope.launch {
  println("Hello")
}

So it's logical to replace it by this using KMM ViewModel:

viewModelScope.coroutineScope.launch {
  println("Hello")
}

But the body of the launch call is never executed... (I first had real network requests but added prints and understood that they were not called with KMM implementation) I found a workaround using GlobalScope.launch which works, but might cause lifecycle issues, so I would prefer to get a working viewModelScope.coroutineScope.launch.

I looked at the native implementation of Android coroutineScope and the difference I see is that on KMM ViewModel we have:

CoroutineScope(SupervisorJob() + Dispatchers.Main)

While on AndroidX it's implemented this way:

CloseableCoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)

So this might be a place to look for a fix. Anyone else is encountering this issue?

rickclephas commented 8 months ago

Hi. Could you possibly share a reproducer for this? On Android viewModelScope.coroutineScope is the CoroutineScope from the AndroidX ViewModels viewModelScope.

nathanfallet commented 8 months ago

I don't know if it's my IDE but looks like it resolves to the otherMain instead of androidMain when I navigate through the source. I'm also going to make a minimal reproducible example. image

EDIT: I'm making a producible example, but everything works fine, and I see that the resolved implementation is the correct one image

nathanfallet commented 8 months ago

I finally found the problem (I need to find why it happens). This was related to my dependency injection:

//val viewModel = koinViewModel<AuthViewModel>() // This does not work. Why?
val viewModel = AuthViewModel() // This works. Why?