Mam opartą na NSPersistentDocument aplikację Core Data, która jest kierowana na 10,5 Leopard i wyżej. Mam zamiar wydać aktualizację, która wprowadza zmiany w modelu danych, a zatem trzeba przenieść istniejące dokumenty do nowego modelu. Zmiany są stosunkowo proste i stworzyłem dla nich model odwzorowania. Zauważ, że nie próbuję wykonywać automatycznej, lekkiej migracji, mam model mapowania (niewielka migracja nie jest obsługiwana w systemie Leopard, ale moje zmiany modelu i tak go wykluczają). W moim NSPersistentDocument podklasy, zastąpić -configurePersistentStoreCoordinatorForURL...
następująco:Automatyczne migrowanie danych podstawowych nie powiedzie się w systemie Mac OS X 10.5, ale nie w wersji 10.6 lub 10.7
- (BOOL)configurePersistentStoreCoordinatorForURL:(NSURL *)url
ofType:(NSString *)fileType
modelConfiguration:(NSString *)configuration
storeOptions:(NSDictionary *)storeOptions
error:(NSError **)error
{
NSMutableDictionary *newOptions = (storeOptions ?
[NSMutableDictionary dictionaryWithDictionary:storeOptions] :
[NSMutableDictionary dictionary]);
[newOptions setObject:(id)kCFBooleanTrue forKey:NSMigratePersistentStoresAutomaticallyOption];
return [super configurePersistentStoreCoordinatorForURL:url
ofType:fileType
modelConfiguration:configuration
storeOptions:newOptions
error:error];
}
To działa prawidłowo na 10,6 i 10,7. Jednak w dniu 10.5 wywołanie [super configurePersistentStore...]
zgłasza wyjątek i kończy się niepowodzeniem. Błąd jest:
Error Domain=NSCocoaErrorDomain Code=134020 UserInfo=0x15812d70 "The model configuration used to open the store is incompatible with the one that was used to create the store."
Gdybym zamiast inicjować migrację ręcznie, przy użyciu tego kodu:
NSArray *bundles = [NSArray arrayWithObject:[NSBundle mainBundle]];
NSManagedObjectModel *sourceModel = [NSManagedObjectModel mergedModelFromBundles:bundles forStoreMetadata:sourceMetadata];
NSManagedObjectModel *destinationModel = [psc managedObjectModel];
NSMappingModel *mappingModel = [NSMappingModel mappingModelFromBundles:bundles forSourceModel:sourceModel destinationModel:destinationModel];
NSMigrationManager *migrationManager = [[[NSMigrationManager alloc] initWithSourceModel:sourceModel destinationModel:destinationModel] autorelease];
BOOL migrationSuccessful = [migrationManager migrateStoreFromURL:backupURL
type:NSXMLStoreType
options:storeOptions
withMappingModel:mappingModel
toDestinationURL:url
destinationType:NSXMLStoreType
destinationOptions:storeOptions
error:error];
return [psc addPersistentStoreWithType:NSXMLStoreType configuration:configuration URL:url options:storeOptions error:error] != nil;
migracja działa OK. Wolę jednak korzystać z migracji automatycznej, jeśli nie z innego powodu, niż z powodu czystszego kodu. Czy ktoś widział podobny problem z automatyczną migracją, która działa w wersji 10.6 lub nowszej, ale nie w wersji 10.5? Moje przypuszczenie jest takie, że jest to coś dość prostego, tak jak wbudowany kod migracyjny nie może znaleźć modelu mapowania z jakiegoś powodu, ale nie wiem, co to musi być.
Miałem dokładnie ten sam problem i rozwiązanie (wtedy dział marketingu zdecydował się zaprzestać obsługi OS X 10.5, więc skończyłem usuwanie ręcznego kodu migracji). – cdelacroix
Przypuszczam, że funkcje auto-migracji/solidności zostały dodane po 10.5 ... – nielsbot
Jestem pewien, że tak, ale nie robię niczego skomplikowanego na tyle, by oczekiwać, że zawiedzie. W każdym razie, w następnej wersji ta aplikacja będzie miała tylko 10,6+, więc nie jest już problemem, a w pewnym momencie usuniemy bieżący ręczny kod migracji. Mimo to dobrze byłoby wiedzieć, dlaczego tak się stało. –