Iam Wayne
Iam Wayne

Reputation: 561

Realm Migration: Migrating objects to another

I've added a new Model object to my realm objects and I am trying to move data from my old realm object properties to this new object.

In the old Schema, I have the following:

class Item: Object {
    @objc dynamic var image = ""
    @objc dynamic var coverImage = ""
    @objc dynamic var video = ""
}

In the new schema, I've added a new property called media so now it's looking this this

class Item: Object {
    @objc dynamic var image = ""
    @objc dynamic var coverImage = ""
    @objc dynamic var video = ""

    @objc dynamic var media: Media?
}

I've also added this new Model object:

class Media: Object {

    @objc dynamic var fullImage = ""
    @objc dynamic var thumbnailImage = ""
    @objc dynamic var video = ""

    var item = LinkingObjects(fromType: Item.self, property: "media")
}

My goal is to move the data from the old Item objects to the new Media objects.

I was trying to do something like this, but I don't know how to migrate that linking object, any help in the right direction would be appreciated.

 Realm.Configuration.defaultConfiguration = Realm.Configuration(
        schemaVersion: 1,
        migrationBlock: { migration, oldSchemaVersion in
            if (oldSchemaVersion < 1) {

                // enumerate first object
                migration.enumerateObjects(ofType: Item.className()) { oldItem, newItem in

                    let image = oldItem?["image"] as! String
                    let coverImage = oldItem?["coverImage"] as! String
                    let video = oldItem?["video"] as! String

                    //migrate second object
                    migration.enumerateObjects(ofType: Media.className(), { (oldMedia, newMedia) in

                    })
                }
            }
    })

Upvotes: 1

Views: 4663

Answers (2)

Jay
Jay

Reputation: 35648

When adding objects to a project, the migration is super simple. In this case you're not changing or adding data to existing or new properties so it's even easier.

All that needs to be done is to increment the schemaVersion and implement your migration block. Suppose the prior version was 1, increment that to 2.

let config = Realm.Configuration (
    schemaVersion: 2,
    migrationBlock: { migration, oldSchemaVersion in
        //nothing to do here since we not altering any data
})

Realm already knows your Object has data and that data will persist as it's not being altered. All of the Item objects will have the new media property added and linked to the new Media object.

See Local Migrations for more examples. The Updating values section is when you want to actually manipulate the existing data

Edit:

We now have a bit more information and what the OP is trying to do is to copy data from an existing object to a new object and then create a relationship between the objects. Here's the code that would do that.

The initial object is Item and the new object is Media. For this example I am copying the data in a Item property image to the Media property fullImage

let config = Realm.Configuration (
    schemaVersion: 1,
    migrationBlock: { migration, oldSchemaVersion in
        migration.enumerateObjects(ofType: Item.className() ) { oldObject, newObject in
            let image = oldObject!["image"] as! String
            let media = Media()
            media.fullImage = image
            newObject!["media"] = media
        }
})

Upvotes: 3

Craig Siemens
Craig Siemens

Reputation: 13266

You don't need to do anything with LinkingObjects, realm calculates those automatically when you query them.

All you'll need to do in your migration is set media to be a new Media object with the values you already have.

Other notes:

  • The second enumerateObjects isn't needed.
  • You can remove image, coverImage, and video from Item since you're moving those value to Media

Edit: This is what you would need to have in your migration.

let media = Media()
media.fullImage = oldItem?["image"] as! String
media.thumbnailImage = oldItem?["coverImage"] as! String
media.video = oldItem?["video"] as! String

newItem?["media"] = media

Upvotes: 2

Related Questions