开关映射的 RxSwift 等效项
Posted
技术标签:
【中文标题】开关映射的 RxSwift 等效项【英文标题】:RxSwift equivalent for switchmap 【发布时间】: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()
.maptoken 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。经过大量测试,我找不到问题所在。我添加了功能,你有什么不寻常的地方吗?
【参考方案1】:
flatMapLatest
的操作符与 RxJS 中的 switchMap
完全相同。
你可以找到usage example here
【讨论】:
谢谢,我刚试过这个,但不幸的是它在到达 flatMap 时崩溃了。即使我在 if 语句之前打印。 ://以上是关于开关映射的 RxSwift 等效项的主要内容,如果未能解决你的问题,请参考以下文章