如何在 RxSwift 中 return 与 flatMapLatest 不同的类型?
How to return different types from flatMapLatest in RxSwift?
我正在关注 RxSwift 示例 GitHub SignUp using Driver,并以类似的方式结束。
我有一个执行身份验证的网络请求,并且 return 是一个 Observable<AuthenticationResult>
,这样我就有了:
public enum AuthenticationResult {
case canceled
case usernameEmpty
case passwordEmpty
case invalidCredentials
case granted(AccessToken)
case other(Error)
}
// Authentication result status
let authenticationResult: Driver<AuthenticationResult>
authenticationResult = input.loginTaps.withLatestFrom(usernameAndPassword)
.flatMapLatest({ (username, password) -> SharedSequence<DriverSharingStrategy, AuthenticationResult> in
return API.authenticate(username: username, password: password, applicationScope: .property).trackActivity(signingIn).asDriver(onErrorJustReturn: .canceled)
})
.flatMapLatest({ (result) -> SharedSequence<DriverSharingStrategy, AuthenticationResult> in
switch result {
case .granted(_):
// The closure is expecting a return value here that I don't have!
let portfoliosNavigationController = UINavigationController(rootViewController: PortfoliosTableViewController())
wireframe.show(viewController: portfoliosNavigationController)
default:
return wireframe.promptFor(result.description, cancelAction: "OK", actions: [])
.map({ (_) -> AuthenticationResult in
result
}).asDriver(onErrorJustReturn: result)
}
})
现在,问题:
我的 flatMapLatest
期望 SharedSequence<DriverSharingStrategy, AuthenticationResult>
而我并不总是 return!
在闭包内部,我可以 return SharedSequence<DriverSharingStrategy, AuthenticationResult>
如果身份验证成功 ,因为我的 wireframe.promptFor
return 是一个可观察对象.
但是,当身份验证失败 时,我没有return 的可观察对象。我的 wireframe.show
方法没有 return 任何东西。
我该如何处理这种情况?
谢谢
假设 switch case .granted
是认证成功,你可以简单地 return Observable.empty()
或 Driver.empty()
.
那有什么作用?
通过在 flatMap
操作中 return 一个空的驱动程序序列,您的意思是结束可观察序列。流将收到 onCompleted
事件,您可以将其理解为 流或操作成功。
您的以下代码将在 drive()
方法的 onCompleted
闭包中找到。
// Your observable stream / driver sequence
.drive(onCompleted: { [unowned wireframe] in
let portfoliosNavigationController = UINavigationController(rootViewController: PortfoliosTableViewController())
wireframe.show(viewController: portfoliosNavigationController)
}
应该可以。
RxCocoa Driver
单元
通过使用 Driver unit,您是说您期望可观察序列具有以下特征:
- 不能出错
- 观察主调度程序
- 分享副作用(shareReplayLatestWhileConnected)
这在执行 UI 相关的事情时通常很有用(比如你想做的是显示导航控制器)。如果是这种情况,请继续使用驱动程序。
但是如果我的流可能遇到错误怎么办?
如果有机会你需要 return 到一个可观察的序列,这样你就可以出错(因为你要执行一个可能出错的可观察操作,或者因为你想抛出一个错误停止操作),然后您可以在 Driver
实例上使用 toObservable()
操作。
不过要小心,因为你失去了你将在主线程上 运行 的断言(你需要它来显示视图控制器)。
我正在关注 RxSwift 示例 GitHub SignUp using Driver,并以类似的方式结束。
我有一个执行身份验证的网络请求,并且 return 是一个 Observable<AuthenticationResult>
,这样我就有了:
public enum AuthenticationResult {
case canceled
case usernameEmpty
case passwordEmpty
case invalidCredentials
case granted(AccessToken)
case other(Error)
}
// Authentication result status
let authenticationResult: Driver<AuthenticationResult>
authenticationResult = input.loginTaps.withLatestFrom(usernameAndPassword)
.flatMapLatest({ (username, password) -> SharedSequence<DriverSharingStrategy, AuthenticationResult> in
return API.authenticate(username: username, password: password, applicationScope: .property).trackActivity(signingIn).asDriver(onErrorJustReturn: .canceled)
})
.flatMapLatest({ (result) -> SharedSequence<DriverSharingStrategy, AuthenticationResult> in
switch result {
case .granted(_):
// The closure is expecting a return value here that I don't have!
let portfoliosNavigationController = UINavigationController(rootViewController: PortfoliosTableViewController())
wireframe.show(viewController: portfoliosNavigationController)
default:
return wireframe.promptFor(result.description, cancelAction: "OK", actions: [])
.map({ (_) -> AuthenticationResult in
result
}).asDriver(onErrorJustReturn: result)
}
})
现在,问题:
我的 flatMapLatest
期望 SharedSequence<DriverSharingStrategy, AuthenticationResult>
而我并不总是 return!
在闭包内部,我可以 return SharedSequence<DriverSharingStrategy, AuthenticationResult>
如果身份验证成功 ,因为我的 wireframe.promptFor
return 是一个可观察对象.
但是,当身份验证失败 时,我没有return 的可观察对象。我的 wireframe.show
方法没有 return 任何东西。
我该如何处理这种情况?
谢谢
假设 switch case .granted
是认证成功,你可以简单地 return Observable.empty()
或 Driver.empty()
.
那有什么作用?
通过在 flatMap
操作中 return 一个空的驱动程序序列,您的意思是结束可观察序列。流将收到 onCompleted
事件,您可以将其理解为 流或操作成功。
您的以下代码将在 drive()
方法的 onCompleted
闭包中找到。
// Your observable stream / driver sequence
.drive(onCompleted: { [unowned wireframe] in
let portfoliosNavigationController = UINavigationController(rootViewController: PortfoliosTableViewController())
wireframe.show(viewController: portfoliosNavigationController)
}
应该可以。
RxCocoa Driver
单元
通过使用 Driver unit,您是说您期望可观察序列具有以下特征:
- 不能出错
- 观察主调度程序
- 分享副作用(shareReplayLatestWhileConnected)
这在执行 UI 相关的事情时通常很有用(比如你想做的是显示导航控制器)。如果是这种情况,请继续使用驱动程序。
但是如果我的流可能遇到错误怎么办?
如果有机会你需要 return 到一个可观察的序列,这样你就可以出错(因为你要执行一个可能出错的可观察操作,或者因为你想抛出一个错误停止操作),然后您可以在 Driver
实例上使用 toObservable()
操作。
不过要小心,因为你失去了你将在主线程上 运行 的断言(你需要它来显示视图控制器)。