我正在使用Firebase FirAuth API,在API返回结果之前,已经返回Disposables.create()并且它不再可点击(我知道这可能是因为在调用API之后没有observer.onCompleted。有没有办法等待/听取结果?
public func login(_ email: String, _ password: String) -> Observable<APIResponseResult> {
let observable = Observable<APIResponseResult>.create { observer -> Disposable in
let completion : (FIRUser?, Error?) -> Void = { (user, error) in
if let error = error {
UserSession.default.clearSession()
observer.onError(APIResponseResult.Failure(error))
observer.on(.completed)
return
}
UserSession.default.user.value = user!
observer.onNext(APIResponseResult.Success)
observer.on(.completed)
return
}
DispatchQueue.main.async {
FIRAuth.auth()?.signIn(withEmail: email, password: password, completion: completion)
}
return Disposables.create()
}
return observable
}
答案 0 :(得分:1)
您认为onError / onCompletion事件终止Observable Sequence是正确的。意思是,在任何情况下,序列都不会再发出任何事件。
作为旁注,您不需要在.on(.completed)
之后执行.onError()
,因为onError已经终止了序列。
您编写return Disposables.create()
的部分返回一个Disposable对象,以便稍后可以将observable添加到DisposeBag中,该DisposeBag将在解除分配DisposeBag时处理释放observable,因此应该立即返回,但不会终止您的请求。
为了更好地了解正在发生的事情,我建议在使用Observable的部分周围添加.debug()
语句,这样可以让您准确了解发生的事件,并帮助您准确理解错误的原因:)
答案 1 :(得分:0)
前段时间我遇到了同样的问题,如果出现错误,我想在Alert
中显示onError
,但不会丢弃可观察的内容。
我通过捕获错误并使用案例enum
和.success(MyType)
.error(Error)
来解决问题
一个例子:
// ApiResponseResult.swift
enum ApiResponseResult {
case error(Error)
case success(FIRUser)
}
// ViewModel
func login(...) -> Observable<ApiResponseResult> {
let observable = Observable.create { ... }
return observable.catchError { error in
return Observable<ApiResponseResult>.just(.error(error))
}
}
// ViewController
viewModel
.login
.subscribe(onNext: { result in
switch result {
case .error(let error):
// Alert or whatever
break
case .success(let user):
// Hurray
break
}
})
.addDisposableTo(disposeBag)