7

If I want to use a custom migration policy for a given entity, I believe I have to prefix the class name by the product module name, as shown on the following image:

Mapping Model Inspector

How can I manage to handle multiple targets?

I tried using the following entry: $(PRODUCT_MODULE_NAME).VisitToVisitPolicy but this does not seem to work. I still have the possibility to duplicate the mapping model, one for each target, but that does not feel right.

adauguet
  • 988
  • 8
  • 18

2 Answers2

2

Had the same problem trying to share model files between app and test targets. Almost gave up and thought I'll have to use your duplicate hack, but thankfully found a sane way:

// Get mapping model
let mappingModel = NSMappingModel(from: [.main], 
                        forSourceModel: sourceModel, 
                      destinationModel: destinationModel)!

// Get migration policy class name that also includes the module name
let fullClassName = NSStringFromClass(NSEntityMigrationPolicySubclass.self)

// Set policy here (I have one policy per migration, so this works)
mappingModel.entityMappings.forEach { 
    $0.entityMigrationPolicyClassName = fullClassName 
}

// Migrate
let manager = NSMigrationManager(sourceModel: sourceModel, 
                            destinationModel: destinationModel)

try! manager.migrateStore(from: sourceURL, 
                    sourceType: NSSQLiteStoreType, 
                       options: nil, 
                          with: mappingModel, 
              toDestinationURL: destinationURL, 
               destinationType: NSSQLiteStoreType, 
            destinationOptions: nil)
Alexander Borisenko
  • 1,574
  • 1
  • 12
  • 16
0

I had the same problem. My solution is similar to Alexander's and it should work with multiple migration policies (one per entity). You need to set Custom Policy to class name without any namespace and after obtaining mapping model I do this:

    mapping.entityMappings.forEach {
        if let entityMigrationPolicyClassName = $0.entityMigrationPolicyClassName,
            let namespace = Bundle.main.infoDictionary?["CFBundleExecutable"] as? String {
            $0.entityMigrationPolicyClassName = "\(namespace).\(entityMigrationPolicyClassName)"
        }
    }
tahavath
  • 234
  • 2
  • 9