How do you apply a diffable data source UI snapshot only after awaiting (with async/await) data fetched from the network?

I'm new to async/await, and am currently migrating my completion handler code to Swift 5.5's concurrency features.

After generating an sync alternative in Xcode to my function func fetchMatchRecords(completion: @escaping ([Match]) -> Void), it becomes func fetchMatchRecords() async -> [Match].

I'm not sure how it would be used in the context of UIKit and diffable data sources.

In a viewDidLoad, previously it would be

MatchHistoryController.shared.fetchMatchRecords() { matches in
    DispatchQueue.main.async {
        self.dataSource.apply(self.initialSnapshot(), animatingDifferences: false)
    }
}

But I'm not sure how it would be used now

Task {
    await MatchHistoryController.shared.fetchMatchRecords()
}
self.dataSource.apply(self.initialSnapshot(), animatingDifferences: false)

How would I make sure that the snapshot is applied only after awaiting a successful fetch result?

Here's the definition of initialSnapshot() that I used:

func initialSnapshot() -> NSDiffableDataSourceSnapshot<Section, Match> {
    var snapshot = NSDiffableDataSourceSnapshot<Section, Match>()
    snapshot.appendSections([.main])
    snapshot.appendItems(MatchHistoryController.shared.matches)
    return snapshot
}

Replies

I think you found work solution, by the way:

Task {
    await MatchHistoryController.shared.fetchMatchRecords()
    if Task.isCancelled == false else { return }
    await MainActor.run { [weak self] in  self?.dataSource.apply(self.initialSnapshot(), animatingDifferences: false) }
}

But what about if you need to apply datasource in global queue, and do it in UIViewController which bordered as @MainActor :) I have got warn UICollectionViewDiffableDataSource is not @Sendable :)