Realm Swift: updating an object inside a closure
For the question, here's a simple example (with a few shortcuts):
class Foo: Object {
dynamic var id: Int = 0
[...]
}
class Bar: Object {
dynamic var id: Int = 0
dynamic var foo: Foo?
convenience required init(data: AnyObject) {
self.init()
self.id = data.id as! Int
if let foo_id = data.foo_id as? Int {
// Function querying the remote database and returning an object
Foo.get(foo_id) { (foo) -> Void in
self.foo = foo // Foo object assigned, as expected
}
}
}
}
If I do self.foo = foo
in function closure get()
, I got an exception:
exception "RLMException", reason: "Attempting to modify an object outside of a write transaction - first call beginWriteTransaction on the RLMRealm instance."
So if I add realm.write around it as given by the previous exception:
...
Foo.get(foo_id) { (foo) -> Void in
let realm = Realm(path: Realm.defaultPath)
realm.write {
self.foo = foo
}
}
...
This time I will get a new one:
exception "RLMException", reason: "Unable to add objects from another realm"
I am stuck and I cannot figure out what is required of me here, but the document does not help.
I'm not used to Realm, so I guess I have something wrong with how it works, but I don't know what.
thanks for the help
source to share
OK, so the problem is when you are trying to open a session write()
when the object is not persisted to the Realm in the initializer itself, and I am guessing the structure is not really good enough.
My recommendation for the approach is this:
- Set the values ββthat you know before fetching data from the database in the object, and the rest that you do not set to any defaults or do not set them as optional values.
- Store the object in scope and then call the load in the closure (asynchronously of course) - which will take the object in the closure and because by then the object is saved in the scope, you will be able to access directly
savedObject.realm
and you should be able to write correctly without exceptions.
source to share
TL; dg; you cannot assign a persistent Realm property to an uncontained Realm object
It would be helpful to know what it is doing Foo.get(_:)
. I assume it creates a persistent Realm object (maybe even on a different thread), whereas the object is Bar
never persisted (the call super.init()
will just create a self-contained object, not tied to any realm).
If my assumptions Foo.get(_:)
are correct, just create a standalone in this function Foo
. Then you can set it as a property Bar
outside of any write transaction.
source to share