Eski çekirdek veri modelim alanına sahiptir ve bu kodu NSNumber
olarak değiştirmek istiyorum. Apple belgelerine ve SO üzerinde birkaç benzer sorular ve diğer bloglar (söz sonundaki referanslara bakınız) okumakÇekirdek verileri özel geçiş
Ama ne olursa olsun, ben de aynı hatayı almaya devam:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Mismatch between mapping and source/destination models'
Ben sadece var Modelin 2 sürümü ve zaman ve tekrar doğruladı kaynak ve hedef modelleri doğru.
Tüm değişikliklerimi iptal ettim ve yeni bir model, eşleştirmeler ve nesneler (NSManagedObject
alt sınıflar) yeniden oluşturdum. Neredeyse 2 gün boyunca bunun üzerinde sıkışıp kaldım ve yaptığım şey hakkında hiçbir fikrim yok. Yanlış yaptığım herhangi bir işaretçi büyük takdir edilecektir.
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Old.sqlite"];
NSError *error = nil;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSString *sourceStoreType = NSSQLiteStoreType;
NSURL *sourceStoreURL = storeURL;
NSURL *destinationStoreURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"New.sqlite"];
NSString *destinationStoreType = NSSQLiteStoreType;
NSDictionary *destinationStoreOptions = nil;
NSDictionary *sourceMetadata =
[NSPersistentStoreCoordinator metadataForPersistentStoreOfType:sourceStoreType
URL:sourceStoreURL
error:&error];
if (sourceMetadata == nil) {
NSLog(@"source metadata is nil");
}
NSManagedObjectModel *destinationModel = [_persistentStoreCoordinator managedObjectModel];
BOOL pscCompatibile = [destinationModel
isConfiguration:nil
compatibleWithStoreMetadata:sourceMetadata];
if (pscCompatibile) {
// no need to migrate
NSLog(@"is compatible");
} else {
NSLog(@"is not compatible");
NSManagedObjectModel *sourceModel =
[NSManagedObjectModel mergedModelFromBundles:nil
forStoreMetadata:sourceMetadata];
if (sourceModel != nil) {
NSLog(@"source model is not nil");
NSMigrationManager *migrationManager =
[[NSMigrationManager alloc] initWithSourceModel:sourceModel
destinationModel:destinationModel];
NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@"MyMigrationMapping" withExtension:@"cdm"];
NSMappingModel *mappingModel = [[NSMappingModel alloc] initWithContentsOfURL:fileURL];
NSArray *newEntityMappings = [NSArray arrayWithArray:mappingModel.entityMappings];
for (NSEntityMapping *entityMapping in newEntityMappings) {
entityMapping.entityMigrationPolicyClassName = NSStringFromClass([ConvertDateToNumberTransformationPolicy class]);
}
mappingModel.entityMappings = newEntityMappings;
BOOL ok = [migrationManager migrateStoreFromURL:sourceStoreURL
type:sourceStoreType
options:nil
withMappingModel:mappingModel
toDestinationURL:destinationStoreURL
destinationType:destinationStoreType
destinationOptions:nil
error:&error];
if (ok) {
storeURL = destinationStoreURL;
}
} else {
NSLog(@"e nil source model");
}
}
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,
nil];
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return _persistentStoreCoordinator;
}
Benim özel NSEntityMigration
sınıfı:
- (BOOL)createDestinationInstancesForSourceInstance:(NSManagedObject *)sInstance
entityMapping:(NSEntityMapping *)mapping
manager:(NSMigrationManager *)manager
error:(NSError **)error
{
// Create a new object for the model context
NSManagedObject *newObject =
[NSEntityDescription insertNewObjectForEntityForName:[mapping destinationEntityName]
inManagedObjectContext:[manager destinationContext]];
NSArray *arrayOfKeys = @[@"startDate", @"endDate", @"creationTime", @"timeStamp"];
for (NSString *key in arrayOfKeys) {
// do our transfer of NSDate to NSNumber
NSDate *date = [sInstance valueForKey:key];
NSLog(@"Key: %@, value: %@", key, [date description]);
// set the value for our new object
[newObject setValue:[NSNumber numberWithDouble:[date timeIntervalSince1970]] forKey:key];
}
// do the coupling of old and new
[manager associateSourceInstance:sInstance withDestinationInstance:newObject forEntityMapping:mapping];
return YES;
}
Bazı referanslar:
- Example or explanation of Core Data Migration with multiple passes?
- Core Data - Default Migration (Manual)
- http://www.preenandprune.com/cocoamondo/?p=468
- http://www.timisted.net/blog/archive/core-data-migration/
@Nishant com.apple.CoreData.MigrationDebug tercihini 1 olarak ayarlamayı denediniz mi? – Willeke
@Willeke Evet Bunu yaptım. Açıkça bana bu eşleşmelerin neden eşlemeler arasında olduğunu anlatmıyor. – Nishant
Buradan neden hata gördüğünüzü söylemek çok zor. Yeni bir soru sorun ve veri modeline ne değiştirdiğinizi, varsayılan haritalama modeline ne değiştirdiğinizi, kodda yaptığınız şeyi ve benzer sorunun ne olduğunu anlatın. – Willeke