Table and collection view data sources for Combine
CombineDataSources provides custom Combine subscribers that act as table and collection view controllers and bind a stream of element collections to table or collection sections with cells.
⚠️⚠️⚠️ Note 🚨🚨🚨: The package is currently work in progress.
1.1 Bind a plain list of elements
1.2 Bind a list of Section models
1.2 Customize the list controller
2.2 Cocoapods
The repo contains a demo app in the Example sub-folder that demonstrates the different ways to use CombineDataSources in practice.
var data = PassthroughSubject()data .bind(subscriber: tableView.rowsSubscriber(cellIdentifier: "Cell", cellType: PersonCell.self, cellConfig: { cell, indexPath, model in cell.nameLabel.text = model.name })) .store(in: &subscriptions)
Respectively for a collection view:
data .bind(subscriber: collectionView.itemsSubscriber(cellIdentifier: "Cell", cellType: PersonCollectionCell.self, cellConfig: { cell, indexPath, model in cell.nameLabel.text = model.name cell.imageURL = URL(string: "https://api.adorable.io/avatars/100/\(model.name)")! })) .store(in: &subscriptions)
var data = PassthroughSubject], Never>()data .bind(subscriber: tableView.sectionsSubscriber(cellIdentifier: "Cell", cellType: PersonCell.self, cellConfig: { cell, indexPath, model in cell.nameLabel.text = model.name })) .store(in: &subscriptions)
var data = PassthroughSubject()let controller = TableViewItemsController(cellIdentifier: "Cell", cellType: PersonCell.self) { cell, indexPath, person in cell.nameLabel.text = person.name } controller.animated = false
// More custom controller configuration ...
data .bind(subscriber: tableView.sectionsSubscriber(controller)) .store(in: &subscriptions)
A common pattern for list views is to load a very long list of elements in "batches" or "pages". (The distinction being that pages imply ordered, equal-length batches.)
CombineDataSources includes a data source allowing you to easily implement the batched list pattern called
BatchesDataSourceand a table view controller
TableViewBatchesControllerwhich wraps loading items in batches via the said data source and managing your UI.
In case you want to implement your own custom logic, you can use directly the data source type:
let input = BatchesInput( reload: resetSubject.eraseToAnyPublisher(), loadNext: loadNextSubject.eraseToAnyPublisher() )let dataSource = BatchesDataSource( items: ["Initial Element"], input: input, initialToken: nil, loadItemsWithToken: { token in return MockAPI.requestBatchCustomToken(token) })
dataSourceis controlled via the two inputs:
input.reload(to reload the very first batch) and
loadNext(to load each next batch)
The data source has four outputs:
output.$itemsis the current list of elements,
output.$isLoadingwhether it's currently fetching a batch of elements,
output.$isCompletedwhether the data source fetched all available elements, and
output.$errorwhich is a stream of
Error?elements where errors by the loading closure will bubble up.
In case you'd like to use the provided controller the code is fairly simple as well. You use the standard table view items controller and
TableViewBatchesControllerlike so:
let itemsController = TableViewItemsController(cellIdentifier: "Cell", cellType: UITableViewCell.self, cellConfig: { cell, indexPath, text in cell.textLabel!.text = "\(indexPath.row+1). \(text)" })let tableController = TableViewBatchesController( tableView: tableView, itemsController: itemsController, initialToken: nil, loadItemsWithToken: { nextToken in MockAPI.requestBatch(token: nextToken) } )
tableControllerwill set the table view data source, fetch items, and display cells with the proper animations.
Add the following dependency to your Package.swift file:
.package(url: "https://github.com/combineopensource/CombineDataSources, from: "0.2")
Add the following dependency to your Podfile:
pod 'CombineDataSources'
CombineOpenSource is available under the MIT license. See the LICENSE file for more info.
CombineOpenSource Slack channel: https://combineopensource.slack.com.
Created by Marin Todorov for CombineOpenSource.
📚 You can support me by checking out our Combine book: combinebook.com.
Inspired by RxDataSources and RxRealmDataSources.