In the last blog post, I took a deep-dive into the basics of FlexDataSource, an extremely useful tool to quickly configure a relationship between models and UITableViewCell
s, and a relationship between an array of models and a functioning UITableView
. As a quick sidebar, I just want to note that FlexDataSource also works with UICollectionView
s much in the same way that I’ve explained in the last post. Although I’ve explained why FlexDataSource is useful, I’ve yet to show why it’s flexible with regards to an arbitrary model to be displayed. That is where the FlexModelItem
class comes into play. Here it is:

FlexModelItem
is generic with two parameters:
- T: The model we want to populate the cell with (no restrictions)
- C: The cell we want to be populated (must inherit from
UITableViewCell
)
FlexModelItem
inherits from FlexDataSourceItem
, so we know that we can plug in a FlexModelItem
whenever a FlexDataSourceItem
is used and not lose any functionality. FlexModelItem
takes a model
and a configurer
in its constructor. The configurer
is a function that will populate whatever cell type C
is with respect to your model of type T
. This obviates the need to define your own subclasses of FlexDataSourceItem
every time that you have a model-to-cell relationship. The FlexDataSourceItem
protocol isn’t generic, however, and FlexDataSource
uses the configureCell: (UITableViewCell) -> Void
function to populate the cell
and a certain indexPath
, so we niftily use the *->
operator, defined here, that essentially fixes the first parameter of a two parameter function and returns a function that only depends on the second parameter. In this case, we fix model: T
to our configurer: (T, C) -> Void
and set the resulting function (C) -> Void
to our local variable to save. Then, in our overridden configureCell
function, we optionally cast our UITableViewCell
to C
, and call our configurer
on that cell.
Now, as an example, let’s say we have a network call that is supposed to return an array of Users
, each with a firstName
, lastName
, and occupation
. We also have a subclass of UITableViewCell
called UserTableViewCell
that has a nameLabel
and an occupationLabel
. Now, we want to display a UITableView
of all the users that get returned from our network call.
We first define our UsersViewController
below:

In our viewDidLoad
, we have to set up our dataSource
. We have also declared an indicatingCall
that we need to store in our UsersViewController
so it doesn’t get deallocated. For those who want to read about the network layer that I normally use, please do so here, but for all intents and purposes, a CombineNetCall
holds all the data you need for a network call:
- The URL
- HTTP Method
- HTTP Headers
- URL Parameters
- HTTP Body
A CombineNetCall
also has a fire
method that essentially makes a URLSessionDataTask
and resumes it as you would using Swift’s native network layer. It also has publishers for the HTTPURLResponse
, Error
, and Data
that you would tap into in the callback of URLSessionDataTask
.
Our next step is to create our network call. Elsewhere in our project we define usersIndexNetCall
:

What we’ve done here is set up a network call to GET https://example.com/api/v1/users
, and we stub our network call with an array of users defined below:

Now, let’s define a function in our ViewController called setUpNetCall
that takes in a CombineNetCall
and returns an AnyPublisher<FlexDataSource, Never>
:

This function stores the call, and taps into the call’s $data
publisher and uses a function called modelPublisher
that will automatically decode the data publisher’s value into the value-type of the variable, in this case, [User]
. Next we use the -*>
operator (similar to *->
, just with the second parameter instead of the first) and the constructor of FlexModelItem
to create a function that maps a User
to a FlexModelItem
. Then, we use the free-function version of map
, and the modelPub
‘s map
method to create a publisher of [FlexDataSourceItem]
, and use build-in methods from FDS
to create a FlexDataSource
publisher, which we return.
Lastly, all we need to do now is get our network call, create the FlexDataSource
publisher, sink into it and set it to our dataSource
variable, which will then trigger it’s didSet
and set itself as our tableView
‘s dataSource and reload the tableView
.

There — we did it! If you’re following along in this tutorial, you’ll notice that your UIViewController
only has one method defined inside of it, besides viewDidLoad
. And the cool thing is — no matter how complicated your models become, displaying a list of them is exactly the same process. All of the meat of your programming work goes into the configuring functions that populate your cell’s with your model. Building a UIViewController
that makes a call to your backend, decodes it into your model, saves the models, and displays them in a UITableView
, with regular, out of the box, Swift would take much longer and require much more lines of code. I’ve gone a long time without conforming a UIViewController
to UITableViewDataSource
, and this is why. In my next post we’ll build off of this and integrate fuikit
, another library I use everyday, so you can see why my UIViewController
s never conform to UITableViewDelegate
either.
Happy Coding!