我正在围绕Firebase身份验证功能编写包装器,以返回Observable
并添加其他profileIncomplete
状态。它基本上首先检查用户是否已登录,如果已登录,则检查用户的个人资料是否完整。以下是我的代码,我想知道是否可以在Observable.create
中订阅一个可观察对象,如果可以,在这种情况下如何正确处置一次性对象?在闭包内部创建DisposeBag
?
enum State {
case loggedIn
case profileIncomplete
case notLoggedIn
}
func listenToAuthState() -> Observable<State> {
return Observable.create { observable in
let authStateHandle = Auth.auth().addStateDidChangeListener() { [weak self] (_, user) in
guard let user = user else {
observable.onNext(.notLoggedIn)
return
}
let disposable = self?.listenToProfileCompleted(uid: user.uid).subscribe(onNext: { (completed) in
if completed {
observable.onNext(.loggedIn)
observable.onCompleted()
} else {
observable.onNext(.profileIncomplete)
}
})
// How to dispose the disposable???
}
return Disposables.create {
Auth.auth().removeStateDidChangeListener(authStateHandle) }
}
}
func listenToProfileCompleted(uid: String) -> Observable<Bool> { ... }
答案 0 :(得分:2)
我认为在Observable.create
(或其他订阅块)中进行订阅是一种代码嗅觉。
似乎您有两个不同的问题。 stateChanged
和profileCompleted
。
我会将它们分为两种不同的方法,listenToAuthState
仅负责反映addStateDidChangeListener
的结果,而listenToProfileCompleted
有一个单独的方法。
这将使您拥有一个单独的“就绪”(或者您想称呼它),可以将两者压缩。或者,如果在侦听配置文件完成之前必须更改身份验证状态,请使用flatMap。
答案 1 :(得分:0)
要处置资源,可以将其添加到DisposeBag。像下面一样
func listenToAuthState() -> Observable<State> {
return Observable.create { observable in
var disposeBag:DisposeBag! = DisposeBag()
let authStateHandle = Auth.auth().addStateDidChangeListener() { [weak self] (_, user) in
guard let user = user else {
observable.onNext(.notLoggedIn)
return
}
let disposable = self?.listenToProfileCompleted(uid: user.uid).subscribe(onNext: { (completed) in
if completed {
observable.onNext(.loggedIn)
observable.onCompleted()
} else {
observable.onNext(.profileIncomplete)
}
}).disposed(by: disposeBag)
// How to dispose the disposable???
}
return Disposables.create {
Auth.auth().removeStateDidChangeListener(authStateHandle)
disposeBag = nil
}
}
}