RxFlow第2部分:实践中
RxFlow是基于Reactive Flow Coordinator模式的iOS应用程序导航框架。 该项目是RxSwiftCommunity组织的一部分。
这三篇文章对它的详细概念进行了解释:
- RxFlow第1部分:理论上
- RxFlow第2部分:实践中
- RxFlow第3部分:提示和技巧
这是Github存储库:https://github.com/RxSwiftCommunity/RxFlow
感谢您的反馈,随时可以贡献contribute
综上所述, RxFlow旨在:
- 简化将导航切割为逻辑部分
- 从视图控制器中删除导航代码
- 鼓励视图控制器的可重用性
- 促进反应式编程
- 促进依赖注入
快速提醒您以下术语:
- Flow :每个Flow都定义了应用程序中的导航区域。
- 步骤 :每个步骤都是应用程序中的导航状态。 流程和步骤的组合描述了所有可能的导航操作。
- 步进器 :可以是任何可以发出步进的东西。 步进器将负责触发流中的每个导航动作
- 可表示的 :它是可以表示的东西的抽象,基本上UIViewController和Flow是可表示的
- NextFlowItem :它告诉协调器将在其响应式机制中产生新步骤的下一件事是什么
- 协调员 : 协调员的工作是以一致的方式混合流程和步骤的组合
同样重要的是要记住, RxFlow使用面向协议的编程,这样它才不会将代码冻结在继承层次结构中。
在RxFlow仓库中,您将找到一个演示应用程序。 它几乎显示了每种可能的导航类型:
- 导航堆栈
- 标签栏
- 掌握/细节
- 模态弹出
RxFlow主要是关于以反应方式处理导航状态更改。 为了在多个上下文中重用,这些状态必须不知道用户所处的当前导航流。因此,状态不是表示“我要转到此屏幕”,而是表示“某人或某件事已完成”。此操作”, RxFlow将根据当前导航流选择正确的屏幕。 使用RxFlow时 ,此导航状态称为步骤 。
枚举是描述步骤的好方法:
- 它们易于使用,
- 一个值只能定义一次(因此状态是唯一的)
- 使用它们是安全的,因为Swift希望您在switch语句中实现所有可能的值
- 他们可以嵌入将从一个屏幕提供给另一个屏幕的值
- 它们是值类型,因此不存在传播不受控制的共享引用
例如,在演示应用程序中,所有这些都是我们涵盖导航可能性所需的所有步骤 。
使用RxFlow ,所有导航代码(例如呈现或推送视图控制器)都在Flows中声明。 Flow表示应用程序中的逻辑导航部分,当与特定的Step组合时,它将触发一些导航动作。
为此, 流程必须实现:
- 一个“ navigation (to 🙂 ”功能,使导航动作根据流程和步骤进行
- 一个“ 根 ” UIViewController,它将基于此Flow中的导航
这是一个处理UINavigationController及其导航堆栈的Flow示例。 在此流程中 ,可以执行三个导航操作。
当我们学习函数式反应式编程时,我们经常会读到副作用 。 FRP的目的是传播事件并在整个过程中应用它们的功能。 这些功能可能会改变这些事件,并最终(但不是必须)执行将执行您想要的任何功能的代码(进行一些联网,保存文件,显示警报等):这些都是副作用 。
由于RxFlow依赖于反应式编程,因此我们可以轻松地识别固有的概念:
- 事件 :这些是发出的步骤
- 函数 :这是“ navigation(to 🙂 ”函数
- 转换 :“ navigation (to 🙂 ”功能将** Step **转换为NextFlowItem
- 副作用 :这些是在“ navigation (to 🙂 ”中执行的导航操作(例如,函数“ navigationToMovieListScreen () ”将新的UIViewController推入导航堆栈)
基本上, NextFlowItem是一个简单的数据结构,其中包含Presentable和Stepper 。
Presentable会告诉协调员您将要呈现的下一件事,而Stepper会告诉协调员接下来将要发出Steps的事物。
默认情况下,所有类型的UIViewControllers都是Presentable 。 流也是可表示的,因为有时您将要启动一个在其自己的Flow中描述的全新导航区域,因此RxFlow认为它可以呈现。
协调员为什么要了解Presentables ?
可表示性是可以表示的事物的抽象。 因为除非显示其关联的Presentable ,否则无法发射Step , Presentable提供协调者将订阅的Reactive可观察对象(因此它将知道Presentable的呈现状态)。 因此,在尚未完全显示其可演示对象时,没有引发步骤的风险。
Stepper可以是任何东西:自定义UIViewController,ViewModel,Presenter…在协调器中注册后, Stepper可以通过其“ step ”属性(RxSwift主题)发出Steps 。 协调员将监听这些步骤,并调用流程的 “ navigation(to 🙂 ”功能。
这是演示应用程序中Stepper的示例。
在此示例中,当用户在列表中选择电影时,将调用选择功能。 该函数在“ self.step” Rx流中发出一个新值。
总结一下导航过程:
- 导航(to 🙂函数以Step作为参数调用
- 根据此步骤 ,称为一些导航代码( 副作用 )
- 同样根据该步骤 ,产生NextFlowItems 。 因此, Presentables和Stepper已注册到协调器中
- 步进器发出新的步进 ,在这里我们再次走
因为什么也不允许应用程序一次具有多个导航。 例如,选项卡栏的每个项目都可以引至导航堆栈。 触发显示UITabbarController的步骤将在每个导航堆栈中生成NextFlowItem 。
您可以查看演示应用程序以了解其概念。 这是我们将UITabBarController与2个流连接的摘录(每个流描述与选项卡栏项关联的导航堆栈):
静态函数“ Flows.whenReady() ”将启动Flows ,并在准备好显示这些Flows时(即,在选择该Flow的第一个屏幕时)调用该Closure。
因为导航流程必须结束! 例如,导航堆栈的最后一个屏幕将不允许进一步的导航,而仅允许UINavigationController自身处理的后退操作。 在这种情况下, navigation (to 🙂函数将返回NextFlowItem.noNavigation 。
正如我们已经看到的,有可能同时浏览多个Flow 。 例如,导航堆栈中的屏幕可以启动弹出窗口,该弹出窗口也可以包含另一个导航堆栈。 从UIKit的角度来看,UIViewController层次结构非常重要,我们不能与Coordinator内部的层次结构搞混。
这就是为什么当当前未显示Flow时(在我们的示例中,当第一个导航堆栈位于弹出窗口下方时), Coordinator将忽略其中可能发出的步骤 。
从更一般的角度来看,仅在该流的上下文中解释在流的上下文中发出的步骤 (它们不能被其他流捕获)。
DI是RxFlow的主要目标之一。 基本上,依赖注入可以通过将某种实现(服务,管理器等)作为参数传递给初始化程序或方法来完成(也可以通过属性来完成)。
在RxFlow中 ,由于开发人员负责实例化UIViewControllers,ViewModels,Presenter等,因此这是注入所需内容的绝佳机会。 这是ViewModel中依赖项注入的示例。
现在您已经知道如何将事物组合在一起,混合流程和步骤以触发导航动作并产生NextFlowItems ,剩下要做的一件事:在应用程序启动时引导导航过程。
一切都在AppDelegate中发生,并且您会发现这非常简单:
- 实例化协调器
- 实例化要导航的第一个流程
- 要求协调员首先协调此流程
- 当第一个Flow准备好时,将其根设置为Window的rootViewController
这是在演示应用程序中完成的方法。
协调器有两个响应式扩展: willNavigate和didNavigate 。 例如,您可以在AppDelegate中订阅它们。
这将产生这种日志:
did navigate flow=RxFlowDemo.MainFlow step=apiKeyIsComplete
did navigate flow=RxFlowDemo.WishlistFlow step=movieList
did navigate flow=RxFlowDemo.WatchedFlow step=movieList
did navigate flow=RxFlowDemo.WishlistFlow step=moviePicked(23452) did navigate flow=RxFlowDemo.WishlistFlow step=castPicked(2)
did navigate flow=RxFlowDemo.WatchedFlow step=moviePicked(55423)
did navigate flow=RxFlowDemo.WatchedFlow step=castPicked(5)
did navigate flow=RxFlowDemo.WishlistFlow step=settings
did navigate flow=RxFlowDemo.SettingsFlow step=settings
did navigate flow=RxFlowDemo.SettingsFlow step=apiKey
did navigate flow=RxFlowDemo.SettingsFlow step=about
did navigate flow=RxFlowDemo.SettingsFlow step=apiKey
did navigate flow=RxFlowDemo.SettingsFlow step=settingsDone
对于分析和调试目的,它可能非常有帮助。
我希望您会发现此反应流协调器模式有趣且有用。 请随意贡献和挑战我的工作:GitHub上的RxFlow。
- 如何在iOS中修复“TIC SSL Trust Error”?
- iOS倒数计时器到特定date
- 用CoreAnimationanimation滚动UIScrollView
- iOS的UIScrollView / UITableView contentOffset重置pushViewControllerAnimated时:
- 如何创buildpinterest风格隐藏/取消隐藏导航/标签栏?
- 如何更改uiimage的button在快速点击图像?
- 错误:从不兼容的types“id”分配给“CLLocationCoordinate2D”
- 如何将AVAssetaudio从一个iOS设备无线传输到另一个?
- 在已发布/可用的iOS应用程序的Apple Store中更改应用程序名称