Rxswift проверяет ввод перед отправкой запроса API - PullRequest
0 голосов
/ 19 февраля 2019

У меня есть экран входа в систему, я ранее показывал ошибку, введенную над текстовым полем, и кнопку отключения, комбинируя адрес электронной почты / пароль Bool Observable, однако теперь дизайн изменился, и я хочу проверить, не являются ли адрес электронной почты / пароль не пустыми, перед отправкой запросаили показать диалоговое окно с предупреждением

Моя проблема заключается в том, как проверить правильность введенных данных перед выполнением запроса:

LoginViewModel:

  var emailValid: Observable<Bool> {
        return emailSubject.asObservable().map { $0.count > 0 && $0.isEmail}
    }

  signInDidTapSubject
       .withLatestFrom(credentialsObservable)
        .flatMapLatest { credentials -> Observable<Event<Result<UserResponse>>> in
            self.loadInProgress.accept(true)
            return network.login(with: credentials).materialize()
        }
        .subscribe(onNext: { [weak self] event in
            self?.loadInProgress.accept(false)
            switch event {
            case .next(let result):
                switch result{
                case .Success(let user):
                    self?.loginResultSubject.onNext(user)
                case .Failure(let error):
                    self?.errorsSubject.onNext(error)
                }
            case .error( _):
                print("error")
            default:
                break
            }
        })
        .disposed(by: disposeBag)

VC:

   loginButton.rx.tap.asObservable()
        .debounce(0.5, scheduler: MainScheduler.instance)
        .subscribe(viewModel.input.loginButtonTapped).disposed(by: disposeBag)

1 Ответ

0 голосов
/ 19 февраля 2019

Чтобы понять это, задайте себе вопрос: «Какие входные данные мне нужны для создания этого выходного сигнала?»

У вас есть два выхода: «Пользователь» и «Ошибка».Давайте сначала сделаем счастливый путь.Какие входные данные вам нужны для создания пользователя?Просто успешный сетевой ответ.Но какие входные данные вам нужны для получения сетевого ответа?Ну, вам нужен адрес электронной почты и пароль, но инцидент, связанный с подстрекательством, нажимается на кнопку входа в систему, и запрос не должен выполняться, если данные неверны:

let networkResponse = loginTrigger
    .withLatestFrom(credentials)
    .filter { $0.email.isEmail && !$0.password.isEmpty }
    .flatMapLatest {
        network.login(with: $0)
            .materialize()
    }
    .share(replay: 1)

let user = networkResponse
    .filter { $0.element != nil }
    .map { $0.element! }

Теперь, какие входные данные вам нужнысделать вывод Error?Вам нужна ошибка из сетевого запроса, если она есть, и вам необходимо знать, были ли адрес электронной почты или пароль недействительными.Тем не менее, вы хотите узнать о недопустимом вводе, только если нажата кнопка входа в систему ...

Это много, но вот как это ломается:

let networkError = networkResponse
    .filter { $0.error != nil }
    .map { $0.error! }

let invalidEmailError = loginTrigger
    .withLatestFrom(email)
    .filter { !$0.isEmail }
    .map { _ in UIError.badEmail as Error }

let invalidPasswordError = loginTrigger
    .withLatestFrom(password)
    .filter { $0.isEmpty }
    .map { _ in UIError.badPassword as Error }

let error = Observable.merge(networkError, invalidEmailError, invalidPasswordError)

Видите, как это работает?Возьмите каждый выход по очереди и выясните, какие входы вам нужны, чтобы этот выход работал.

...