RxSwift及衍生库的选择 - ShenYj/ShenYj.github.io GitHub Wiki

RxSwift 及衍生库的选择

  • RxSwift

    ┌──────────────┐    ┌──────────────┐
    │   RxCocoa    ├────▶   RxRelay    │
    └───────┬──────┘    └──────┬───────┘
            │                  │        
    ┌───────▼──────────────────▼───────┐
    │             RxSwift              │
    └───────▲──────────────────▲───────┘
            │                  │        
    ┌───────┴──────┐    ┌──────┴───────┐
    │    RxTest    │    │  RxBlocking  │
    └──────────────┘    └──────────────┘
    • RxSwift (核心库)
      RxSwift 的核心,提供了(大部分)由 ReactiveX 定义的 Rx 标准。它没有其他依赖项
    • RxCocoa (对于我们iOS、macOS平台来说也是核心库)
      为一般的 iOS/macOS/watchOS 和 tvOS 应用程序开发提供 Cocoa 特定的功能,例如共享序列、特征等等。它依赖于 RxSwift 和 RxRelay。
    • RxRelay (核心库)
      RxRelay 是一个在 Subjects 之上很好的抽象层。它可以让我们发出元素,而不用担心 error 和 completed 这样的终止事件。由于它们被添加到 RxSwift 中,并且是 RxCocoa 项目的一部分。
      许多开发者对此很不乐意。因为他们如果要使用 Relays 就必须引入 RxCocoa,即便他们编写的代码与 RxCocoa 没有任何关系。这其实是很不合理的。并且这样一来 Linux 用户就无法使用 Relays,因为 Linux 无法导入 RxCocoa。

      因此在 RxSwift 5 中将 RxRelayRxCocoa 剥离出来

    • RxTest (单元测试)
      提供对流生成过程的精确控制(TestScheduler 提供的能力). 因为在 RxSwift 中, 通过 Scheduler 来抽象和描述任务的执行方式, 以及调度任务执行结果(即发射的事件).
    • RxBlocking (单元测试)
      允许用户将当前线程阻塞(使用 toBlocking())以获取一段时间内的所有事件, 这样在最后可以进行同步测试. 它适用于有限序列, 即会出现终止事件的序列.
  • 网络

    • 只负责网络请求

      • AF + RxAlamofire

      直接 RxAlamofire 的一层Rx 扩展使用,没任何封装,其他的反序列化啥的不考虑

    • 在请求基础上增加一层抽象层

      • AF + Moya/RxSwift

      如果你使用 CocoaPods 管理依赖库,Moya 通过 subspec 直接做了 RxSwift 支持
      多了一层抽象层

    • 网络请求 + 抽象层 + 反序列化

      • AF + Moya/RxSwift + ObjectMapper(Rx)
      • AF + Moya/RxSwift + HandyJSON(Rx)

      反序列化方案主要有: ObjectMapperHandyJSONSwiftJSON

      1. 不是很推荐直接去用 Codeable,除非业务场景足够简单,但实际项目伴随后期迭代,接口的标准很难把控
      2. 我一直使用 ObjectMapper 的方案, SwiftJSON 来解决一些小的应用场景, HandyJSON 这个库从日常 issues 来看并不推荐,每逢beta必尴尬,不过他的实现原理还是很牛逼的
      3. ObjectMapper 在使用 RxSwift早期版本时,是有一个不错的 RxSwift 扩展的,但是停止维护了,目前是本地修改了源码的方式来适配到最新的 RxSwift 6 作为 Rx的 Extension 来维护的

        另外也有一些 fork 的版本,比如 SwiftHub 目前在用的 p-rob/Moya-ObjectMapper

    • 网络状态的监听

      • RxReachability
        RxSwift Community 提供基于 ReachabilitySwift 的 Rx 扩展库

    之所以单独将网络拆分出来

    1. 我觉得网络层需要考虑的信息起始还是挺多的,比如基本的网络请求、签名、Token处理、反序列化等,这一层的封装可能有不同的技术方案组合、设计。
    2. 可能会用到不同来源的库,有 RxSwift Community 提供的,也有个人、其他组织提供的
  • 衍生库 (RxSwift Community)

    RxSwift Community 提供了大量的 RxSwift 衍生库, 也包括 RxSwift 作者提供的衍生库

    • RxOptional
      为可选值类型、空值的处理,以及去重的一些处理,比如常用到的操作符

      • filterNil 过滤掉nil的元素,返回其余元素
      • replaceNilWith 将nil替换为某个值
      • catchOnNil 当catch到nil时需要做什么处理,比如在网络返回时会很有用
      • filterEmpty 过滤掉空的元素
      • distinctUntilChanged 阻止 Observable 发出相同的元素,过滤掉连续相同的元素

        区别于 RxSwiftExt 的元素去重操作符 distinct

    • RxSwiftExt
      为 RxSwift 提供了更多操作符

      • 比如对于一个可选值的处理,我可以借助三个库的不同操作符完成处理
        • RxSwiftExt 的 unwrap 操作符
        • RxOptional 的 filterNil 操作符
        • RxSwift 的 compactMap 操作符

      这样也会对新手造成困扰,一上来面对着如此之多的库、操作符,信息爆炸
      如果你是Rx新手,看到了我这篇笔记,那么在对比了解了核心库与衍生库的各自职能后,比如这两个衍生库,打开对应的仓库地址(也可以是其他人总结的操作符汇总),按需查找

    • NSObject+Rx
      这是一个基于 OC NSObject 的扩展,通过运行时关联对象为每一个继承自 NSObject 的实例提供了一个disposeBag (垃圾袋),提高开发中的效率,代价就是需要继承自 NSObject

      这个库与 Moya 是同一位作者,我也是通过这个库的PR,被邀请进了 RxSwift Community

    • RxDataSources
      如今 App 界面几乎离不开列表,如果你的 UI 足够简单,你可能还用不到这个库,当你的页面分组情况较为复杂时,RxDataSources 是个不错的选择,除了对UITableView扩展外,还包括 UICollectionViewUIPickerView

      但目前为止,我还没有找到一个 自定义Section HeaderRx 很好的结合方式

      • 关于 RxDataSources 的使用,SwiftHub 设置界面的实现是个不错的示范

        另外关于列表的刷新控件,结合我的实际经验,SwiftHub中使用了 KafkaRefresh,个人感觉并不好用,纯 Swift的库 ESPullRefresh 不够优秀,还存在 bug,所以最强刷新框架仍是 MJRefresh

    • RxGesture
      对手势的扩展

    • RxAnimated
      为我们 UI 绑定时提供了一些基本的动画效果

    • RxWebKit
      WKWebView 的扩展

    • RxCoreLocation
      CoreLocation 的扩展

    • RxBinding
      使用 RxSwift 非必要的一个衍生库,但是又能让你的代码增光添色的库,主要是提供了绑定、双向绑定的操作符

    • RxRealm
      在 Swift 下我使用过的数据库有: fmdbSQLite.swiftRealm
      但后面两次 RxSwift 项目中暂时未用到数据库,因此目前还没有对 RxRealm 进行过实践,这也将会是我后续需求的优先选择方案

      也提供了基于 firebaseSQLite 的扩展,可以自行查找,有关数据的扩展,不再进行列举

    • RxKingfisher
      见名知意,Kingfisher 的扩展

    • RxTheme
      一个不错的基于 Rx 的响应式换肤方案,SwiftHub 中有运用

    • RxFlow
      这是一个我还未曾探索的衍生库,相对于其他的部分衍生库 star 量还不错

    • RxLocalizer
      为本地化提供的一个扩展

      目前 Swift 项目我们最低兼容到 11.0, 但需要注意,此库最低要求 12.0 起步

    • RxUIAlertRxAlertViewable

      • RxAlertViewable 是为使用 RxSwift 开发 MVVM 应用程序而创建的。它支持使用信号 Observable 显示来自视图模型类的简单的 Alert
        • 不过示例中的样式很难满足实际需求,项目中我没有使用过,对于没有太多界面要求的简单提示,我倾向于使用 RxUIAlert
      • RxUIAlert 是对 UIAlertController 的轻量级扩展
    • Action
      在 observables 之上提供一个抽象:actions
      Actions 接受一个 workFactory:一个闭包,它接受一些输入并产生一个 observable。当在 action 上调用 execute() 时,workFactory 被传递了这个参数,并且 action 订阅了返回的 observable

    • RxNimbleRxTestExt
      单元测试用的, Swift 上的单元测试方案我倾向于使用 Quick + Nimble

      • Nimble 也是做了 subspec 支持的,可以直接这样来完成依赖

        pod 'RxNimble', subspecs: ['RxBlocking', 'RxTest']

    RxSwift Community 中还有其他衍生库,不过上面罗列的信息已经足够支撑你完成一个基于 RxSwift 的 MVVM 项目,甚至某些你可能还用不上;
    也存在一些已经停止维护、甚至是废弃的库,比如 RxMediaPickerRxAVFoundation 现在就处于没有维护的状态,PR没有及时的处理,在使用这两个库的时候,我是本地修改了源码作为 Extension 来使用的。

  • 衍生库 (非 RxSwift Community 提供)

    • RxViewController
      UIViewControllerNSViewController 的生命周期进行了扩展,方便我们在 Rx下使用

    • RxAppState
      UIApplication 进行了一些扩展,比如是否是首次启动,当前应用的运行状态处于前台还是后台等

      RxAppStateRxViewController 存在一定重叠,在同一个类中不要同时使用

⚠️ **GitHub.com Fallback** ⚠️