Cipri
Cipri

Reputation: 314

How to use Flow in iOS from my kotlin repository?

In my KMM app, I have my kotlin shared code with this method:

fun getUserProfile(): Flow<UserInfo?> =
        firestore.collection("UserInfo").document(auth.currentUser!!.uid).snapshots
            .mapLatest { user ->
                user.data<UserInfo>()
            }
            .catch { ex ->
                println("Something wrong")
            }

The way that I call the method in the android:

ViewModel:

val userInfo = repo.getUserProfile().catch { println("no User found") }

UI:

usersViewModel.userInfo.collectAsState(null).apply { }

I want something similar for my iOS SwiftUI, I want a simple call:

func getUserInfo(){
 }

Upvotes: 0

Views: 71

Answers (1)

Kevin Galligan
Kevin Galligan

Reputation: 17282

Directly, manually consuming a Flow is not great. There are two main library options. We publish SKIE, which I would recommend. Specifically for what you want to do, take a look at this: https://skie.touchlab.co/features/flows-in-swiftui.

Kotlin

class SharedViewModel {
    
    val counter = flow<Int> {
        var counter = 0
        while (true) {
            emit(counter++)
            delay(1.seconds)
        }
    }

    val toggle = MutableStateFlow<Boolean>(false)
}

Swift

struct ExampleView: View {
    let viewModel = SharedViewModel()

    var body: some View {
        // Observing multiple flows with attached initial values, only requiring a single view closure for content.
        Observing(viewModel.counter.withInitialValue(0), viewModel.toggle) { counter, toggle in
            Text("Counter: \(counter), Toggle: \(toggle)")
        }
    }
}

The other option is https://github.com/rickclephas/KMP-NativeCoroutines.

SKIE actually augments the output of the Kotlin compiler, generating Swift and compiling into the framework. KMPNC is more of a standard library, but requires more direct management of lifecycle, etc.

Upvotes: 1

Related Questions