Realm-cocoa: Notification block does not work always with Realm Object Server

Created on 12 Jan 2017  路  4Comments  路  Source: realm/realm-cocoa

Goals

Update the user interface instantly when my Collection Result changes (using Realm Object Server as my target realm database)

Expected Results

Refresh the user interface whenever the Results change

Actual Results

The notification block works flawlessly using local realm database. I wanted to move my database server-side, so I tried to convert my code to work with realm mobile platform

The user interface is sometimes updated as soon as changes occur, sometimes takes seconds, sometimes never update (although when checked, the actual collection result is changed)

for example, when I first initialize the notification block, the table view refreshes successfully.. when I add a new object, update or remove an object, sometimes it refreshes instantly sometimes it takes time sometimes it doesn't... etc

Please note that every time this happens I check the Collection Results, and make sure that it changed successfully

Code Sample

var notificationToken: NotificationToken?


func initNotification() -> NotificationToken? {

        return self.myObjects?.addNotificationBlock { [weak self] (changes: RealmCollectionChange) in
            guard let tableView = self?.tableView else { return }
            switch changes {
            case .initial:
                // Results are now populated and can be accessed without blocking the UI
                tableView.reloadData()
                break
            case .update(_, let deletions, let insertions, let modifications):
                // Query results have changed, so apply them to the UITableView
                tableView.beginUpdates()
                //tableView.insertRows(at: IndexSet(insertions),
                //                     withAnimation: NSTableViewAnimationOptions.effectGap )
                //tableView.removeRows(at: IndexSet(deletions),
                //                     withAnimation: .effectFade)
                //tableView.reloadData(forRowIndexes: IndexSet(modifications), columnIndexes: IndexSet(0...tableView.tableColumns.count-1))
                tableView.reloadData()
                tableView.endUpdates()
                break
            case .error(let error):
                // An error occurred while opening the Realm file on the background worker thread
                fatalError("\(error)")
                break
            }
        }
   }

    deinit {
        notificationToken?.stop()
    }

    func syncRealm() {
        self.userLogin() { config in
            DispatchQueue.main.async {
                MyObject.configuration = config
                self.myObjects = MyObject.getAll()
                self.notificationToken = self.initNotification()
            }             
        }
    }   

    func userLogin(onCompletion: @escaping (Realm.Configuration) -> Void) {
        let serverURL = URL(string: "http://127.0.0.1:9080")!
        let credentials = SyncCredentials.usernamePassword(username: "test@test", password: "test")
        SyncUser.logIn(with: credentials, server: serverURL) {
            user, error in

            if let user = user {
                let syncServerURL = URL(string: "realm://localhost:9080/~/test")!
                let config = Realm.Configuration(syncConfiguration: SyncConfiguration(user: user, realmURL: syncServerURL))
                //let realm = try! Realm(configuration: config)
                onCompletion(config)
            } else if let error = error {
            }
        }

    }

Version of Realm and Tooling

Realm version: 2.1.2 (Swift 3)

ProductName:    Mac OS X
ProductVersion: 10.12.1
BuildVersion:   16B2555

/Applications/Xcode.app/Contents/Developer
Xcode 8.2.1
Build version 8C1002

/usr/local/bin/pod
1.1.0.rc.2
(not in use here)

/bin/bash
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin16)

/usr/local/bin/carthage
0.17.2
(not in use here)

/usr/bin/git
git version 2.10.1 (Apple Git-78)
T-Help

Most helpful comment

@danipralea these are two different types of notifications: Realm Notifications that are triggered everytime when any write transaction is committed and Collection Notifications that notify about the changes in specific Realm Results.

All 4 comments

I think we had this issue before but it should have been fixed in https://github.com/realm/realm-cocoa/pull/4253, however it was released in 2.1.0.. @hadiyazdi could you please try to reproduce this issue with the latest (2.2.0) version of Realm and if it still exists, it would be great if you can provide an example Xcode project to reproduce it. Thanks!

Hey guys!
I noticed the SDK in implementation is different than the documentation.

More specifically, the notification block does not return the changes anymore, but only the notification name and the realm:

let block : NotificationBlock = { [weak self] (notification: Realm.Notification, realm: Realm) in
            guard let `self` = self else { return }

            print("realm notification : \(notification)")
        }

But the docs are different in implementation: https://realm.io/docs/swift/latest/#collection-notifications

@stel the question is: How do I access now the actual changes (the insertions, deletions, modifications) ?

@danipralea these are two different types of notifications: Realm Notifications that are triggered everytime when any write transaction is committed and Collection Notifications that notify about the changes in specific Realm Results.

thanks @stel

Was this page helpful?
0 / 5 - 0 ratings