CocoaPods trunk is moving to be read-only. Read more on the blog, there are 18 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.