RxSwift Tap事件未触发

时间:2018-12-18 16:03:13

标签: ios swift mvvm reactive

我正在使用RxSwif实现mvvm。

发生了什么事

  • 验证字段(在两个textField中都写入7个字符)。
  • 点击登录按钮。
  • 调用API很好。
  • 再次点击按钮。
  • 未调用API。

我注意到每次我在textFields中写一些东西时,“ validObservable”都会改变。

ViewController:

    var viewModel: LoginViewModelType!
  let disposeBag = DisposeBag()
  @IBOutlet weak var dniTextField: UITextField!
  @IBOutlet weak var passwordTextField: UITextField!
  @IBOutlet weak var logInButton: UIButton!

  override func viewDidLoad() {
    super.viewDidLoad()


    logInButton.rx
      .tap
      .bind(to: viewModel.inputs.logInButtonDidTap)
      .disposed(by: disposeBag)


    dniTextField.rx
      .text
      .bind(to: viewModel.inputs.dniChanged)
      .disposed(by: disposeBag)

    passwordTextField.rx
      .text
      .bind(to: viewModel.inputs.passwordChanged)
      .disposed(by: disposeBag)


    /*viewModel.outputs.isLoginButtonEnabled
      .drive(onNext: { [weak self] isEnabled in
        guard let `self` = self else { return }
        self.logInButton.isEnabled = isEnabled
      })
      .disposed(by: disposeBag)
    */

    viewModel.outputs.logIn
      .drive(onNext: { [weak self] user in
        guard let `self` = self else { return }
        self.performSegue(withIdentifier: "showMainController", sender: user)
      })
      .disposed(by: disposeBag)
  }

  override func awakeFromNib() {
    super.awakeFromNib()
    viewModel = LoginViewModel()
  }

ViewModel:

    var inputs: LoginViewModelInputs { return self }
  var outputs: LoginViewModelOutputs { return self }

  // ---------------------
  // MARK: - Inputs
  // ---------------------
  var dniChanged: BehaviorRelay<String?>
  var passwordChanged: BehaviorRelay<String?>
  var logInButtonDidTap: PublishSubject<Void> = PublishSubject<Void>()


  // ---------------------
  // MARK: - Outpuds
  // ---------------------
  var logIn: Driver<User>
  var isLoginButtonEnabled: Driver<Bool>

  private let disposeBag = DisposeBag()

  public init () {
    dniChanged = BehaviorRelay<String?>(value: "")
    passwordChanged = BehaviorRelay<String?>(value: "")

    let dniObservable = dniChanged.asDriver().filterNil().asObservable()
    let passwordObservable = passwordChanged.asDriver().filterNil().asObservable()

    let dniValidation = dniObservable.map { $0.count > 4 }
    let passwordValidation = passwordObservable.map { $0.count > 3 }

    let validObservable = Observable.combineLatest(dniValidation, passwordValidation) { return $0 && $1 }.filter { $0 }

    isLoginButtonEnabled = validObservable.asDriver(onErrorDriveWith: .empty())

    let loginSuccessObservable = Observable.combineLatest(dniObservable, passwordObservable, validObservable) { (dni, password, valid) -> LogInRequest in
      return LogInRequest(dni: dni, password: password)
    }

    logIn = logInButtonDidTap.withLatestFrom(loginSuccessObservable).flatMapLatest({ request -> Observable<User> in
      return API.shared.post(endpoint: EndPoints.Authorize, type: User.self, body: request)
    }).asDriver(onErrorDriveWith: .empty())
  }

1 个答案:

答案 0 :(得分:0)

我会说.empty()导致可观察对象完成,并且结果将导致订阅被处置。

我会放一些.debug()指令,以确保处置什么以及何时处置。