1

I was looking into real time sync as implemented in Realm's "tasks" example app.

In particular, this block:

private func setupNotifications() -> NotificationToken {
    return parent.items.addNotificationBlock { [unowned self] changes in
        switch changes {
        case .Initial:
            // Results are now populated and can be accessed without blocking the UI
            self.viewController.didUpdateList(reload: true)
        case .Update(_, let deletions, let insertions, let modifications):
            // Query results have changed, so apply them to the UITableView
            self.viewController.tableView.beginUpdates()
            self.viewController.tableView.insertRowsAtIndexPaths(insertions.map { NSIndexPath(forRow: $0, inSection: 0) }, withRowAnimation: .Automatic)
            self.viewController.tableView.deleteRowsAtIndexPaths(deletions.map { NSIndexPath(forRow: $0, inSection: 0) }, withRowAnimation: .Automatic)
            self.viewController.tableView.reloadRowsAtIndexPaths(modifications.map { NSIndexPath(forRow: $0, inSection: 0) }, withRowAnimation: .None)
            self.viewController.tableView.endUpdates()
            self.viewController.didUpdateList(reload: false)
        case .Error(let error):
            // An error occurred while opening the Realm file on the background worker thread
            fatalError(String(error))
        }
    }
}

Basically the changes are communicated using indices. By simply accessing the underlaying model / realm object using these indices the interface is updated.

Now I have an architecture that doesn't seem compatible with this. I have a dedicated database layer (of which realm is an implementation), where I load the realm objects in a background thread and map to plain model objects. This way I decouple my code from the database implementation and can use immutable models.

I'm not sure how to handle the indices in this case. Looks like I should remember the original query, do it again, and then access the entries I need using these indices? That sounds very inefficient...

Additionally, I don't know how the indices work with specific queries like "all items that have status x in field y" - does the index I receive refers to this specific query?

What is the recommended way to proceed here?

Edit: Just to add some additional commentary, I implemented myself sync functionality using a custom server and websockets, and I used semantic keys instead of indices (sometimes I even sent the complete object to avoid having to query the database). This way I had not to deal with possible inconsistencies resulting of index based access. Wonder if something like that is possible or planed with Realm sync at some point.

P.S. I intend to switch to Realm sync because my custom server is not well tested and very hard to maintain. I hope that this is possible.

User
  • 31,811
  • 40
  • 131
  • 232
  • Recommended way to proceed is to use the zero-copy database as a zero-copy database, rather than map everything out - but you can read more about this in the [official documentation](https://realm.io/docs/swift/latest/#queries) – EpicPandaForce Dec 04 '16 at 21:05
  • Well, decoupling the interface code from the DB implementation was what allowed me to switch to realm in the first place. Of course it has disadvantages, I'm aware of that. – User Dec 04 '16 at 21:11

1 Answers1

1

All realm queries return Results, it's an auto-updating container type, so you don't need to make the query again. You can setup the notification handler for any specific Result and be notified when this collection is changed to update your mapped models as well.

Dmitry
  • 7,300
  • 6
  • 32
  • 55
  • Okay. This is going to be difficult because my architecture is not reactive. I'm using stateless providers, where I retrieve the data via callbacks. Will have to figure something, probably I'll end using `Result` directly in the controllers. Just to confirm, if I have a query with several filters/predicates, the indices I receive refer to this specific result, i.e. including all the filters, right? – User Dec 05 '16 at 13:22