Я хочу проверить текст проверки при нажатии кнопки - PullRequest
1 голос
/ 19 апреля 2019

Я хочу проверить текст проверки при нажатии кнопки.Если подтвердить ошибку, он покажет текст ошибки на UILabel и не отправит запрос.В противном случае, если подтвердить успех, он отправит запрос.

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

Я должен написать код.

class LoginViewModel: BaseViewModel, ViewModelType {
    struct Input {
        let loginTaps: Driver<Void>
    }
    struct Output {
        let validatedUsername: Driver<Bool>
        let validatedPassword: Driver<Bool>
    }

    let username = BehaviorRelay(value: "")
    let password = BehaviorRelay(value: "")
    let loginTapped = PublishSubject<Void>()

    func transform(input: Input) -> Output {

        let validatedUsername = username.asDriver(onErrorJustReturn: "").map { username in
            return username.isPhoneNumber
        }

        let validatedPassword = password.asDriver(onErrorJustReturn: "").map { password in
            return password.count > 7
        }

        input.loginTaps.map { () -> Void in
            <#code#>
            // I want do check and then do network request
        }

        input.loginTaps.drive(onNext: { [weak self] () in
                self?.loginTapped.onNext(())
            }).disposed(by: rx.disposeBag)

        loginTapped.flatMapLatest { _  -> Observable<RxSwift.Event<Token>> in

           // and if I want to return Bool not Token, how should I do????????????

            return self.provider.login(username: self.username.value, password: self.password.value)
                .asObservable()
                .materialize()
            }.subscribe(onNext: { (event) in
                switch event {
                case .next(let token):
                    AuthManager.setToken(token: token)
                case .error(let error):
                    log.error(error.localizedDescription)
                default: break
                }
            }).disposed(by: rx.disposeBag)

        return Output(validatedUsername: validatedUsername,
                      validatedPassword: validatedPassword)
    }
}

1 Ответ

0 голосов
/ 20 апреля 2019

Я бы ожидал увидеть что-то вроде этого:

class LoginViewModel {
    struct Input {
        let loginTap: Signal<Void>
        let username: Driver<String>
        let password: Driver<String>
    }

    struct Output {
        let errorText: Driver<String>
        let loginSuccess: Signal<Void>
    }

    var networkRequest: (URLRequest) -> Observable<Data> = { _ in fatalError("need to replace this with an implementation.") }

    func transform(input: Input) -> Output {

        func isValidCredentials(username: String, password: String) -> Bool {
            return username.isPhoneNumber && password.count > 7
        }

        let credentials = Driver.combineLatest(input.username, input.password)

        // this chain emits when the login button is tapped and the credentials are invalid
        let invalidInputError = input.loginTap
            .withLatestFrom(credentials)
            .filter { !isValidCredentials(username: $0, password: $1) }
            .map { _ in "Credentials are invalid" }
            .asDriver(onErrorRecover: { _ in fatalError("can't get here") })

        let networkRequest = self.networkRequest // to avoid dealing with `self` in the flatMap below

        // this chain makes a request if the login button is tapped while the credentials are valid
        let loginResult = input.loginTap
            .withLatestFrom(credentials)
            .filter { isValidCredentials(username: $0, password: $1) }
            .map { URLRequest.login(username: $0, password: $1) }
            .asObservable()
            .flatMapLatest { networkRequest($0).materialize() }
            .share(replay: 1)

        // this chain emits when the login result produces an error
        let loginError = loginResult
            .map { $0.error }
            .filter { $0 != nil }
            .map { $0!.localizedDescription }
            .asDriver(onErrorRecover: { _ in fatalError("can't get here") })

        // this chain emits when the login result succeeds
        let loginSuccess = loginResult
            .filter { $0.element != nil }
            .map { _ in }
            .asSignal(onErrorRecover: { _ in fatalError("can't get here") })

        let errorText = Driver.merge(invalidInputError, loginError)

        return Output(errorText: errorText, loginSuccess: loginSuccess)
    }
}
...