https://kotlinlang.org logo
#multiplatform
Title
# multiplatform
k

Kyle

10/02/2023, 3:30 PM
in my viewModel I have
Copy code
val mileageLog: StateFlow<List<MileageLogEntry>?> = _mileageLog.asStateFlow()
and in swiftUI I’m trying to display all of the items,
Copy code
List {
  ForEach(viewModel.mileageLog!, id: \.self) { entry in
     MileageLogListItem(viewModel: viewModel, entry: entry, showEntryEditor: $showEntryEditor)
  }
}
but when I emit a new list I get
[SwiftUI] Publishing changes from background threads is not allowed; make sure to publish values from the main thread (via operators like receive(on:)) on model updates.
. What’s the appropriate way to get the List to refresh in swift code?
r

Rick Clephas

10/02/2023, 3:42 PM
What does your Kotlin code that updates the
mileageLog
look like? Also what logic are you using to propagate the state changes to Swift?
k

Kyle

10/02/2023, 3:45 PM
Copy code
_mileageLog.emit(/* new list */)
and I’m using rickclephas’ KMM-ViewModel library with a viewmodel in kotlin and it being referenced in swift with
@StateViewModel *var* mileageLogViewModel: MileageLogViewModel = InjectApplicationComponent().mileageLogViewModel
pretty sure. Still experimenting with some possible fixes now. Also, I just realized that you are Rick. Thank you for creating some very useful libraries
😁 1
r

Rick Clephas

10/02/2023, 4:19 PM
🙂. If the error persists please open an issue with a reproduction sample and I will take a look at it 👍🏻
k

Kyle

10/02/2023, 4:24 PM
ok, figured out the first part of the issue. I got the “publishing changes from background threads is not allowed” problem to go away by wrapping the emit call in
Copy code
viewModelScope.coroutineScope.launch
The list still isn’t updating though so still have to figure that out
r

Rick Clephas

10/02/2023, 4:41 PM
Ah I missed that one. In that case since it’s already in a suspend function could just wrap it in a
withContext(Dispatchers.Main) {}
call. Which will make sure to run the emit on the main thread, while still waiting for the emit call to complete before returning from
deleteMileageLogEntry
. On the Swift side just make sure to use one of the
@XViewModel
property wrappers (e.g.
@ObservedViewModel
) on the
viewModel
property. That should be enough to propagate the changes to SwiftUI.
k

Kyle

10/02/2023, 5:00 PM
adding @StateViewModel back to the viewmodel fixed that. I was trying @Binding, then read something that said don’t do that, but didn’t think about adding the other annotation back. The important thing, it works! Thank you for the info
👍🏻 1