moko-mvvm icon indicating copy to clipboard operation
moko-mvvm copied to clipboard

iOS nullable value from CStateFlow

Open kramlex opened this issue 3 years ago • 1 comments

mokoMvvmFramework does not allow to get a iOS nullable value from CStateFlow, , it is necessary to add at the moment, force unwrap is being used there

func stateNullable<T, R>(
        _ flowKey: KeyPath<Self, CStateFlow<T>>,
        equals: @escaping (T?, T?) -> Bool,
        mapper: @escaping (T?) -> R?
    ) -> R? {
        let stateFlow: CStateFlow<T> = self[keyPath: flowKey]
        var lastValue: T? = stateFlow.value

        var disposable: DisposableHandle? = nil

        disposable = stateFlow.subscribe(onCollect: { value in
            if !equals(lastValue, value) {
                lastValue = value
                self.objectWillChange.send()
                disposable?.dispose()
            }
        })

        return mapper(stateFlow.value)
    }
Снимок экрана 2022-06-03 в 9 03 36 PM

kramlex avatar Jun 03 '22 14:06 kramlex

Hey @kramlex, I tried to use your solution, but could not get it working. I added a debug output, but it only prints nil. I double checked on the KMM side, added a output there and got the correct state after the update.

func stateNullable<T, R>(
    _ flowKey: KeyPath<Self, CStateFlow<T>>,
    equals: @escaping (T?, T?) -> Bool,
    mapper: @escaping (T?) -> R?
) -> R? {
    let stateFlow: CStateFlow<T> = self[keyPath: flowKey]
    var lastValue: T? = stateFlow.value

    var disposable: DisposableHandle?

    disposable = stateFlow.subscribe(onCollect: { value in
        print(value)
        if !equals(lastValue, value) {
            lastValue = value
            self.objectWillChange.send()
            disposable?.dispose()
        }
    })

    return mapper(stateFlow.value)
}

My code in the KMM module looks like this:

private var _availableItems = MutableStateFlow<List<Item>?>(null)
val availableItems = _availableItems.cStateFlow()

Inside my SwiftUI view, I am calling it like this:

vehicles: viewModel.stateNullable(\.availableItems, equals: { $0 === $1 }, mapper: { $0 as! [Item]? }),

The normal/predefined states work just fine. Do you have any hint what I am missing?

Edit: after switching to a non-nullable list, I got the similar effect that the list value is not updated and stays empty. So from m experience, there seems to be a problem with lists in general.

Edit 2: I could work around this limitation by using the state pattern in your example. As the state is always non-nullable, the code from above is not even need. Nevertheless, it would still be nice if nullable data types would be supported.

ln-12 avatar Aug 19 '22 12:08 ln-12

Hi, @ln-12. I analyzed your problem and couldn't reproduce it. The proposed solution works correctly. If the problem hasn't been solved yet, then I would like to take a look at your view model or case.

kramlex avatar Sep 24 '22 18:09 kramlex

Thanks @kramlex, I found another approach which is working fine for me.

ln-12 avatar Sep 26 '22 08:09 ln-12

will be released in 0.15.0

Alex009 avatar Oct 03 '22 07:10 Alex009