Realm Sync + SwiftUI: Object is already managed by another Realm. Use create instead to copy it into this Realm

The best way to exemplify this will be with the following code snippet

let config = Realm.Configuration.defaultConfiguration
let realm = try! Realm(configuration: config)
let list = List()
list.name = "list_\(Int.random(in: 0...100))"
try! realm.write {
   realm.add(list)
}
let frozenList = list.freeze()
try! realm.write {
   let household = Household()
   realm.add(household)
   household.name = "name_\(Int.random(in: 0...100))"
   household.lists.append(frozenList)
}

Even though list belongs to the same realm we are using to write household, when we append a frozen instance of list it throws the same error (Object is already managed by another Realm. Use create instead to copy it into this Realm.).
In our SwiftUI implementation, we try to avoid this by thawing the object before appending it to the list, but because in this case there is a nested object within the newly created object, we are not doing. Like in my previous post, the solution will be to do a recursive check for sub-objects when users try to append an object.

1 Like

@Diana_Maria_Perez_Af

Just a question and a comment in our use case - and maybe I misunderstand, but that example doesn’t appear to agree with the documentation;

which states

You must thaw both the object you want to append and the collection you want to append it to.

so this does not work (and shouldn’t because frozen objects cannot be modified, and appending is modifying)

household.lists.append(frozenList)

but you said

For clarification, are the SwiftUI wrappers (attempting to) unfreezing these objects while it’s a manual thing in Swift?

To me it all comes down to the phrasing of the error message Object is already managed by another Realm

A frozen object isn’t really a “managed object”; it can’t be modified, written or really have anything done with it other than passing it around and looking at it.

Why should I care about “another realms” if I just declared a single realm instance ?

If it’s thawed you get back the Realm is was spawned on, which would be the “single realm instance”.

If we’re adhering to the docs the code should be

try! realm.write {
   let household = Household()
   realm.add(household)
   household.name = "name_\(Int.random(in: 0...100))"
      let thawedList = frozenList.thaw() //this is "the same Realm" and "only one realm"
   household.lists.append(thawedList)
}

Frozen objects remain valid as long as the live realm that spawned them stays open

So this sounds like an issue specific to SwiftUI - in Swift, as long as we thaw object before writing etc, then we only ever have a “single realm instance” and don’t encounter that error message.

My code snippet was supposed to exemplify what is happening in our SwiftUI Implementation and why is throwing an error, this code should never be used.

Yep appending is inserting which it is internally modifying the object.

Because we freeze objects to be used in the view, so we don’t have thread issues. We also thaw this objects in case of a write operation.

I guess we could have a better error message for this. I’ll add to the note of the issue I opened to fix this.

Yep the issues is specific to our SwiftUI wrappers, I opened an issue to fix this.
I hope you now understand what is happening, we’ll have any update for this in the GitHub issue.

2 Likes

@Diana_Maria_Perez_Af

Wonderful explanation! Thanks for the reply and clarification.

1 Like

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.