Djuro
06/15/2023, 2:09 PMkmm-viewmodel
and launching a coroutine within
private val mutableStateFlow: MutableStateFlow<String> = MutableStateFlow(viewModelScope,"")
val stateFlow = mutableStateFlow.asStateFlow()
viewModelScope.coroutineScope.launch {
delay(1000)
mutableStateFlow.value = "new state"
}
In iosApp I do @StateViewModel *var* viewModel = KMMViewModel()
and pass stateFlow
to appropriate either swiftUI/compose multiplatform UI element
Changes of this state are never reflected in the UI. Did someone experience a similar issue?Rick Clephas
06/15/2023, 2:11 PMmutableLoginUiStateFlow
?Djuro
06/15/2023, 2:19 PMRick Clephas
06/15/2023, 2:22 PMDjuro
06/15/2023, 2:23 PMviewModel.coroutineScope
Djuro
06/15/2023, 2:23 PMRick Clephas
06/15/2023, 2:29 PMDjuro
06/15/2023, 2:44 PMshared -> common -> QrScanViewModel
open class QrScanViewModel : KMMViewModel(), KoinComponent {
private val _scannedCode = MutableStateFlow(viewModelScope, "Initial value")
@NativeCoroutinesState
val scannedCode = _scannedCode.asStateFlow()
fun updateScannedCode(result: String) {
_scannedCode.value = result
}
fun flowTest() {
updateScannedCode("Here it does update UI.")
viewModelScope.coroutineScope.launch {
flow {
delay(1000)
emit("one")
delay(1000)
emit("two")
delay(1000)
emit("three")
}.collectLatest {
Logger.i { "Here it does not update UI :/ $it" }
updateScannedCode(it)
}
}
}
}
iosApp -> QrScanViewModel
import Foundation
import shared
extension QrScanView {
@MainActor class QrScanViewModel : shared.QrScanViewModel {
@Published var isPresentingScanner = false
override init() {
super.init()
self.testFlow()
}
func testFlow(){
super.flowTest()
}
}
}
iosApp -> QrScanView
struct QrScanView : View {
@StateObject var viewModel = QrScanViewModel()
var body : some View{
VStack(spacing: 10){
Text(viewModel.scannedCode)
}
}
}
Rick Clephas
06/15/2023, 3:58 PM@StateObject
. It should be @StateViewModel
. Once you change that the code works as expected.
Note: “Here it does update UI.” wasn’t actually a state change. It runs synchronously when the viewmodel is created. Which basically makes it the initial value.Djuro
06/16/2023, 7:39 AM@StateObject
instead of @StateViewModel
• I used compose multiplatform that led to these issues:
◦ I passed viewModel.testFlow directly to the compose function and it didn’t perform recomposition
▪︎ Reason: well, of course viewmodel.testFlow
is not a compose state
▪︎ Solution: added wrapper compose function having only viewModel parameter in shared.common
. Then collect viewModel.testFlow.collectAsState
inside that wrapper and passed it to another compose function.