在具有 ViewModel 架构的 KMM 应用程序中使用collectAsState 的最佳方式

问题描述 投票:0回答:1

在 KMM 应用程序中使用collectAsState 的最佳方式是什么? 目前我在我的应用程序中使用它,如下所示:

用户界面:

usersViewModel.userInfo.collectAsState(null).apply {
//use data from userInfo
}

视图模型:

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

回购:

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

目前看起来很慢,我不知道是因为调试还是我没有以最佳方式获取实时数据。

感谢您的帮助!

android kotlin google-cloud-firestore android-livedata kotlin-multiplatform
1个回答
0
投票

总体思路是不收集流量,而只是将它们传递到各层(可能会在途中转换它们),直到它们到达 UI。只有在那里它们最终才会被收集。

对于您的存储库,这意味着您不应该收集并重新发出该值,而只需通过映射其内容来转换流程:

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

在视图模型中,您需要将流转换为 StateFlow:

val userInfo: StateFlow<User?> = repo.getUserProfile()
    .stateIn(
        scope = viewModelScope,
        started = SharingStarted.WhileSubscribed(5_000),
        initialValue = null,
    )

最后在可组合项中将 StateFlow 转换为 Compose State:

val userInfo: User? by usersViewModel.userInfo.collectAsState()

(如果您希望集合具有生命周期意识,则需要使用 gradle 依赖项

collectAsStateWithLifecycle
中的
androidx.lifecycle:lifecycle-runtime-compose
来代替。)

请注意

by
委托,它允许您使用
userInfo
,就好像它是
User?
类型一样,而它实际上是引擎盖下的
State<User?>

现在您可以使用

userInfo
变量做任何您想做的事情。 Flow 框架保证该变量始终是最新的,并且每当出现新值时就会触发 UI 的重组。

© www.soinside.com 2019 - 2024. All rights reserved.