Elegantly prepare data source for Table View and Collection View

Table View and Collection View have been the pillars on which almost all iOS applications have been built. Building these collections is pretty easy and straight forward. The basic flow for populating any Table View or Collection View is:

The data source is generally the list of data that is supplied to the table view. The table views data source methods then iterate on this list and instantiate cells.

The datasource methods that take part in this:

Table view data sourced methods

There are a lot of different ways to configure your datasource for the table view. Starting from a simple list of data models to more complex generic approaches using protocols.

When we have a single cell the datasource remains pretty simple. Let us look at the following response which has a list of your friends and their contact number:

Great..!! You are friends with the Justice League

When we parse this response to a model named , our data source method and subsequent implementation would look something like this:

Single cell-type typical implementation.

So far, so good. Everything looks neat.

Multiple cell types

Let us take the example of the below screen. This screen is from the Nearby app from my blogpost on MVVM. The Nearby app fetches JSON from Google APIs.

Nearby Home

For simplicity, we will not take the Google API JSON directly. Rather we will use a simplified JSON for understanding:

Nearby.json

If you observe closely, you can see there are three categories of cells in this screen. Let us name them , , and .

: This cell is the pagination cell which will hold the first Place from every category

: Lists all the categories

: Lists the places grouped under a single category

There is a huge problem when it comes to implementing having multiple cell types. We end up in lots of if-else checks to determine the cell type based on the data.

Let us look at different ways of configuring our datasource and subsequent implementations.

Enum based datasource implementation

Preparing the data source:

Though there are a lot of ways to configure the datasource for the above cell, one would generally prefer to configure datasource based on the cell type as it would help to determine which cell to display and what data to show. Or else you can go for a lot of if-else checks.

I will not be listing the complete implementation details rather will give a high-level implementation detail.

Enum based modeling and datasource configuration

What did we do here?
- Model to hold detail for a place.
- Enum to hold the types of categories of places we have.
- Model to hold a category detail
-Enum to specify the type of cells that are present in the home page list. We have specified data of cells as associated values within these enums.

  • can be populated with a list of thereby the associated value is an array of
  • is a cell with a collection view that can be populated using a list of categories.
  • We have multiple places cells grouped under a common category type. A can be build using a list of .

Populating the data

A typical implementation of this approach will be something like this:

Enum based datasource approach

What did we do here?

  • We have declared a property that holds all the cell types and their associated values. I believe the logic to prepare the is pretty straightforward based on the details of the cell data that we discussed earlier.
  • In the table view’s datasource method, we distinguished between the cell with the help of our enums.
  • We created methods to provide cells based on the cell data that we got from our associated value.

Great … !! We did it. We composed our datasource in a pretty clean way and avoided any if-else checks in our implementation.

If you are using MVVM most often you can check out the code of Nearby app to have a glimpse of this approach implemented in MVVM.

Problem

  • We have switch cases spread everywhere.
  • Our will bloat with logic to configure the cell.
  • Repetitive cell configuration methods in .
  • If cell types increase, you can imagine how ugly our would look.
Why?

Protocols to the rescue

If you look closely, you would find many repetitive patterns in our implementation. The creation of cells is duplicated and even the configuration calls for the cells might seem duplicated as well except the data that we are passing to each cell.

If we can somehow remove these repetitions by abstracting the data that is needed by every cell, then our problem will be sorted.

Didn’t get it? Wait for the code.

Presentation Models

Let us abstract all details needed by the cells in Presentation models which would confirm a common protocol.

Presentation Models

The common protocol contains an identifier property, which will help to determine the cell type from the identifier of the cell.

Now you might think that here the presentation model is being pretty tightly coupled with the cell. But it's okay. Presentation models of a particular view should be specific to the view and not reused across. It is always the UI component that needs to be reused.

Abstracting Cells

Cells can also be abstracted in a similar manner.

Cell abstraction

The protocol holds the configuration method call in it. Every cell conforms to this and implements its own configuration methods.

View Controller Implementation

Now we can have a list of as our datasource.

We need not do anything fancy to prepare the here. We have to just map our data into our presentation models. An example could be the following:

is the data model that is got after parsing the Nearby home response.

Isn’t this clean and reusable also. You can also reuse this similar approach for other cells and presentation models as well.

Isn’t that great…!!

Problem

Typecasting and type safety might be a problem that comes as a trade-off for making your code short. For logging any abuse of the protocols, we can log the errors if any as done in the above implementation.

You have pros and cons in both the above approaches, you have to decide what is best suited for you.

I would love to hear from you

You can reach me for any query, feedback or just want to have a discussion by the following channels:

Twitter — @G_ABHISEK

LinkedIn

Gmail: abhisekbunty94@gmail.com

Please feel free to share with your fellow developers.

Software Developer(iOS), Speaker & Writer at Swift India