【发布时间】:2019-11-19 17:59:50
【问题描述】:
在 RxJS 中,您可以将 observable 中的值用于新的 observable。例如:
this.authService.login(username, password).pipe(
switchMap((success: boolean) => {
if(success) {
return this.contactService.getLoggedInContact()
} else {
return of(null)
}
})
).subscribe(contact => {
this.contact = contact
})
但现在我必须用 Swift 做一个项目,我想实现同样的目标。我可以让这两种方法工作,但是将第一个可观察的结果用于第二个可观察的结果是我无法工作的。 switchMap 管道是 RxSwift 中不存在的东西,我找不到等价物。
我尝试将登录函数的结果映射到可观察对象,然后对其进行平面映射,但不幸的是,这不起作用。
在 Swift 中不使用订阅的最佳方法是什么?
编辑我尝试过平面地图:
APIService.login(email: "username", password: "password")
.flatMapLatest { result -> Observable<Contact> in
if result {
return APIService.getLoggedInContact()
} else {
return .of()
}
}.subscribe(onNext: {result in
print("Logged in contact: \(result)")
}, onError: {Error in
print(Error)
}).disposed(by: disposeBag)
但不幸的是,这不起作用,我收到错误Thread 1: EXC_BAD_ACCESS (code=1, address=0x13eff328c)
EDIT2:
这是登录功能
static func login(email: String, password: String) -> Observable<Bool> {
return Observable<String>.create { (observer) -> Disposable in
Alamofire.request(self.APIBASEURL + "/contact/login", method: .post, parameters: [
"email": email,
"password": password
], encoding: JSONEncoding.default).validate().responseJSON(completionHandler: {response in
if (response.result.isSuccess) {
guard let jsonData = response.data else {
return observer.onError(CustomError.api)
}
let decoder = JSONDecoder()
let apiResult = try? decoder.decode(ApiLogin.self, from: jsonData)
return observer.onNext(apiResult!.jwt)
} else {
return self.returnError(response: response, observer: observer)
}
})
return Disposables.create()
}.map{token in
return KeychainWrapper.standard.set(token, forKey: "authToken")
}
}
这是 getLoggedInContact 函数
static func getLoggedInContact() -> Observable<Contact> {
return Observable.create { observer -> Disposable in
Alamofire.request(self.APIBASEURL + "/contact/me", method: .get, headers: self.getAuthHeader())
.validate().responseJSON(completionHandler: {response in
if (response.result.isSuccess) {
guard let jsonData = response.data else {
return observer.onError(CustomError.api)
}
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(.apiNewsDateResult)
let apiResult = try? decoder.decode(Contact.self, from: jsonData)
return observer.onNext(apiResult!)
} else {
return self.returnError(response: response, observer: observer)
}
})
return Disposables.create()
}
}
【问题讨论】:
-
尝试清理和重建。您在编辑中所做的应该可以工作......顺便说一句,使用
.empty()而不是.of()会更惯用。 -
@DanielT。清理和重建不起作用:/它在 FlatMapLatest 类的 run 方法中崩溃,并出现相同的错误。
-
您的
get...函数中或代码中的其他地方一定有什么事情发生了。我将代码复制粘贴到一个沙盒项目中,它运行良好。 -
@DanielT。嗯,好的,谢谢!我会调查一下,我只是想象它不会是那些函数,因为作为独立函数,它们按预期工作。
-
@DanielT。经过大量测试,我找不到问题所在。我添加了功能,你有什么不寻常的地方吗?
标签: swift rxjs reactive-programming rx-swift reactivex