1

When I observe my realm model and bind changes to table view it works. But when I try to add row to the table I have some crash

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to insert row 1 into section 0, but there are only 1 rows in section 0 after the update'

Can I do it without using standard delegates methods?

Here is my code snippet

        let realm = try! Realm()

    let places = realm.objects(Place.self)

    Observable.from(places)
        .bindTo(tableView.rx.items(cellIdentifier: "PlaceCell", cellType: PlaceCell.self)) { (row, element, cell) in
            let viewModel = PlaceCellViewModel(place: element)
            cell.setup(viewModel: viewModel)
        }
        .addDisposableTo(disposeBag)

    Observable.changesetFrom(places).subscribe(onNext: { [weak self] result, changes in

        if let changes = changes {
            self?.tableView.beginUpdates()
            let indexes = changes.inserted.map { IndexPath(row: $0, section: 0) }
            self?.tableView.insertRows(at: indexes, with: .bottom)
            self?.tableView.endUpdates()
        } else {
            self?.tableView.reloadData()
        }

        })
        .addDisposableTo(disposeBag)
milczi
  • 7,064
  • 2
  • 27
  • 22

1 Answers1

5

Currently, you have two subscriptions racing against each other to update your table.

  1. Your first subscription uses a binding to your table view (basically calling reloadData() each time there's a change in your underlying data)

  2. Your second subscription also updates your table but this time it uses the fine-grained methods to insert records.

Hence when the second subscription kicks in - your first subscription has already updated your table and you get a crashing error message.


Currently there's no wrapper in RxRealm to wrap fine-graned notifications in a binder (you can create an issue on the RxRealm repo about it though!)

If you'd like to have animated changes for your table rows you have to implement the table view data source methods, like here:

https://github.com/RxSwiftCommunity/RxRealm/blob/master/Example/RxRealm/ViewController.swift#L74


Update #1: I'd like to add that some time after this (and other similar questions) I started an RxRealmDataSources library, which works pretty much like the vanilla RxDataSources library but specifically to accomodate for binding Realm types. The lib takes care to bind an RxRealm observable to a table or collection view on both iOS and macOS and update them with the neccessary animations.

Here's the GitHub repo: https://github.com/RxSwiftCommunity/RxRealmDataSources

Marin Todorov
  • 6,377
  • 9
  • 45
  • 73