How can I create embedded objects during migration?

I am in the process of migrating a few classes from using objects and relations to embedded objects. There is a lot of edge cases when converting doing this migration. I need to ensure that there is exactly one backlink for each object that will be converted otherwise the app will crash at startup.

After a lot of work, I have gotten the first case to work. I can successfully delete all orphaned objects. Now I need to handle the second case. Whenever there is an object that has multiple backlinks I want to keep the first backlink and for all subsequent backlinks I want to create a new object and copy all values over to the new object, which brings me to the question.

How can I create embedded objects during migration?

Here are two approaches I have tried

Option 1: Create an unattached object by value and replace the object in the second backlink

/**
  This will crash with error
  Object cannot be inserted unless the schema is initialized. This can happen if you try to insert objects
  into a RLMArray / List from a default value or from an overriden unmanaged initializer (`init()`)
**/
let listOfObjects = secondBacklinkObject?.dynamicList("linksToFirstObject")
let copy = DynamicObject(value: objectToCopyCopy)
listOfObjects?.replace(index:indexOfChildWithMultipleBacklinks, object: copy)

Option 2: Create a managed object and replace it in the second backlink

/**
  This will crash with error: Embedded objects cannot be created directly
*/
let listOfObjects = secondBacklinkObject?.dynamicList("linksToFirstObject")
let copy = migration.create("EmbeddedObject", value: objectToCopy)
listOfObjects?.replace(index:indexOfChildWithMultipleBacklinks, object: copy)

Is there an api for creating an embedded object during migration? If not, how can I prevent data loss in cases where there are multiple backlinks when converting “object” to embeddedobject? The example is in swift, but I will have the same question for Kotlin as well as the app is available on both platforms.

On Android there does seem to be an API for this in the DynamicRealm.createEmbedded. But this doesn’t seem to be available in the Swift SDK?

As there doesn’t seem to be a public API in Swift for creating embedded objects during migration, I created a feature request for it here https://github.com/realm/realm-cocoa/issues/7508.

Without this feature available in Swift I am not sure how to proceed with the migration :confused:

1 Like

Anyone from realm side care to explain what the public API for this is supposed to be like? Still waiting for the bug fix for this since november 2021 :confused:

Anyone? I did see 15 people click to the linked issue, so I assume I am not alone in having this problem.