0

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!

Mohit
  • 45
  • 2
  • 10
  • What you're attempting to do with the code is not really clear. Starting with `var snapshot = datasource.snapshot()` and then `let itemIdentifiers = deletions.compactMap {` etc. What are you expecting that code to do? In other words when deletions happen in Realm the Results object always reflects the current state of the data. So when an item is deleted from Realm it's automatically removed from `var items` and generally speaking `items` would be the dataSource backing your tableView or collectionView. What is `dataSource`? – Jay Jun 19 '21 at 12:31
  • Hello @Jay, Thanks for your reply. Apologies if my question wasn't clear. What I'm trying to do is to update my UI whenever there is a change in items. However the diffableDataSource doesn't reflect the changes so I decided to use the NotificationToken for that but then again it didn't help much. I've edited the question to include the datasource. – Mohit Jun 19 '21 at 16:57

0 Answers0