iosswiftrealmdatabase-migrationrealm-migration

Casting error in Realm migration to change property Double to List<CustomObject>


What I need is to create a migration to change discount:Double to discounts:List<Discount>() based on the following code.

Here is the Existing Object: This is how my Realm Object looks right now.

class Item:Object{
    @objc dynamic var itemName:String = "Some Name"
    @objc dynamic var discount:Double = 0 // need to change this property
}

Here is how I'm trying to make the change.

New Object:

class Discount: Object {
    @objc dynamic var name:String = "Discount Name"
    @objc dynamic var discount:Double = 0.0
}

Modified Object with one-to-manyrelation.

class Item:Object{
    @objc dynamic var itemName:String = "Some Name"
    let discounts = List<Discount>()
}

Migration

    Realm.Configuration.defaultConfiguration = Realm.Configuration(
        schemaVersion: 3,
        migrationBlock: { migration, oldSchemaVersion in
            if (oldSchemaVersion < 3) {
                migration.enumerateObjects(ofType: Item.className()) { oldObject, newObject in

                    let oldDiscount = oldObject!["discount"] as! Double

                    let discount = Discount()
                    discount.amount = oldDiscount

                    let discounts = newObject!["discounts"] as! List<Discount>
                    discounts.append(discount)
            }
        }
    })

I'm getting error:

Could not cast value of type RealmSwift.List<RealmSwift.DynamicObject>(0x1c8910068) to RealmSwift.List<AppName.Discount> (0x1c890f6a0).

Again, the question is, how can I create a migration to change discount:Double to discounts:List<Discount>()?


Solution

  • You can migrate the discount property into the new discount list as a List like [oldDiscount]

    Here's the code. I renamed some of the objects to make it a bit more clear as the re-use of the word 'discount' to refer to the class and the property was confusing.

    let vers = UInt64(1)
    let config = Realm.Configuration( schemaVersion: vers, migrationBlock: { migration, oldSchemaVersion in
         if (oldSchemaVersion < vers) {
             print("performing migration")
             migration.enumerateObjects(ofType: ItemClass.className()) { oldItem, newItem in
                let oldDiscount = oldItem!["discount"] as? Double ?? 0.0
    
                let d = DiscountClass()
                d.name = "Test"
                d.discount = oldDiscount
    
                newItem!["discountList"] = [d]
             }
         } else {
            print("no migration needed")
        }
     })