Search code examples
core-datacore-data-migration

change attribute type in entity and migrate the coredata


I need to change my CoreData attribute type from one type to another and generate the NSManagedObject subclasss manually. how to migrate the older version data to new one [enter image description here](https://i.sstatic.net/SZEkU.png)


Solution

  • since I need to change the attribute type this come under the heavyweight migration. so I need to add new version for my coredata.

    1.create new model version

    follow only for creating new model version

    Changing Attribute Type in Core Data with NSInferMappingModelAutomaticallyOption

    2.core datamapping model

    i) new file->mapping model (Core Data -> Mapping Model)

    ii) Choose the source (from model) and target (to model) version of your model

    iii) Create class(any name) as a subclass of NSEntityMigrationPolicy

    iv) override a method called createDestinationInstances. Below is my override method which transfer id from string to int

    override func createDestinationInstances(forSource sInstance: NSManagedObject, in mapping: NSEntityMapping, manager: NSMigrationManager) throws {
        
        
        let destMOC = manager.destinationContext
        guard let destinationEntity = mapping.destinationEntityName else{
            fatalError("Destination Entity name error")
        }
        print(destinationEntity)
        
        guard let sId = sInstance.value(forKey: "id") as? String,
              let name = sInstance.value(forKey: "name"),
              let dId = Int(sId)
        else{
            fatalError("source object didnt have valube id")
        }
        
        let context = NSEntityDescription.insertNewObject(forEntityName: "Entity", into: destMOC)
       
        context.setValue(name, forKey: "name")
        context.setValue(dId, forKey: "id")
    }
    

    v) Register this class as custom entity migration policy in the mapping model (Model.xcmappingmodel -> File inspector -> third column -> Custom policy put class name as Module.className

    (eg for registering class) enter image description here

    (eg for module and className)

    [enter image description here[3

    that's it. if you run it will migrate to new version.