Easy Guide to RxDataSources!

Vaibhav Singh
4 min readJan 14, 2022

--

In this article, I’m planning to cover a brief introduction to RxDataSources, a framework available from the RxSwiftCommunity GitHub organization and originally developed by Krunoslav Zaher, the creator of RxSwift.

I’ve taken the code from RayWenderlich’s book on RxSwift, I felt there was a lack of good material online about RxDataSources and the book covered it very well, so I felt the need to share it in case anyone has been struggling with RxDataSources.

In this article, I’m gonna be sharing some code snippets from a ToDo list app, to keep the article concise I’m gonna keep the code focused on RxDataSources.

The reason RxDataSources isn’t part of RxCocoa is mainly that it is deeper and more complex than the simple extensions RxCocoa provides. It comes with the following benefits:

  • Support for sectioned tables and collection views.
  • Optimized (partial) reloads for deletions, insertions, and updates, thanks to an efficient differentiation algorithm.
  • Configurable animations for deletions, insertions, and updates.
  • Support for both section and item animations.

Using RxDataSources, instead of passing an array of items to the table or collection view, you pass an array of section models. The section model defines both what goes in the section header (if any), and the data model of each item of that section.

The simplest way to start using RxDataSources is to use the already provided SectionModel or AnimatableSectionModel generic types as the type for your section. In this article we want our tableViews animating so we’ll go with AnimatableSectionModel.

Let’s start by adding the following typealias to our viewModel

typealias TaskSection = AnimatableSectionModel<String, TaskItem>

This defines your section type as having a section model of type String, since you just need a title, and section contents as an array of TaskItems.

The only constraint with RxDataSources is that each type used in a section must conform to the IdentifiableType and Equatable protocols. IdentifiableType declares a unique identifier unique among objects of the same concrete type, so that RxDataSources can uniquely identify data models

Our goal is to split the tasks list like so:

  • Due (unchecked) tasks first, sorted by last-added-first.
  • Done (checked) tasks, sorted by checked data (last checked first).

Below we define sectionedItems as an Observable of TaskSection, by returning an array with two TaskSection elements, you automatically create a list with two sections.

Now. coming back to our viewController, the next step is to create a data source suitable for use with RxDataSources.

For table views, it can be one of two:
• RxTableViewSectionedReloadDataSource<SectionType>.
• RxTableViewSectionedAnimatedDataSource<SectionType>.

The Reload type isn’t very advanced. When the section observable it subscribes to emits a new list of sections, it simply reloads the table by using reloadData() internally.

The Animated type is the one you want. Not only does it perform partial reloads, but it also animates every change. Add the following dataSource property to the ViewController class:

The major difference with RxCocoa’s built-in table view support is that you set up the data source object to display each cell type, instead of doing it in the subscription.

Within the view controller, add a method to configure the datasource

The titleForHeaderInSection closure returns a string title for section headers. This is the simplest case for creating section headers. If you want something more elaborate, you can configure it by setting dataSource.supplementaryViewFactory to return an appropriate UICollectionReusableView for the UICollectionElementKindSectionHeader kind.

When binding an observable to a table or collection view, you provide a closure to produce and configure each cell as needed. RxDataSources works the same way, but the configuration is all performed in the “data source” object.

Let’s look at the cell’s configure method. Did you notice it takes in an action?
This is a great way to handle actions on the cell, like tapping on the cell using RxSwift, these actions are propagated back to the viewModel.

This is how our flow looks like using actions to bind cell actions to the viewModel

The interesting part is that the cell itself, aside from assigning the action to its button (see below), doesn’t have to know anything about the view model itself.

Since viewDidLoad() is the place where the table view is placed in auto-height mode, that’s a good place to complete the table configuration. The only requirement of RxDataSources is that the data source configuration must be done before you bind an observable. So let’s call configureDataSource() inside viewDidLoad().

Finally, bind the view model’s sectionedItems observable to the table view via its data source in the bindViewModel() method:

And that’s it!

Hope this article covered the implementation of RxDataSources concisely, I tried to keep it short so we can focus on RxDataSources. Please let me know in the comments if you have any questions or suggestions!

Thanks for reading!

--

--

Vaibhav Singh
Vaibhav Singh

Written by Vaibhav Singh

iOS Engineer @ Pulselive Leading development of the Premier League App!

No responses yet