ReactiveSprint (RSP) 是一个框架,它提供了用于开发带有 模型-视图-视图模型 (MVVM) 应用程序 的 API。
ReactiveSprint 将适用于不同的平台(Cocoa、Android、Windows 等)以统一每个平台的工程结构并加快开发过程。
ReactiveSprint 面向 Swift 2.2
,ReactiveCocoa 4。
ReactiveSprint 提供了常见 ViewModels 和 Views 的抽象实现。
假设我们需要显示用户帖子列表。我们想要一个 ViewModel 来获取这些帖子列表,以及一个 TableViewController 来显示它们。使用 ReactiveSprint,我们只需要实现表示每个文章单元格的 UITableViewCell
以及相应的 ViewModel
。
这里是我们通常需要的内容(在 MVVM 中)
Post
模型PostViewModel
对每个行PostsViewModel
用于获取帖子、处理刷新、维护 PostViewModel
实例数组等。PostTableViewCell。
UITableViewDataSource。
PostsTableViewController
。为我们的 Post
模型实现 AnyModel 协议。
struct Post: AnyModel {
//Add Posts` properties
var caption: MutableProperty<String>
}
我们可以从 ModelViewModel 子类来实现 PostViewModel
,用于每个表格视图单元格。
class PostViewModel: ModelViewModel<Post> {
// Expose properties from `Post` which will be used in PostTableViewCell
var caption: AnyProperty<String>
override init(_ model: Post) {
super.init(model)
caption = AnyProperty(model.caption)
}
}
我们还需要实现一个 ViewModel 来获取帖子,维护 PostViewModel 实例数组,处理刷新,可能还需要处理分页。
我们可以从 FetchedArrayViewModel 子类化,或者初始化一个实例
let postsViewModel = FetchedArrayViewModel { page -> SignalProducer<(Int?, [PostViewModel]), NSError> in
// requests posts for `page`
return ApiClient.requestPosts(page)
}
这样我们就得到了一个支持获取、刷新和分页帖子 ViewModel。
ApiClient.requestPosts(:_)
函数接收一个 Int
类型的参数,表示要请求的页面,并返回一个 SignalProducer,该 producer 发送一个包含 PostViewModel
和 Int
的数组,这些数据将用于请求下一页。
FetchedArrayViewModel
包含刷新和获取下一页使用的 ReactiveCocoa.Action 实例。
我们可以通过继承 RSPTableViewCell 来实现 PostTableViewcell
,并重写 bindViewModel(_:)
方法来将 ViewModel 的属性绑定到我们的单元格中。
class PostTableViewcell: RSPTableViewCell {
@IBOutlet var captionLabel: UILabel!
override bindViewModel(viewModel: ViewModelType) {
precondition(viewModel is PostViewModel)
super.bindViewModel(viewModel)
let postViewModel = viewModel as! PostViewModel
postViewModel.caption.producer
.takeUntil(rac_prepareForReuseSignalProducer)
.startWithNext { [unowned self] text in
self.captionLabel.text = text
}
}
}
我们可以继承或初始化 RSPTableViewDataSource 来实现一个使用 postsViewModel
的 UITableViewDataSource
。
let postsDataSource = RSPTableViewDataSource(arrayViewModel: arrayViewModel)
RSPTableViewDataSource
使用 arrayViewModel.count
作为行数。它会从池中使用标识符为 ViewModelIdentifier 的单元格,并为每个单元格设置一个 PostViewModel
实例。
我们可以通过继承 RSPUIFetchedTableViewController 来实现作为 UITableViewController
子类的 PostsTableViewController
。或者 RSPFetchedTableViewController 来创建一个自定义的 UIViewController
,其中包含 UITableView
。
class PostsTableViewController: RSPUIFetchedTableViewController {
/// self.viewModel should be set with instance of
/// `PostsViewModel` some time before `viewDidLoad()`
override viewDidLoad() {
super.viewDidLoad()
// Register `PostTableViewCell` for `ViewModelIdentifier`
tableView.registerClass(PostTableViewcell.self, forCellReuseIdentifier: ViewModelIdentifier)
tableView.dataSource = RSPTableViewDataSource(arrayViewModel: arrayViewModel)
}
}
这就是实现具有刷新和分页功能的帖子表格所需的所有内容。我们只需专注于实现 PostTableViewCell
和其相关的 ViewModel PostViewModel
。
此项目目前正在开发中。但将会提供 CocoaPod,并支持 Carthage。
ReactiveSprint 在 MIT 许可协议下可用。有关更多信息,请参阅 LICENSE 文件。