I am creating a realm object in swift 4 and am trying to observe it for changes as per the latest documentation.
Realm object:
import Foundation
import RealmSwift
class Thing: Object{
@objc dynamic var id = UUID().uuidString
@objc dynamic var descriptionText: String = "xyxyx"
override static func primaryKey() -> String? {
return "id"
}
Remote Realm
extension Realm {
static func sharedDataRealm(callback: @escaping (Realm?, Swift.Error?) -> Void) {
SyncUser.logIn(with: Constants.syncCredentials, server: Constants.remoteAuthServer) { (remoteUser, error) in
if let user = remoteUser {
let sharedConfig = user.configuration(realmURL: Constants.remoteSharedRealmServer, fullSynchronization: true)
Realm.asyncOpen(configuration: sharedConfig, callback: callback)
} else {
callback(nil, error)
}
}
}
}
Database layer
class Database {
static let shared: Database = Database()
private init(){}
func saveThing(thing: Thing){
Realm.sharedDataRealm(callback: { (remoteRealm, error) in
if let realm = remoteRealm {
do { try realm.write { realm.add(thing, update: true)}
} catch {
print("error \(error)")
return
}
}
})
}
func updateText(onThing: Thing){
Realm.sharedDataRealm(callback: { (remoteRealm, error) in
if let realm = remoteRealm {
do { try realm.write { onThing.descriptionText = "\(arc4random())"}
} catch {
print("*** error \(error)")
return
}
}
})
}
}
Problematic observer code:
let thing = Thing()
Database.shared.saveThing(thing: thing)
_ = thing.observe { (change) in
switch change {
case .change(let properties):
for property in properties {
print("property \(property.name) has new value \(property.newValue as! String)")
}
case .error(let error):
print(" an error occured: \(error)")
case . deleted:
print(" thing was deleted")
}
}
Other observer code (with delay added..)
override func viewDidLoad() {
super.viewDidLoad()
var thing = Thing()
print ("*** created \(thing.descriptionText)")
Database.shared.saveThing(thing: thing)
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(5000)) {
_ = thing.observe { (change) in
switch change {
case .change(let properties):
for property in properties {
print("*** property \(property.name) has new value \(property.newValue as! String)")
}
case .error(let error):
print("*** an error occured: \(error)")
case . deleted:
print("*** situation was deleted")
}
}
}
Database.shared.updateText(onThing: thing)
}
The "problematic observer code" crashes with "reason: 'Only objects which are managed by a Realm support change notifications'" at the "thing.observe(..)" line. The "Other observer code" does not crash, because I introduce a delay from the moment I added the object to the Realm and the moment that I start to observe it. However the change on the "thing" object still does not trigger any notification and the print of the new property is not run.
Per my experience in coding, I should NOT have to hardcode a delay to allow the realm to actually finalize the creation (and managing operation) of my object, in the first place. I assume that this delay is needed because I live in a region which is far from the Realm region and there is probably some lag (?).
1. Is there a better way to start observing the object after its creation without hardcoding delays?
2. Why there is no notification when the updateText() function is executed, even after the observer gets attached?..
Thank you