RxSwift: malentendiendo algún concepto

Soy muy principiante con RxSwift y estoy tratando de comenzar con una simple pantalla de inicio de session. Así que tengo 2 campos de text y un button de inicio de session, que se enlaza a un object de PublishSubject por lo que cada vez que PublishSubject el button enviaré una request de networking para realizar la authentication.

Debido a que la authentication puede fallar, fui con un Driver para poder reproducir mi request cada vez que hago clic en el button.

Tengo 2 versiones de lo que creo que es el mismo código, pero una funciona y otra no. Estoy tratando de entender lo que sucede detrás de la escena.

Aquí la primera versión que funciona (solicite cada vez que toque el button):

 let cnetworkingentials = Driver.combineLatest(email.asDriver(), password.asDriver()) { ($0, $1) } self.signIn = signInTaps .asDriver(onErrorJustReturn: ()) .withLatestFrom(cnetworkingentials) .flatMapLatest { email, password in // returns Driver<Result<AuthenticateResponse, APIError>> return provider.request(.Authenticate(email: email, password: password)) .filterSuccessfulStatusCodes() .mapObject(AuthenticateResponse) .map { element -> Result<AuthenticateResponse, APIError> in return .Success(element) } .asDriver { error in let e = APIError.fromError(error) return Driver<Result<AuthenticateResponse, APIError>>.just(.Failure(e)) } .debug() } 

Y aquí está el que no funciona (solicite incendios solo con el primer clic):

 let cnetworkingentials = Observable.combineLatest(email.asObservable(), password.asObservable()) { ($0, $1) } self.signIn = signInTaps.asObservable() .withLatestFrom(c) .flatMapLatest { email, password in // returns Observable<AuthenticateResponse> return provider.request(.Authenticate(email: email, password: password)) .filterSuccessfulStatusCodes() .mapObject(AuthenticateResponse) } .map { element -> Result<AuthenticateResponse, APIError> in // returns Observable<Result<AuthenticateResponse, APIError>> return .Success(element) } .asDriver { error in // returns Driver<Result<AuthenticateResponse, APIError>> let e = APIError.fromError(error) return Driver<Result<AuthenticateResponse, APIError>>.just(.Failure(e)) } .debug() 

Para get información, aquí está mi statement de properties:

 let email = Variable("") let password = Variable("") let signInTaps = PublishSubject<Void>() let signIn: Driver<Result<AuthenticateResponse, APIError>> 

Analicemos lo que está sucediendo en el primero (ya que en general son los mismos):

 // 1. let cnetworkingentials = Driver.combineLatest(email.asDriver(), password.asDriver()) { ($0, $1) } // 2. self.signIn = signInTaps .asDriver(onErrorJustReturn: ()) // 3. .withLatestFrom(cnetworkingentials) // 4. .flatMapLatest { email, password in // returns Driver<Result<AuthenticateResponse, APIError>> return provider.request(.Authenticate(email: email, password: password)) .filterSuccessfulStatusCodes() .mapObject(AuthenticateResponse) .map { element -> Result<AuthenticateResponse, APIError> in return .Success(element) } .asDriver { error in let e = APIError.fromError(error) return Driver<Result<AuthenticateResponse, APIError>>.just(.Failure(e)) } .debug() } 
  1. Está combinando las últimas señales del email y la contraseña y combinándolas en una tupla de String .
  2. Esta es su señal de inicio de session, el compuesto de todas las siguientes señales.
  3. Está combinando los últimos resultados de las cnetworkingentials con solo tocar un button.
  4. Cada vez que se toca el button o se emite el correo electrónico o la contraseña, se cancela la señal actual y se crea una nueva que realiza una llamada (usando Moya), se filtra mediante códigos de estado exitosos, se correlaciona el object y se manejan el éxito y el error.

El segundo ejemplo es principalmente el mismo, excepto que está utilizando observables en lugar de controlleres. Compruebe signInTaps y vea si está recibiendo events cada vez que toque el button. Podría ser que en algún punto de la línea la señal está desasignando y realmente la única diferencia entre las dos versiones es el uso de controlleres y observables.

También tenga en count que el uso de un controller es solo un azúcar sintáctico sobre un observable.

 let intDriver = sequenceOf(1, 2, 3, 4, 5, 6) .asDriver(onErrorJustReturn: 1) .map { $0 + 1 } .filter { $0 < 5 } 

es lo mismo que

 let intObservable = sequenceOf(1, 2, 3, 4, 5, 6) .observeOn(MainScheduler.shanetworkingInstance) .catchErrorJustReturn(1) .map { $0 + 1 } .filter { $0 < 5 } .shareReplay(1) 

Entonces, cuando usa observables sobre los controlleres, está perdiendo .observeOn y .observeOn . Podría ser que con los controlleres solo está viendo los valores de reproducción y caching.