switchmap 的 RxSwift 等价物
RxSwift equivalent for switchmap
在 RxJS 中,您可以将可观察对象的值用于新的可观察对象。例如:
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)
编辑 2:
这是登录功能
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()
}
}
有一个运算符flatMapLatest
,它和RxJS中的switchMap
完全一样。
你可以找到usage example here
在 RxJS 中,您可以将可观察对象的值用于新的可观察对象。例如:
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)
编辑 2:
这是登录功能
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()
}
}
有一个运算符flatMapLatest
,它和RxJS中的switchMap
完全一样。
你可以找到usage example here