How to Reload Collection View (DiffableDataSource) after API Finishes Calling

Hello,

I have a collection view that uses a diffable data source, and I am initiating an API call while configuring a cell RuntimeCell in the cell registration block inside setupDataSource(). The cell has a runtimeLabel property whose text I am setting inside a configureLabel(movieId:) function.

I noticed that the collection view does not automatically refresh the text label once this API call finishes and after setting the text property on a UILabel in the collection view cell to a value retrieved during the API call. I presume this is because I need to call dataSource.apply(snapshot) myself to reload the changes in the collection view after the API call finishes retrieving the runtime data.

However, since the API call happens via the configuration of the cell in the cell registration closure, this API call ends up being called infinitely if I call dataSource.apply(snapshot) every time the API call finishes (i.e. calling dataSource.applySnapshot() calls the closure for the cell registration handler which re-triggers the API call).

What is the correct architecture to apply to accomplish reloading the collection view so that the text label appears once the API finishes calling?

Thank you

class MovieDetailViewController: UIViewController {
func setupDataSource() {
        
      // ...
       
        let runTimeCellRegistration = UICollectionView.CellRegistration<RuntimeCell, Item> { cell, indexPath, item in
            
            cell.runtimeLabelDelegate = self
                        
            cell.configureLabel(movieId: self.selectedMovie.id)
        }

        dataSource = UICollectionViewDiffableDataSource(collectionView: collectionView, cellProvider: { collectionView, indexPath, itemIdentifier in
            
            let section = Section(rawValue: indexPath.section)
            switch section {
               //...
                case .runtime:
                    return collectionView.dequeueConfiguredReusableCell(using: runTimeCellRegistration, for: indexPath, item: itemIdentifier)
                //...
            }
            return nil
        })
    }
}

protocol RuntimeLabelCellDelegate: AnyObject {
    func didUpdateRuntime()
}

class RuntimeCell: UICollectionViewCell {
      
    var runtimeLabel: UILabel!
    
    //... UI Setup

    func configureLabel(movieId: Int) {
        Task {
            do {
                let details = try await movieSearchService.fetchMovieDetails(movieId: movieId)
                await MainActor.run {
                    let minutes = details.runTime

                    let durationText = "\(minutes)m"
                    var emojiText = ""
                    
                    if minutes < 90 {
                        emojiText = "Short & Sweet ⚡️"
                    } else if minutes > 150 {
                        emojiText = "Get the snacks ready 🍿"
                    }
                    runtimeLabel.text = emojiText.isEmpty ? durationText : "\(durationText) • \(emojiText)"
                    runtimeLabelDelegate?.didUpdateRuntime()
                }
            } catch {
                print("Failed to load details: \(error)")
            }
        }
    }
}

extension MovieDetailViewController: RuntimeLabelCellDelegate {
    func didUpdateRuntime() {
        var snapshot = dataSource.snapshot()
        
        snapshot.appendItems([.runtime], toSection: .runtime)
        
        dataSource.apply(snapshot, animatingDifferences: true)
    }
}

How to Reload Collection View (DiffableDataSource) after API Finishes Calling
 
 
Q