I'm new to realm and trying to implement realm with UICollectionViewDiffableDataSource
. However, I'm finding it difficult to update the data source after inserting / deleting a new object. I tried to update with NotificationToken
but it crashes. Here's the code that I've tried so far:
fileprivate let realm = try! Realm()
fileprivate var notificationToken: NotificationToken?
fileprivate var items: Results<Item>?
fileprivate enum Section: String, CaseIterable, Hashable {
case main
}
fileprivate typealias DataSource = UICollectionViewDiffableDataSource<Section, Item>
fileprivate typealias Snapshot = NSDiffableDataSourceSnapshot<Section, Item>
fileprivate lazy var dataSource = itemsDataSource()
fileprivate func itemsDataSource() -> DataSource {
let dataSource = DataSource(collectionView: itemsCollectionView) { collectionView, indexPath, item in
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as! STItemCell
cell.titleLabel.text = item.name
return cell
}
return dataSource
}
fileprivate func bind() {
items = realm.objects(Item.self).sorted(byKeyPath: "order").filter("isDeleted == false")
notificationToken = items?.observe({ [weak self] changes in
guard let datasource = self?.datasource else { return }
switch changes {
case .initial:
self?.applySnapshot()
case .update(_, deletions: let deletions, insertions: let insertions, modifications: let modifications):
var snapshot = datasource.snapshot()
if !deletions.isEmpty {
let itemIdentifiers = deletions.compactMap { item in
return datasource.itemIdentifier(for: IndexPath(item: item, section: 0))
}
snapshot.deleteItems(itemIdentifiers)
}
if !insertions.isEmpty {
let itemIdentifiers = insertions.compactMap { item in
return datasource.itemIdentifier(for: IndexPath(item: item, section: 0))
}
// snapshot.insertItems(...) // Don't know how to implement this...
}
if !modifications.isEmpty {
let itemIdentifiers = modifications.compactMap { item in
return datasource.itemIdentifier(for: IndexPath(item: item, section: 0))
}
snapshot.reloadItems(itemIdentifiers)
}
datasource.apply(snapshot, animatingDifferences: true)
case .error(let error):
fatalError("\(error)")
}
})
}
fileprivate func applySnapshot(animatingDifferences: Bool = true) {
var snapshot = Snapshot()
snapshot.appendSections([.main])
guard let items = items else { return }
snapshot.appendItems(Array(items))
datasource.apply(snapshot, animatingDifferences: animatingDifferences)
}
Would really appreciate your help regarding this. Thanks!