Ios RxSwift回调返回结果之前的第一个

Ios RxSwift回调返回结果之前的第一个,ios,swift,firebase,firebase-authentication,rx-swift,Ios,Swift,Firebase,Firebase Authentication,Rx Swift,我正在使用Firebase FirAuth API,在API返回结果之前,Disposables.create()已返回且不再可单击(我知道这可能是因为调用API后没有observer.onCompleted。是否有方法等待/侦听结果 public func login(_ email: String, _ password: String) -> Observable<APIResponseResult> { let observable = Observable&

我正在使用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

}
public func登录(\uemail:String,\upassword:String)->可观察{
让observable=observable.create{observable->Disposable in
让完成:(FIRUser?,错误?->Void={(用户,错误)在
如果let error=error{
UserSession.default.clearSession()
操作员错误(APIResponseResult.失败(错误))
观察员。在(.completed)
返回
}
UserSession.default.user.value=用户!
observer.onNext(APIResponseResult.Success)
观察员。在(.completed)
返回
}
DispatchQueue.main.async{
FIRAuth.auth()?.signIn(使用电子邮件:电子邮件,密码:密码,完成:完成)
}
返回一次性物品。创建()
}
可观测回波
}

您的假设是正确的,即onError/onCompletion事件终止了可观察序列。这意味着,在任何情况下,该序列都不会再发出任何事件

作为附带说明,您不需要在
.onError()
之后执行
.on(.completed)
,因为onError已经终止了序列

写入的部分
return Disposables.create()
返回一个一次性对象,以便以后可以将observable添加到DisposeBag中,该DisposeBag将在DisposeBag解除分配时处理该observable的解除分配,因此它应该立即返回,但不会终止您的请求


为了更好地理解正在发生的事情,我建议在使用Observable的部分周围添加
.debug()
语句,这将允许您准确地了解正在发生的事件,并帮助您准确地了解错误:)

我不久前也遇到过同样的问题,如果有错误,我想在
onError
中显示
警报,但不处理可观察到的内容

我通过捕获错误并返回一个带有案例
.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)
//apireresult.swift
枚举ApiResponseResult{
案例错误(错误)
案例成功(FIRUser)
}
//视图模型
func登录(…)->可观察{
让observable=observable.create{…}
返回observable.catchError{error in
返回可观察的。仅(.error(error))
}
}
//视图控制器
视图模型
.登录
.subscribe(onNext:{结果为
切换结果{
案例错误(let error):
//警觉还是什么
打破
成功案例(让用户):
//万岁
打破
} 
})
.addDisposableTo(disposeBag)

Firebase是异步的,不以同步方式返回数据。虽然你可以强制这种模式,但它将导致许多长期问题。所有的调度队列和回调都应该被删除,否则将是一个噩梦,以进行故障排除。让Firebase完成它的工作;一旦Firebase闭包中的数据可用,然后进入UI中的下一步,处理该数据等。代码可能过于复杂-如果您能够解释您试图实现的目标,可能会提供一个清晰的解决方案,而不是解决方法。感谢您的解释。我想要实现的是将正确的响应返回到视图控制器,以便重定向(如果成功)或发出警报(如果错误)。在这种情况下,我总是得到一个空错误,因为它总是首先返回错误场景。只需更改流程:捕获用户信息,然后通过Firebase调用创建用户。在闭包中,您可能会出现错误(检查错误代码以了解原因),并将错误或无错误告知用户,以便继续显示下一个viewController或下一步的内容。应该是大约6行代码,并且可以在没有调度队列和回调的情况下完成。感谢您指出这一点。我想了解RxSwift如何与Firebase API一起工作,因此我正在尝试调用并等待响应。