RxSwift及衍生库的选择 - ShenYj/ShenYj.github.io GitHub Wiki
-
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 中将
RxRelay
从RxCocoa
剥离出来 -
RxTest
(单元测试)
提供对流生成过程的精确控制(TestScheduler 提供的能力). 因为在 RxSwift 中, 通过 Scheduler 来抽象和描述任务的执行方式, 以及调度任务执行结果(即发射的事件). -
RxBlocking
(单元测试)
允许用户将当前线程阻塞(使用 toBlocking())以获取一段时间内的所有事件, 这样在最后可以进行同步测试. 它适用于有限序列, 即会出现终止事件的序列.
-
RxSwift
-
网络
-
只负责网络请求
AF + RxAlamofire
直接 RxAlamofire 的一层Rx 扩展使用,没任何封装,其他的反序列化啥的不考虑
-
在请求基础上增加一层抽象层
AF + Moya/RxSwift
如果你使用 CocoaPods 管理依赖库,Moya 通过 subspec 直接做了 RxSwift 支持
多了一层抽象层 -
网络请求 + 抽象层 + 反序列化
AF + Moya/RxSwift + ObjectMapper(Rx)
AF + Moya/RxSwift + HandyJSON(Rx)
反序列化方案主要有:
ObjectMapper
、HandyJSON
、SwiftJSON
- 不是很推荐直接去用
Codeable
,除非业务场景足够简单,但实际项目伴随后期迭代,接口的标准很难把控 - 我一直使用
ObjectMapper
的方案,SwiftJSON
来解决一些小的应用场景,HandyJSON
这个库从日常 issues 来看并不推荐,每逢beta必尴尬,不过他的实现原理还是很牛逼的 -
ObjectMapper
在使用 RxSwift早期版本时,是有一个不错的 RxSwift 扩展的,但是停止维护了,目前是本地修改了源码的方式来适配到最新的RxSwift 6
作为 Rx的 Extension 来维护的另外也有一些 fork 的版本,比如
SwiftHub
目前在用的 p-rob/Moya-ObjectMapper
-
网络状态的监听
-
RxReachability
由RxSwift Community
提供基于ReachabilitySwift
的 Rx 扩展库
-
之所以单独将网络拆分出来
- 我觉得网络层需要考虑的信息起始还是挺多的,比如基本的网络请求、签名、Token处理、反序列化等,这一层的封装可能有不同的技术方案组合、设计。
- 可能会用到不同来源的库,有 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
操作符
- RxSwiftExt 的
这样也会对新手造成困扰,一上来面对着如此之多的库、操作符,信息爆炸
如果你是Rx新手,看到了我这篇笔记,那么在对比了解了核心库与衍生库的各自职能后,比如这两个衍生库,打开对应的仓库地址(也可以是其他人总结的操作符汇总),按需查找 - 比如对于一个可选值的处理,我可以借助三个库的不同操作符完成处理
-
NSObject+Rx
这是一个基于 OCNSObject
的扩展,通过运行时关联对象为每一个继承自NSObject
的实例提供了一个disposeBag
(垃圾袋),提高开发中的效率,代价就是需要继承自NSObject
这个库与
Moya
是同一位作者,我也是通过这个库的PR,被邀请进了 RxSwift Community -
RxDataSources
如今 App 界面几乎离不开列表,如果你的 UI 足够简单,你可能还用不到这个库,当你的页面分组情况较为复杂时,RxDataSources
是个不错的选择,除了对UITableView
扩展外,还包括UICollectionView
和UIPickerView
但目前为止,我还没有找到一个
自定义Section Header
与Rx
很好的结合方式-
关于
RxDataSources
的使用,SwiftHub 设置界面的实现是个不错的示范另外关于列表的刷新控件,结合我的实际经验,
SwiftHub
中使用了KafkaRefresh
,个人感觉并不好用,纯 Swift的库ESPullRefresh
不够优秀,还存在 bug,所以最强刷新框架仍是MJRefresh
-
-
RxGesture
对手势的扩展 -
RxAnimated
为我们 UI 绑定时提供了一些基本的动画效果 -
RxWebKit
对WKWebView
的扩展 -
RxCoreLocation
对CoreLocation
的扩展 -
RxBinding
使用 RxSwift 非必要的一个衍生库,但是又能让你的代码增光添色的库,主要是提供了绑定、双向绑定的操作符 -
RxRealm
在 Swift 下我使用过的数据库有:fmdb
、SQLite.swift
、Realm
但后面两次 RxSwift 项目中暂时未用到数据库,因此目前还没有对RxRealm
进行过实践,这也将会是我后续需求的优先选择方案也提供了基于
firebase
、SQLite
的扩展,可以自行查找,有关数据的扩展,不再进行列举 -
RxKingfisher
见名知意,Kingfisher
的扩展 -
RxFlow
这是一个我还未曾探索的衍生库,相对于其他的部分衍生库 star 量还不错 -
RxLocalizer
为本地化提供的一个扩展目前 Swift 项目我们最低兼容到 11.0, 但需要注意,此库最低要求 12.0 起步
-
- RxAlertViewable 是为使用 RxSwift 开发 MVVM 应用程序而创建的。它支持使用信号 Observable 显示来自视图模型类的简单的 Alert
- 不过示例中的样式很难满足实际需求,项目中我没有使用过,对于没有太多界面要求的简单提示,我倾向于使用
RxUIAlert
- 不过示例中的样式很难满足实际需求,项目中我没有使用过,对于没有太多界面要求的简单提示,我倾向于使用
-
RxUIAlert
是对UIAlertController
的轻量级扩展
- RxAlertViewable 是为使用 RxSwift 开发 MVVM 应用程序而创建的。它支持使用信号 Observable 显示来自视图模型类的简单的 Alert
-
Action
在 observables 之上提供一个抽象:actions
Actions 接受一个 workFactory:一个闭包,它接受一些输入并产生一个 observable。当在 action 上调用 execute() 时,workFactory 被传递了这个参数,并且 action 订阅了返回的 observable -
RxNimble、RxTestExt
单元测试用的, Swift 上的单元测试方案我倾向于使用Quick + Nimble
-
Nimble
也是做了 subspec 支持的,可以直接这样来完成依赖pod 'RxNimble', subspecs: ['RxBlocking', 'RxTest']
-
RxSwift Community
中还有其他衍生库,不过上面罗列的信息已经足够支撑你完成一个基于 RxSwift 的 MVVM 项目,甚至某些你可能还用不上;
也存在一些已经停止维护、甚至是废弃的库,比如RxMediaPicker
和RxAVFoundation
现在就处于没有维护的状态,PR没有及时的处理,在使用这两个库的时候,我是本地修改了源码作为 Extension 来使用的。 -
-
衍生库 (非
RxSwift Community
提供)-
RxViewController
对UIViewController
和NSViewController
的生命周期进行了扩展,方便我们在 Rx下使用 -
RxAppState
对UIApplication
进行了一些扩展,比如是否是首次启动,当前应用的运行状态处于前台还是后台等RxAppState
与RxViewController
存在一定重叠,在同一个类中不要同时使用
-