Building Table/CollectionView in a few lines of code with DataDrivenRxDatasources on top of RxDataSources

Mykola Fiantsev
3 min readJan 30, 2021
Photo by John Cameron on Unsplash

In this article, I’d like to introduce our approach to deal with Table and Collection views quick and easy way. To be short I am going to talk about UITableView, but all of this works for UICollectionView as well. As the result, we will be able to build TableView as easily as tableView.rx.bind(sections: sections).disposed(by: bag) for any table with any cells inside. It is all the code that you need in your UIController.

Cool, isn’t it? Let’s get started.

The only notice that I have to say that all of this based on RxSwift. In case you are not familiar with this, I highly recommend taking a look. Otherwise, it could be a little bit difficult to catch.

The standard approach to managing table views with data sources has several flaws:

  • Repeated boilerplate code — data source and delegate methods, cell registration, etc.
  • Tangled follow the flow of control for TableView data source and delegate methods since they are often placed in a different order, far from each other, or even located in different files.
  • Violation of dependency inversion principle. The knowledge about which cells are attached to a table view and how these cells are instantiated (nib or class) leaks to corresponding view controllers. View controller becomes dependent on the module of the lower level (tableview cell).
  • Leaves lots of room for mistakes, since data source methods must be consistent with each other. For example, if numberOfRows(inSection:), numberOfSections(in:) and tableView(_,cellForRowAt:) are inconsistent, it results in an unwanted behaviour or even crash. Cells in these methods is a generic UITableViewCell type which usually should be type casted to a concrete class.
  • Table/collection view data source protocol implementation is imperative and does not feel Swift way.

Since the moment I got carried away with RxSwift, I prefer to build code that is driving by events and has no room for numberOfRows(inSection:). I used to feel very frustrated when I found myself creating just another table for my app. Strong Rx community attempted to build tables (remember, when I am talking about tables, I am talking about collections as well) rx-way with RxDataSources.

This library helped us to solve some of “standard approach” problems with an elegant data binding mechanism and powerful AnimatableSectionModel & SectionModel abstractions but still left us on our own with repeatable cell registration and violation of dependency inversion principle.

After building a few tableviews with RxDataSources you maybe noticed some repeatable stuff that is screaming about being encapsulated. We made this logical step and made our own DataDrivenRxDatasources library which brings another level of the abstractions and lets us address these issues and design a data-driven, reusable, and declarative table view component which depends only on its ViewModel.

The core of our library is based on abstracted protocols that are supposed to provide binding sections and cells but don’t care what these sections and cells really are. Here is the example of a cell that assigns some value and provides xib to register itself:

The cell has to adopt the ModelledCell protocol that’s it. Additionally, we have some other helpers protocols such as Selectable, Editable, etc which allows us to provide selection or “swipe to delete” actions.

ViewController’s view model takes some reactive data provider and transforms its events (data) to cell view models wrapped into sections. Here is the word “DataDriven” stands.

As you could notice we can mix different cells as long as they are satisfied ModelledCell protocol without touching ViewController’s code.

Summary

Loving this level of abstraction we are successfully applying DataDrivenRxDatasources in our projects and production for multiple companies. I wrote this because I’d like to introduce our library to the community, maybe you will like it too and find a place to apply it in your projects or if you have some ideas about improving it ⏤ welcome to join, PRs are welcome. I believe it worth some audience.

We placed our code on GitHub with available integrations via Swift Package Manager and Cocoapods. Also we included examples for an easy start. I strongly believe that it will help you to build tables and collections with less code easily way.

--

--