Search code examples
iosswiftrealmrealm-object-server

Is it possible to use Realm object server real time sync without indices?


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.


Solution

  • 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.