The data source is the heart and soul of UITableView and UICollectionView. Diffable data sources UITableViewDiffableDataSource and UICollectionViewDiffableDataSource is the declarative way to supply the structure and content of the actual data to these UIKit or AppKit components.

lazy var dataSource: UITableViewDiffableDataSource<Section,Entry> = {
    return UITableViewDiffableDataSource(tableView: tableView) { (tableView, indexPath, entry) -> UITableViewCell? in
      let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
      cell.textLabel?.text = entry.content  
      return cell
    }
  }()

Declaring a UITableViewDiffableDataSource object is similar to tableView(_:cellForRowAt:) in UITableViewDataSource protocol where the index path is expressed to extract the requested section number and row number, and return a fully configured UITableViewCell ready for display in the table view.

UITableViewDiffableDataSource is declared with generic types to avoid using primitive types to expression sections and rows and improve the type safety.

enum Section {
  case today
}

struct Entry: Hashable {
  var content: String
}

The Section type is expressed using an enum that contains all the cases related to the structure and content of the actual data. The Entry type contains the content and conforms to the Hashable protocol to let the diffable data source uniquely identify it.

Updating a UITableView or UICollectionView is performed by initializing a NSDiffableDataSourceSnapshot instance with the concerned data, then apply the differences.

func reloadSnapshot(section: Section, entries: [Entry], animated: Bool) {
    var snapshot = NSDiffableDataSourceSnapshot<Section,Entry>()
    snapshot.appendSections([section])
    snapshot.appendItems(entries)
    dataSource?.apply(snapshot, animatingDifferences: animated)
}

Diffable data source is an elegant and efficient way to reduce complexity when dealing with UI state, improving type safety, reusable data sources across your code base which leads to the reduction of the boilerplate code.

Thanks for reading 🙂