Hello, I'm using <@U01EMBJSZHA>'s library for view...
# multiplatform
a
Hello, I'm using @Rick Clephas's library for view models combined with the KMP-
NativeCoroutine
library so I can use StateFlow on iOS. The problem I'm having is it seems it doesn't want to work with generics. I have the below (focus on
uiState
):
Copy code
open class BaseViewModel<U, R> internal constructor(
    uiStateDefault: U,
    private val redirectTypeDefault: R
) : KMMViewModel() {

    protected val redirectBehaviorSubject = BehaviorSubject(Redirect(redirectTypeDefault))

    protected val uiStateMutable = MutableStateFlow(viewModelScope, uiStateDefault)

    @NativeCoroutinesState
    val uiState: StateFlow<U> =uiStateMutable.asStateFlow()

    val redirectObservable: ObservableWrapper<Redirect<R>> =
        redirectBehaviorSubject.wrap()
    
    // ....
}
and while on Android it WORKS, on iOS it doesn't. It does see the
uiState
but it's seen as
Any?
and iOS needs to cast it to whatever
U
is in order for it to work. Is it a limitation of the
NativeCoroutine
library; am I using it wrong ?!; is it a limitation of KMM itself ?! I would like not to define
uiState
on each viewModel subclass so iOS can see it properly ... does anyone have an idea how to solve this and keep it generic ? :(
r
Yeah that is indeed a limitation. KMP-NativeCoroutines generates extensions functions which don’t support generics. Since you are using
NativeCoroutinesState
and just need the actual value you can do the following manually:
Copy code
@HiddenFromObjC
val uiState: StateFlow<U> =uiStateMutable.asStateFlow()

@ObjCName("uiState")
val uiStateValue: U get() = uiState.value
This is basically what is normally generated as an extension property, but as a member property which solves the generics limitation
a
hmm, but that will not trigger a recompose when the value changes, will it ?
recompose or whatever the swiftUI thing is called 😄 I think it's a view ... anyway ..
r
State changes will still be propagated to Swift(UI)
The magic for that is in
MutableStateFlow(viewModelScope, uiStateDefault)
a
ah, ok!
r
Once you update the value of that MutableStateFlow the changes are propagated to Swift
a
that's awesome then !!
trying it right now ! thank you very much !
👍🏻 1
hmm, so .. i just realized, i don't even need the @NativeCoroutinesState annotation then ...
r
Correct. It is just an easy way to create the value property for 99% of the cases.
a
fingers crossed! thank you
woot. it worked! the only thing is that it sees it a nullable even though it's always got a default value. ios dev needs to use
uiState?.someField
... Not sure if there's anything I can do about that though 🤔
r
Hmm good question, Maybe the following?:
BaseViewModel<U: Any, R>
m
The interop with Objective-C doesn't handle nullable generics in general, so I've avoided it in all my public generics.
a
@Rick Clephas i forgot to mention, setting U: Any worked perfectly ! Thank you !
👍🏻 1