UICollectionView perform batch updates crash with realm notification

539 views Asked by At

I am using realm swift for my messaging app. My base view for messaging is a custom UICollectionView and my i use realm swift for data storage. Unfortunately i couldn't find any official example from realm for updating collection view with realm notification. So i implemented like this when i get messages from realm getting notificationToken by adding an observer for that realm list so when update comes from that notification i perform batch updates and delete, insert and modify indexes that realm told me to do in this notification. my app works well in testing environment but in production i got some crashes that reported my by fabric that told me app crashing and it is caused by this batch updates. their messages are mostly like

invalid update: invalid number of sections. The number of sections contained in the collection view after the update (1) must be equal to the number of sections contained in the collection view before the update (1), plus or minus the number of sections inserted or deleted (0 inserted, 1 deleted).  

or invalid number of items in section after update and so on . I am so confused now. any ideas?

My code for doing this updates

notificationToken = dbmsgs?.observe { [weak self] (changes: RealmCollectionChange) in
  switch changes{
  case .initial:
    print("intial")
    self?.collectionView.reloadData()
  case .update(_,let deletions,let insertions,let modifications):
    self?.collectionView.performBatchUpdates({
      if deletions.count > 0{
        print("deletions count\(deletions.count)")
        if (self?.collectionView.numberOfItems(inSection: 0) ?? 0) - deletions.count > 0 {
          self?.collectionView.deleteItems(at: deletions.map { IndexPath(row: $0, section: 0) })
        }
        else{
          self?.collectionView.deleteSections(IndexSet(integer: 0))
        }
      }
      if insertions.count > 0{
        print("insertaions count\(insertions.count)")
        for index in insertions{
          guard let lastdbmsg = self?.dbmsgs?[index] else{
            return
          }
          let sectionIndex = 0
          let itemIndex = ( self?.dbmsgs != nil) ? (self?.dbmsgs?.count)! - 1 : 0
          if itemIndex == 0{
            self?.collectionView.insertSections([0])
          }
          self?.collectionView.insertItems(at: [IndexPath(item: itemIndex, section: sectionIndex)])
          if itemIndex != 0{
            self?.collectionView.reloadItems(at: [IndexPath(row: itemIndex-1, section: 0)])
          }

        }
      }
      if modifications.count > 0{
        self?.collectionView.reloadItems(at: modifications.map({ IndexPath(row: $0, section: 0)}))
      }
    },completion: { (_) in
    })
  case .error(let error):
    // An error occurred while opening the Realm file on the background worker thread
    fatalError("\(error)")
  }
}
0

There are 0 answers