3

I am doing a migration which requires removing objects from the realm and replacing them with a different type.

In short, I used to have a single type, and am now creating a hierarchy, so BaseItem now needs to be a DerivedItem.

I'm not sure the best way to accomplish this.

Here's what I am going to try:

setSchemaVersion(kSchemaVersion, Realm.defaultPath, { migration, oldSchemaVersion in
    if oldSchemaVersion == 0 {
        let realm = Realm()
        realm.write({ () -> Void in
            old = oldObject!    
            if old["type"] as! Int == 1 {
                let textItem = TextItem()
                textItem.text = old["text"] as! String
                copyBaseItemCommon(old, textItem)
                realm.add(textItem)
                realm.delete(newObject!)
     }
})

Are those add and deletes the way to go?

UPDATE:

Tried this and the code deadlocks in line 3: let realm = Realm()

Anyone know what the technique for doing this type of migration is?

voidref
  • 1,113
  • 11
  • 15

2 Answers2

11

When you download the Realm, you have an Example project. Open it and you have a demo for migration.

This is how they do the migration:

let migrationBlock: MigrationBlock = { migration, oldSchemaVersion in
    if oldSchemaVersion < 1 {
        migration.enumerate(Person.className()) { oldObject, newObject in
            if oldSchemaVersion < 1 {
                // combine name fields into a single field
                let firstName = oldObject!["firstName"] as! String
                let lastName = oldObject!["lastName"] as! String
                newObject?["fullName"] = "\(firstName) \(lastName)"
            }
        }
    }
}
setDefaultRealmSchemaVersion(1, migrationBlock)

If you check the documentation for migration, you'll see that you have some methods for create and delete in migration:

/**
    Create an `Object` of type `className` in the Realm being migrated.

    :param: className The name of the `Object` class to create.
    :param: object    The object used to populate the object. This can be any key/value coding
                      compliant object, or a JSON object such as those returned from the methods in
                      `NSJSONSerialization`, or an `Array` with one object for each persisted
                      property. An exception will be thrown if any required properties are not
                      present and no default is set.

    :returns: The created object.
    */
func create(className: String, value: AnyObject = default) -> RealmSwift.MigrationObject

/**
    Delete an object from a Realm during a migration. This can be called within
    `enumerate(_:block:)`.

    :param: object Object to be deleted from the Realm being migrated.
    */
func delete(object: RealmSwift.MigrationObject)

And you use them in the migration block like this migration.create("TextItem", oldObject!).

Remember that in migration, you use the migration object, and not the Realm.

voidref
  • 1,113
  • 11
  • 15
pteofil
  • 4,133
  • 17
  • 27
-3

are you using the updated realm?

Based on the documentation..

you should do like this>>

 let realm = Realm()

 realm.write
{
 realm.add(theObject)
 realm.delete(theObject)
}

Hope it helps!

zapzapzap
  • 17
  • 7