繁体   English   中英

从每个屏幕访问登录 state(Jetpack Compose + MVVM + Hilt)

[英]Access the login state from every screen (Jetpack Compose + MVVM + Hilt)

我尝试在我的应用程序中随处访问登录 state 和其他用户信息。

以下是我的计划:

创建一个 UserState 数据 class:

data class UserState(
    val username: String = "",
    val profileImageUrl: String = "",
    var isLoggedIn: Boolean = false,
    val isPremiumUser: Boolean = false,
    val coins: Int = 0
)

用刀柄将其设为 singleton 并将其注入我的 AuthRepository:

    @Provides
    @Singleton
    fun provideUserState() = UserState()

    @Singleton
    @Provides
    fun provideAuthRepository(userState: UserState): AuthRepository {
        return AuthRepositoryImpl(userState)
    }

然后当身份验证(firebase + 自定义后端)成功或其他身份验证函数被调用时,我使用 userData 更新 userState:

class AuthRepositoryImpl @Inject constructor( 
    private var userState: UserState 
) : AuthRepository {

    override fun getUserState(): UserState {
        return userState
    }

    override suspend fun authenticateUser(token: String){
        
        val responseUser = authenticateUser(token)
        if (responseUser != null) {
            userState = UserState(
                username = responseUser.username,
                profileImageUrl = responseUser.profileImageUrl,
                isLoggedIn = true,
                isPremiumUser = responseUser.profileImageUrl,
                coins = responseUser.coins
            )
        } 
    } 
}

现在是我不确定如何做的部分,我如何从我的 ViewModel 中观察 userState? 例如,如果我从 ViewModel XI 调用我的 AuthRepository 中的 logOut function 想要查看/获取 ViewModel Y 中的更改。

例如,我在 MainViewModel 的 init 块中调用 getUserState 方法:

init {
    _mainUserState.value = authRepository.getUserState()
}

所以问题是它只在开始时更新,我如何观察对 UserState Singleton 所做的更改? 我不确定流是否是答案,如果是的话,如何在他的场景中准确使用它们

您可以在您的身份验证存储库中使用 flow 执行类似的操作:

private val _authData = MutableStateFlow<AuthEvent>(AuthEvent.Nothing)
    val authData: Flow<AuthEvent> = _authData

然后在登录/注销时像这样发出

_authData.emit(AuthEvent.Login)
  • AuthEvent 只是一个密封的 class

  • 将 AuthState 添加到 AuthEvent.Login class

  • 你也可以做共享流程



然后在你的 viewModel 下 viewModelScope 观察它

viewModelScope.launch {
            authRepository.getAuthFlow().collect() { data ->
                when (data) {
                    is AuthEvent.Logout -> {
                        sendUiEvent(MainUIEvent.Logout)
                        _state.value = state.value.copy(isLoggedIn = false, authData = null)
                    }

                    is AuthEvent.Login -> {
                        _state.value = state.value.copy(isLoggedIn = true, authData = data.authData)
                        sendUiEvent(MainUIEvent.LoggedIn)
                    }

                    is AuthEvent.Nothing -> {

                    }
                }
            }
        }

此 appoarch 允许您从 mainViewModel 处理身份验证状态和导航

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM