viewModelScope.launch и callbackFlow
Помогите пожалуйста разобраться со скопами, делаю патерн MVI не могу понять почему нужно оборачивать вызываемые методы еще одним launch {}. Если не сделать обертку для repository.registerWithEmailAndPassword то интент поймается только 1 раз, дальше глухо как будто Интенты больше не поступают. Не уверен что так делать правильно, с оберткой в launch работает но хотелось узнать как это правильно сделать и как это работает.
Нужно ли что-то писать в awaitClose {} если используешь callbackFlow с viewModelScope? По идеи когда ляжет viewModelScope он должен за собой утащить все остальное правильно?
ViewModel
val userIntent = Channel<RegisterIntent>(Channel.UNLIMITED)
private val _state = MutableStateFlow<RegisterStates>(RegisterStates.Idle)
val state: StateFlow<RegisterStates>
get() = _state
init {
handleIntent()
}
@ExperimentalCoroutinesApi
private fun handleIntent() {
viewModelScope.launch {
userIntent.consumeAsFlow().collect { intent ->
when (intent) {
is RegisterIntent.Idle -> {
}
is RegisterIntent.RegisterWithEmailAndPassword -> {
viewModelScope.launch {
repository.registerWithEmailAndPassword(
intent.name,
intent.email,
intent.password,
intent.profileImage
).collect { authData ->
when (authData) {
UserAuthData.Success -> {
_state.value = RegisterStates.Success
}
is UserAuthData.Fail -> {
_state.value = RegisterStates.Fail(authData.e)
}
else -> {
}
}
}
}
}
}
}
}
}
Repository
override fun registerWithEmailAndPassword(
name: String,
email: String,
password: String,
profileImage: Uri?
): Flow<UserAuthData> =
callbackFlow {
val onCompleteListener = OnCompleteListener<AuthResult> {
if (it.isSuccessful) {
..........
sendBlocking(UserAuthData.Success)
} else {
sendBlocking(UserAuthData.Success)
}
}
}
val onFailureListener = OnFailureListener {
sendBlocking(UserAuthData.Fail(it))
}
try {
auth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(onCompleteListener)
.addOnFailureListener(onFailureListener)
} catch (e: Exception) {
sendBlocking(UserAuthData.Fail(e))
}
awaitClose {
}
}
View
lifecycleScope.launch {
registerViewModel.userIntent.send(
RegisterIntent.RegisterWithEmailAndPassword(
userName,
userEmail,
userPassword,
profileImg
)
)
}