Skip to content
Prepare to Grow

UIKit Development

Diffable Data Sources and Modern Cell Configuration

Drive lists from stable identity using snapshots, cell registrations, and repeatable content configurations.

Intermediate6 min read2 guided activities

Before you begin

What you will understand

  • Explain identity-based list updates.
  • Create and apply diffable snapshots.
  • Configure cells with registrations outside provider closures.
  • Update content without unsafe batch calculations.
01

Learning stage

Concept Explanation

A diffable data source represents list state as ordered section and item identifiers. Applying a new snapshot lets UIKit calculate inserts, deletes, moves, and updates from stable identity. Identifiers must be Hashable and stable; mutable display values generally should not define identity.

Cell registration pairs a cell type with an item type and a configuration handler. Create registrations once, then dequeue configured cells inside the data-source provider. Content configurations make each pass derive appearance from the current item, which works naturally with reuse and state changes.

A snapshot is UI state, not the database itself. Build it from the current source of truth on the main actor. For an item whose identity is unchanged but visible content changed, reconfigure or reload that identifier. Avoid overlapping snapshot applications and make empty, loading, and error states explicit outside fabricated rows.

  • Stable identifier: durable Hashable identity independent of position.
  • Snapshot: ordered section and item identifiers for current UI state.
  • Diff: insert, delete, move, and update calculation.
  • Cell registration: reusable cell creation and configuration recipe.
  • Reconfiguration: refreshes visible content without changing identity.
02

Learning stage

Syntax & Examples

A list data source joins stable lesson IDs back to current models and applies a new snapshot after filtering.

LessonDataSource.swiftswift
enum Section { case main }

private var lessonsByID: [Lesson.ID: Lesson] = [:]
private var dataSource: UICollectionViewDiffableDataSource<Section, Lesson.ID>!

private func configureDataSource() {
  let registration = UICollectionView.CellRegistration<UICollectionViewListCell, Lesson> {
    cell, _, lesson in
    var content = cell.defaultContentConfiguration()
    content.text = lesson.title
    content.secondaryText = lesson.subtitle
    cell.contentConfiguration = content
    cell.accessories = lesson.isComplete ? [.checkmark()] : [.disclosureIndicator()]
  }

  dataSource = .init(collectionView: collectionView) { [weak self] collectionView, indexPath, id in
    guard let lesson = self?.lessonsByID[id] else { return nil }
    return collectionView.dequeueConfiguredReusableCell(using: registration,
                                                          for: indexPath,
                                                          item: lesson)
  }
}

@MainActor
func show(_ lessons: [Lesson], animated: Bool) {
  lessonsByID = Dictionary(uniqueKeysWithValues: lessons.map { ($0.id, $0) })
  var snapshot = NSDiffableDataSourceSnapshot<Section, Lesson.ID>()
  snapshot.appendSections([.main])
  snapshot.appendItems(lessons.map(.id))
  dataSource.apply(snapshot, animatingDifferences: animated)
}
The snapshot stores identity while the current model dictionary provides display values.
03

Learning stage

Real-World Usage

Connect the UIKit concept to complete, maintainable application features.

  • Animate filtered search results safely.
  • Move favorites between sections.
  • Refresh one item's progress without rebuilding the list manually.
  • Share identity-driven updates across table and collection views.
04

Learning stage

Common Mistakes

Identify lifecycle, ownership, identity, layout, accessibility, and user-experience risks.

  • Using an item's array index as its identifier.
  • Including mutable title or completion state in identity.
  • Creating cell registration inside the provider closure.
  • Applying snapshots from background threads.
  • Treating the snapshot as the only domain data store.
05

Learning stage

Practice Exercises

Build the behavior in a small Xcode project and inspect it across realistic states.

Activity 1

Filter with snapshots

Build All, In Progress, and Complete filters that generate snapshots from one lesson store while preserving item IDs.

Hint: The filter changes membership and order, not identity.

Activity 2

Refresh visible progress

Update one lesson's progress and reconfigure its identifier without deleting and reinserting it.

Hint: Update the model store before applying the snapshot change.

06

Learning stage

Knowledge Check

Answer each question before revealing the explanation.

QUESTION 1

Why do diffable data sources require stable identifiers?

  1. A.To determine which logical items moved, appeared, disappeared, or changed
  2. B.To choose fonts
  3. C.To create constraints
  4. D.To avoid models
Reveal answer

To determine which logical items moved, appeared, disappeared, or changed

Positions vary; identity lets the framework compare two ordered states safely.

QUESTION 2

Where should a cell registration be created?

Reveal answer

Outside the cell-provider closure, usually while configuring the data source.

Recreating it inside the provider prevents correct reuse and can cause an exception.

07

Learning stage

Interview Preparation

Explain the design in terms of lifecycle, identity, ownership, system behavior, and trade-offs.

What problem does a diffable data source solve?

Short answer: It derives safe animated list updates by comparing snapshots of stable section and item identity.

Explore the detailed answer

Instead of manually coordinating index-path insertions, deletions, and moves, I construct the desired ordered identity state. UIKit calculates the transition. The model store still owns content, IDs remain stable, and registrations configure reusable cells from current data.

Possible follow-ups

  • • What makes a good item identifier?
  • • When would you reconfigure rather than reinsert an item?
08

Learning stage

Key Takeaways

Diffable data sources replace fragile positional update bookkeeping with snapshots of stable identity, while registrations make cell configuration repeatable.

  • Identity must survive sorting and filtering.
  • Snapshots describe ordered UI state.
  • Keep content in a real model store.
  • Create registrations once.
  • Apply UI updates on the main actor and reconfigure unchanged identities.