测试已测试 | ✓ |
语言语言 | SwiftSwift |
许可 | MIT |
发布最后发布 | 2016年5月 |
SPM支持 SPM | ✗ |
由 Sergey Gavrilyuk 维护。
依赖 | |
结果 | ~> 2.0 |
ReactiveCocoa | ~> 4.1 |
基于 RAC
的轻量级通用 ViewModel,用于处理项目分页列表(通常但不一定是通过 REST API 异步检索到的分页)
PaginatedListViewModel
的使用快速示例
创建依赖
struct SamplePaginatedListViewModelDependency: PaginatedListViewModelDependency {
typealias ListItemType = String
func intialPageSignal() -> SignalProducer<RecusrsivePageSignalPayload<ListItemType>, NSError> {
let count = 10
func makeNextPageSignal(skip: Int) -> SignalProducer<RecusrsivePageSignalPayload<ListItemType>, NSError> {
return SignalProducer() {
sink, _ in
// make page a list of Ints turned into String
let page = (skip...(skip + count)).map{ "\($0)"}
let payload = RecusrsivePageSignalPayload(
currentPage: page,
nextPageSignal: makeNextPageSignal(skip + count)
)
sink.sendNext(payload)
sink.sendCompleted()
}
}
return makeNextPageSignal(0)
}
}
创建 ViewModel
实例
let dependency = SamplePaginatedListViewModelDependency()
let paginatedList = PaginatedListViewModel(dependency: dependency)
观察 viewModel 的 items
属性
paginatedList.items.producer.startWithNext { items in
NSLog("Whole list is now \(items)")
}
通过与 ViewModel 交互开始加载
paginatedList.loadNextPage()
现在,每次您调用 loadNextPage
时,viewModel 将请求它的依赖关系以请求新页面(通常是通过 RAC
的信号,但不一定是),这将触发代码生成和发送新的页面。关于这一机制,下面将详细介绍。
PaginatedListViewModel
完全基于 RAC4 构建。它依赖于 SignalProducer
作为输入,并以 RAC 的 AnyProperty
形式输出信息。
PaginatedListViewModel
使用依赖注入来抽象页面构造的某些特定细节。其工作职责是管理列表的一致性以及支持正确的列表状态(包括 loading
和 lastError
属性,这些也是可观察的)。
为了进行分页,我们假设连接了请求下一页的信号。具体来说,我们以递归的方式链接它们,使用 RecusrsivePageSignalPayload
进行间接表示。这里的想法非常简单:每个表示页面加载的信号都会发送回一个数据包,实际上是一对对象:当前请求的页面以及表示后续页面请求的 SignalProducer。为了进行分页,PaginatedListViewModel
在接收到当前页面时捕获后续页面的 SignalProducer,并在下次调用 loadNextPage()
时启动该信号生产者,从而启动下一页的请求。
每次 PaginatedListViewModel
开始下一页的 SignalProducer 属性 loading
设置为 true,当该 SignalProducer 终止(无论成功还是失败)时,它被设置为 false。
当当前页面的请求失败时,表示该页面请求的 SignalProducer 不会被放弃。属性 lastError
设置为从该 SignalProducer 返回的任何错误。下次调用 loadNextPage
时,PaginatedListViewModel
将尝试启动上一次失败的同信号生产者。启动时,lastError
属性被重置为 nil。
正如所见,依赖项仅用于获取第一页的SignalProducer,因为后续页面的SignalProducer可以通过上一页面的请求获取。然而,当在PaginatedListViewModel
中调用reset
方法时,这个过程将被重新开始,下次调用loadNextPage
时,PaginatedListViewModel
将从提供的依赖项请求第一页的SignalProducer。
检出此存储库,将PaginatedListViewModel
文件夹复制到您的项目第三方依赖项文件夹中。然后拖动PaginatedListViewModel.xcodeproj
进入您的总项目中。不要忘记在您的总项目的Target依赖项构建阶段中添加PaginatedListViewModel
。
请参考以下示例集合中的示例项目,以获取其他基于ViewModel的µ-frameworks示例这里。
PaginatedListViewModel
由Sergey Gavrilyuk @octogavrix创建。
PaginatedListViewModel
采用MIT许可协议分发。请参阅LICENSE获取更多信息。