Контекст
Я следую примеру WWD C 2019 722 https://developer.apple.com/videos/play/wwdc2019/722/ и WWD C 2019 721 https://developer.apple.com/videos/play/wwdc2019/721/ и делаю поле с проверкой запускает асинхронную проверку сети на поле.
Что должно произойти, как упоминалось в докладе, это то, что поле имени пользователя должно:
- Debounce
- Показать индикатор загрузки
- Выполнить сетевой запрос
- Завершить сетевой результат
- Скрыть индикатор загрузки
- И показать или скрыть сообщение проверки в результате ответа сети
у меня есть прототип, который имеет debounce, и проверяет сетевой запрос с помощью оператора задержки. Все это работает хорошо по большей части.
let a = $firstName
.debounce(for: .seconds(0.5), scheduler: DispatchQueue.main)
.flatMap { name -> AnyPublisher<String, Never> in
if name == "" {
return Just(name)
.eraseToAnyPublisher()
} else {
return Just(name)
.handleEvents(receiveOutput: { _ in self.isFirstNameLoading = true})
.delay(for: .seconds(2), scheduler: DispatchQueue.main)
.handleEvents(receiveOutput: { _ in self.isFirstNameLoading = false})
.eraseToAnyPublisher()
}
}
.map { name -> Bool in name != "Q" }
.assign(to: \.isFirstNameValid, on: self)
Отладка ждет, пока ввод не приостановится. flatMap
действует как условное ветвление в потоке операторов Combine: если значение пусто, не беспокойтесь о сетевом запросе; иначе, если значение имеет значение после отката, выполните сетевой запрос. И, наконец, мой пример, что «Q» всегда является ошибкой в фиктивных целях.
Однако небольшая проблема заключается в том, что отладка происходит до ветвления. Я хотел бы переместить debounce в ветвь else условного выражения, например, так.
let a = $firstName
.flatMap { name -> AnyPublisher<String, Never> in
if name == "" {
return Just(name)
.eraseToAnyPublisher()
} else {
return Just(name)
.debounce(for: .seconds(0.5), scheduler: DispatchQueue.main)
.handleEvents(receiveOutput: { _ in self.isFirstNameLoading = true})
.delay(for: .seconds(2), scheduler: DispatchQueue.main)
.handleEvents(receiveOutput: { _ in self.isFirstNameLoading = false})
.eraseToAnyPublisher()
}
}
.map { name -> Bool in name != "Q" }
.assign(to: \.isFirstNameValid, on: self)
Когда это происходит, истинная ветвь условного выражения (пустой ввод) выполняется правильно, и map + assign после того, как flatMap работает правильно. Однако, когда вход имеет значение, и ветвь else условного запуска выполняется, ничего после отката не запускается вообще.
Я попытался переключить DispatchQueue
на OperationQueue.main
и RunLoop.main
, но безрезультатно.
Сохранение отката до условной работы пока нормально, но мне интересно, Я делаю что-то не так с моей попыткой поместить это в ветку. Мне также интересно, если бы это был правильный способ сделать "ветвление" в операторах с Combine, особенно с моим использованием flatMap
и Just()
.
Любая помощь будет оценена!