RxFlow第3部分:提示和技巧

RxFlow是基于Reactive Flow Coordinator模式的iOS应用程序导航框架。 该项目是RxSwiftCommunity组织的一部分。

这三篇文章对它的详细概念进行了解释:

  • RxFlow第1部分:理论上
  • RxFlow第2部分:实践中
  • RxFlow第3部分:提示和技巧

这是Github存储库:https://github.com/RxSwiftCommunity/RxFlow

感谢您的反馈,随时可以贡献contribute

让我们深入探讨我在响应式编程方面遇到的一些技巧和窍门。

UIViewControllers使反应

正如我们在第2部分中所看到的,我们需要在某个时候以响应方式知道何时显示一个Presentable 。 一个可呈现对象公开了3个可观察对象:

RxFlow中 ,UIViewController符合此协议,因此我们必须找到一种使它们具有反应性的方法。

希望在此过程中发现的一个很棒的项目在此方面起到了很大的帮助:RxViewController。

通过应用我在这篇文章中描述的模式,它为UIViewControllers提供了Reactive扩展:Swift中的Verstatile命名空间。 此外,它使用RxCocoa内置函数可以观察选择器调用。 一旦理解了这一概念,便对UIViewController进行了自己的扩展。

作为记录,这就是协调器的用法,其中“ nextPresentable”是由Flow上的“ navigation (to 🙂 ”函数生成的Presentable 。 在关联的Presentable第一次显示之后,我们仅听下一个Stepper

让我们暂停一下

RxFlow中的另一个关键原理是: 流中发生的事情,留在流中 。 因此,如果Flow不再位于视图层次结构的顶部,我必须找到一种方法来“暂停” Steps的订阅。

RxSwift不提供“开箱即用”的方式来暂停订阅,但RxSwiftExt可以。 这是来自RxSwiftCommunity的项目。 它为RxSwift添加了许多新的运算符,例如“ pausable”。

除非第二个可观察序列中的最新元素为true,否则它将暂停源可观察序列的元素。

让我们看一下实现。

实际上,这只是3个RxSwift内置运算符的组合:

  • withLatestFrom:与由主要Observable触发的值相关联,该值是另一个称为“ pauser”的Observable的最后一个值(驱动暂停的那个值)
  • 过滤器:仅接受“ pauser”中可观察到的值为true的值
  • 映射:忽略制表符的Observable值,以便仅返回的值是主Observable的值

再次,这是协调器使用的方式:

这很容易理解:当“ rxVisible”的Observable值为false时,nextStepper的步骤将暂停。

具有存储属性的协议?

作为面向协议的框架, RxFlow希望开发人员实现多种协议。 当您建立这种框架时,您不希望用户为实现那些协议而必须实现的过多功能或特性感到困扰。

功能不是问题,因为您可以提供带有协议扩展的默认实现。 但是属性是一个问题,因为Swift不允许将它们存储在这样的扩展中。

例如,当您实现步进器协议时,会为您提供“ step ”属性,该属性允许触发新的Step值。 我是怎么做到的?

同样,RxSwiftCommunity在这里有很大的帮助。 我受到NSObject-Rx的启发。 该项目提出了对NSObject的扩展,该扩展存储了RxSwift DisposeBag。 目的是为每个扩展NSObject的类(尤其是UIViewControllers)提供默认的DisposeBag。 正是我需要的,但是在协议扩展中。 这是Stepper的代码。

所有的魔术都发生在“ step ”计算属性中。 我们使用“ objc_setAssociatedObject”函数来存储对BehaviorSuject的引用(请参阅此NSHipster文章)。 每次访问此属性时,我们都会检索此存储的引用(在第一次调用时,将创建BehaviorSubject并将其与subjectContext引用关联)。

这个技巧有一个缺点。 值类型(例如Structs)可以采用协议,这意味着内存是在堆栈中处理的,而不是在堆中处理(如引用类型)。 因此,Struct实例的生命周期和可重用性由Swift运行时处理。 当运行时将重用实例时,不确定“ objc_getAssociatedObject”关联值会发生什么。 为了安全起见,应仅将此类协议约束为仅由类实现,这将确保所有事情都在堆中发生。

还给社区

如您所见,RxFlow中的一些关键功能基于开发人员社区所做的工作。 当您自己开源项目时,必须考虑以下几点:您将需要帮助! 我认为这对于将其还给社区非常重要。

在RxFlow的情况下,我有机会打开已合并的2个PR:

  • 修复HasDisposeBag协议
  • 为显示和关闭状态添加新的可观察物

很高兴知道我的代码可以帮助其他开发人员。

结论

使我的第一个开放源码项目可用一直是一个很大的挑战。 这并非想象中那么容易,因为您必须:

  • 收集并综合所有导致您进入项目的想法(来自先前项目的想法,遇到的问题和解决方案,…)。 所以放轻松,在编码任何东西之前都要考虑一下🙂
  • 尝试根据项目的复杂性选择合适的模式,不要过度设计工作
  • 认为您好像将使用代码的人一样,请使其尽可能简单(这是最难的事情)
  • 写一个好的自述文件,因为代码不足以使您的项目更具吸引力
  • 对您的资源管理要专业。 没有人愿意为看似丑陋的项目做贡献(git CLI是您最好的朋友)
  • 尝试写博客文章来分享您的工作,您将获得聪明人的反馈
  • 保持信念,您会不时灰心。 因此,如果您不知所措,请稍事休息,洗脑,然后想法会回来。

RxFlow已发布在CocoaPods和Cartage的1.0.1版本中。 我现在将在新的副项目中使用它,我将在接下来的几篇文章中讨论它!

RxFlow Github存储库:https://github.com/RxSwiftCommunity/RxFlow

希望您喜欢有关反应流协调器的阅读文章。 如果您对RxFlow有任何疑问或意见,请随时与我联系。