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

+3


source to share


2 answers


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.
+4


source


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.

+1


source







All Articles