CocoaPods trunk is moving to be read-only. Read more on the blog, there are 9 months to go.
| TestsTested | ✓ |
| LangLanguage | SwiftSwift |
| License | MIT |
| ReleasedLast Release | Apr 2016 |
| SPMSupports SPM | ✗ |
Maintained by Ahmad Baraka.
ReactiveSprint (RSP) is a framework which provides API for developing apps with Model-View-ViewModel (MVVM).
ReactiveSprint will be available for different platforms (Cocoa, Android, Windows.. etc) to unify the structure of projects for each platform and speedup the development process.
ReactiveSprint targets Swift 2.2, ReactiveCocoa 4.
ReactiveSprint provides abstract implementation of common ViewModels and Views.
Let’s say we need to display a list of posts for users. We want to have a ViewModel which fetches that list of posts, and a TableViewController that displays them. With ReactiveSprint we only need to implment UITableViewCell that represents each Post cell, and a ViewModel for it.
Here’s what we typically need (In MVVM):
Post ModelPostViewModel for each row.PostsViewModel for fetching posts, handling refresh, maintaining an array of PostViewModel instaces.. etc.PostTableViewCell.UITableViewDataSource.PostsTableViewController. Implement AnyModel protocol for our Post model.
struct Post: AnyModel {
//Add Posts` properties
var caption: MutableProperty<String>
}We can subclass ModelViewModel to implement PostViewModel which will be used for each table view cell.
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)
}
}We also need to implement a ViewModel which fetches posts, maintains an Array of PostViewModel instances, handles refresh and possibly handle pagination too.
We can either subclass FetchedArrayViewModel or initialize an instance:
let postsViewModel = FetchedArrayViewModel { page -> SignalProducer<(Int?, [PostViewModel]), NSError> in
// requests posts for `page`
return ApiClient.requestPosts(page)
}This gives us a ViewModel which supports fetching, refreshing and pagination of posts.
ApiClient.requestPosts(:_) takes an Int input as the page to be requested, and returns a SignalProducer which sends an array of PostViewModel and Int which will be used for requesting next page.
FetchedArrayViewModel has ReactiveCocoa.Action instances for refreshing, and fetching next pages.
We can subclass RSPTableViewCell to implement PostTableViewcell and override bindViewModel(_:) to bind our ViewModel’s properties to our cells.
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
}
}
}We can subclass or initialize RSPTableViewDataSource to implement a UITableViewDataSource which uses postsViewModel.
let postsDataSource = RSPTableViewDataSource(arrayViewModel: arrayViewModel)RSPTableViewDataSource uses arrayViewModel.count as count of rows. And dequeues a cell with identifier ViewModelIdentifier and sets an instance of PostViewModel for each cell.
We can subclass RSPUIFetchedTableViewController to implement PostsTableViewController as a subclass of UITableViewController. Or RSPFetchedTableViewController for a custom UIViewController with a 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)
}
}This is all we need to do to implement a table view of posts with refreshing, and pagination. We only focus on implementing PostTableViewCell and its relative ViewModel PostViewModel.
This project is currently under development. But a CocoaPod will be available. And Carthage will be supported as well.
ReactiveSprint is available under the MIT license. See the LICENSE file for more info.