/// A Flow defines a clear navigation area. Combined to a Step it leads to a navigation action
public protocol Flow: class, Presentable, Synchronizable {
/// the Presentable on which rely the navigation inside this Flow. This method must always give the same instance
var root: Presentable { get }
/// Resolves FlowContributors according to the Step, in the context of this very Flow
///
/// - Parameters:
/// - step: the Step emitted by one of the Steppers declared in the Flow
/// - Returns: the FlowContributors matching the Step. These FlowContributors determines the next navigation steps (Presentables to display / Steppers to listen)
func navigate (to step: Step) -> FlowContributors
}
在其 extension 中,flowReadySubject 返回是否可以执行 Flow,并包装成 Single 命名为 rxFlowReady。
FlowContributor
提供 Flow 的抽象,可以做到派发 Flow
/// A FlowContributor describes the next thing that will contribute to a Flow.
///
/// - contribute: the given stepper will emit steps (according to lifecycle of the given presentable) that will contribute to the current Flow
/// - forwardToCurrentFlow: the given step will be forwarded to the current flow
/// - forwardToParentFlow: the given step will be forwarded to the parent flow
public enum FlowContributor {
/// the given stepper will emit steps, according to lifecycle of the given presentable, that will contribute to the current Flow
case contribute(withNextPresentable: Presentable, withNextStepper: Stepper)
/// the "withStep" step will be forwarded to the current flow
case forwardToCurrentFlow(withStep: Step)
/// the "withStep" step will be forwarded to the parent flow
case forwardToParentFlow(withStep: Step)
/// Shortcut static func that returns a .contribute(withNextPresentable: _, withNextStepper: _)
/// in case we have a single actor that is a Presentable and also a Stepper
///
/// - Parameter nextPresentableAndStepper
/// - Returns: .contribute(withNextPresentable: withNext, withNextStepper: withNext)
public static func contribute(withNext nextPresentableAndStepper: Presentable & Stepper) -> FlowContributor {
return .contribute(withNextPresentable: nextPresentableAndStepper, withNextStepper: nextPresentableAndStepper)
}
}
FlowCoordinator
RxFlow 的核心实现,协调处理 Flow 的流转,通过 coordinate 的 API 执行 Flow
Stepper
public protocol Stepper {
/// the relay used to emit steps inside this Stepper
var steps: PublishRelay<Step> { get }
/// the initial step that will be emitted when listening to this Stepper
var initialStep: Step { get }
/// function called when stepper is listened by the FlowCoordinator
func readyToEmitSteps ()
}
默认是 NoneStep,readyToEmitSteps 是空实现
OneStepper
一个简单的 step,大部分场景可以直接使用
DefaultStepper
默认是 RxFlowStep.home
CompositeStepper
复杂场景下的 Step,合并多个 step,把初始 step 和下一个 step 关联起来
public func readyToEmitSteps() {
let initialSteps = Observable<Step>.from(self.innerSteppers.map { $0.initialStep })
let nextSteps = Observable<Step>
.merge(self.innerSteppers.map { $0.steps.asObservable() })
initialSteps
.concat(nextSteps)
.bind(to: self.steps)
.disposed(by: self.disposeBag)
}
RxFlow
借用官方的描述来说,RxFlow 是一个基于反应流协调器模式的 iOS 应用程序导航框架。
Flow
导航的抽象,负责持有 root 和执行 navigate 操作
在其 extension 中,flowReadySubject 返回是否可以执行 Flow,并包装成 Single 命名为 rxFlowReady。
FlowContributor
提供 Flow 的抽象,可以做到派发 Flow
FlowCoordinator
RxFlow 的核心实现,协调处理 Flow 的流转,通过
coordinate
的 API 执行 FlowStepper
默认是 NoneStep,readyToEmitSteps 是空实现
OneStepper
一个简单的 step,大部分场景可以直接使用
DefaultStepper
默认是 RxFlowStep.home
CompositeStepper
复杂场景下的 Step,合并多个 step,把初始 step 和下一个 step 关联起来
NoneStepper
不触发任何 step
Usage
根据业务生命周期,遵循 Flow 协议构造对应的 Flow,比如 APP 生命周期的 APPFlow,登录相关的 LoginFLow,设置的 SettingFLow 等。
多个 Flow 共享一个或多个 Step (具体看业务场景,独立业务内部可以自由约定) 约定,对外约定 GlobalStep,业务模块化粒度适中,尽量保证一个业务只有一个 GlobalStep 便于维护。
具体使用可以参考 RxFlowDemo 示例
执行 Step 的两种方式:
处理原则
接口
LingoFlowAvailable
缺陷
参考文档