robercoding
08/13/2024, 5:06 PMrobercoding
08/13/2024, 5:06 PMViewModel
from the ObservableViewModel
. I have a function that sets a value into DataStore
lib from KMM, letās call it foo
function
import com.rickclephas.kmp.nativecoroutines.NativeCoroutinesState
import com.rickclephas.kmp.observableviewmodel.ViewModel
import com.rickclephas.kmp.observableviewmodel.launch
import com.rickclephas.kmp.observableviewmodel.stateIn
...
open class MyViewModel(useCase: UseCase): ViewModel() {
private val isProcessing: MutableStateFlow<Boolean> = MutableStateFlow(false)
@NativeCoroutinesState
val value: StateFlow<FooState<String>> = combine(isProcessing, useCase.valueFlow) { isProcessing, value ->
if(isProcessing) {
return@combine FooState.Processing
}
if(value != null) FooState.Success else FooState.Empty
}.stateIn(viewModelScope, started = SharingStarted.Lazily, initialValue = FooState.Loading)
fun foo(value: String) {
viewModelScope.launch {
isProcessing.emit(true)
useCase.setValue(value)
isProcessing.emit(false)
}
}
}
When calling the viewModel.foo(value)
from iOS. It should show a progress view due to FooState.Processing
but itās not shown due to the non-responsive UI.
This works if I delay the execution of the function useCase.setValue(value)
.
Do you know if Iām doing a beginner mistake here with the iOS thread?
Iāve tried setting <http://Dispatchers.IO|Dispatchers.IO>
to the viewModelScope.launch(<http://Dispatchers.IO|Dispatchers.IO>) { .. }
but not workingrobercoding
08/13/2024, 5:10 PMRick Clephas
08/13/2024, 5:29 PMUseCase
class looks.
Most likely the setValue
call is too fast.robercoding
08/13/2024, 5:37 PMclass UseCaseImpl constructor(private val preference: LocalePreference): UseCase {
override val locale: Flow<LocaleItem?> = preference.getStringDataFlow(PREFERENCE_APP_LOCALE, null).map {
it?.toLocaleItem()
}
override suspend fun setValue(value: String) {
preference.setStringData(PREFERENCE_APP_LOCALE, value)
}
}
class LocalePreference(DataStore<Preference>) {
fun getStringDataFlow(preferenceKey: String, ifNotAvailable: String?): Flow<String?> = developmentDataStore.data.map { preferences ->
preferences[stringPreferencesKey(preferenceKey)] ?: ifNotAvailable
}
}
robercoding
08/13/2024, 5:39 PMMost likely theSo itās nothing related to the thread? Or what would be the root issue whencall is too fast.setValue
setValue
is called too fast?robercoding
08/13/2024, 5:40 PMisProcessing
state, itād still take a moment for the UI to respond.
Iāve set processing state due to how long it took to respond the UI and then realized the UI is frozen.robercoding
08/13/2024, 5:41 PMfun foo(value: String) {
viewModelScope.launch {
useCase.setValue(value)
}
}
robercoding
08/13/2024, 5:43 PM.onChange(of: viewModel.appLanguage) {
let result: PreferenceState<LocaleItem> = viewModel.appLanguage
let isEmpty = PreferenceState.isEmpty(result)
let isSuccess = PreferenceState.isSuccess(result)
let isProcessing = PreferenceState.isProcessing(result)
withAnimation(.easeInOut) {
if isSuccess() {
let locale = (result as! PreferenceStateSuccess<LocaleItem>).data
self.locale = Locale(identifier: "\(locale!.language)-\(locale!.country)")
showMainView = true
showOverlay = false
} else if isEmpty() {
showLanguageView = true
showMainView = false
showOverlay = false
} else if isProcessing() {
// showOverlay.toggle()
} else {
showOverlay = false
}
}
}
PS: Not the most beautiful code for sure, still learning swift with KMMRick Clephas
08/13/2024, 5:43 PMrobercoding
08/13/2024, 5:44 PMSo if setValue is resource intensive it would block the main thread. Unless itās suspendingIn this case, itās suspending or am I missing something here? š¤
robercoding
08/13/2024, 5:47 PMrobercoding
08/13/2024, 5:47 PMRick Clephas
08/13/2024, 5:48 PMrobercoding
08/13/2024, 5:50 PMAmir Hammad
08/13/2024, 9:01 PMrobercoding
08/14/2024, 6:24 AM@StateViewModel
is set as mentioned in the documentation
@StateViewModel var viewModel = HomeComponent().localeViewModel
robercoding
08/14/2024, 6:51 AMUseCase
and still happening. It must be something with the flows or Swift UIrobercoding
08/15/2024, 3:12 PMwithAnimation
on showOverlay
which for some reason froze the app. Removing withAnimation
for showOverlay
works nicely š
Not sure if this is a patch or is it is expected to not animate the blur and progress view but anyhow this solution helps me to forget about it and I can continue learning Swift UI and iOS ecosystem šrobercoding
08/15/2024, 3:12 PMrobercoding
08/16/2024, 8:41 PMRick Clephas
08/17/2024, 11:54 AM