Люди,
Легкая миграция не работает для меня 100% времени в этой строке:
[persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]
с ошибкой:
Error: Error Domain=NSCocoaErrorDomain Code=134130 UserInfo=0x4fbff20 "Operation could not be completed. (Cocoa error 134130.)"
"Can't find model for source store";
Вот мой контекст, модель и постоянное хранилище управляемых объектов:
- (NSManagedObjectContext *) managedObjectContext {
if (managedObjectContext != nil) {
return managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
managedObjectContext = [[NSManagedObjectContext alloc] init];
[managedObjectContext setPersistentStoreCoordinator: coordinator];
}
return managedObjectContext;
}
- (NSManagedObjectModel *)managedObjectModel {
if (managedObjectModel != nil) {
return managedObjectModel;
}
managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];
return managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (persistentStoreCoordinator != nil) {
return persistentStoreCoordinator;
}
NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"Locations.sqlite"]];
NSError *error;
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
// Allow inferred migration from the original version of the application.
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
NSLog(@"Error: %@",error);
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return persistentStoreCoordinator;
}
У меня есть две версии моей модели в моем проекте: версия 4 и версия 5. Если я установлю свою версию 4 по умолчанию, она отлично работает. Если я выберу "Дизайн → Модель данных → Добавить версию модели" (как описано этот пост), внесите изменения, Design → Data Model → Set Current Версия, сборка и запуск, она потерпит неудачу с вышеупомянутой ошибкой "Невозможно найти модель для источника". Установите модель обратно в версию 4, без проблем, addPersistentStoreWithType. В качестве альтернативы, если я добавлю версию модели и не вношу никаких изменений, просто перейдите от версии 4 к 5 без добавления каких-либо новых полей, никаких проблем. Если я попытаюсь перейти от 5 до 6, вышеназванная ошибка.
Этот код не работает как на Simulator, так и на телефоне. Я прочитал несколько рецептов, призывающих удалить и переустановить приложение, которое работает как для Simulator, так и для телефона, но я боюсь, что когда я выпущу его для реальных пользователей, он сломает мою установленную базу, так как они не смогут удалить и переустановить - App Store будет автоматически обновлять их.
Этот код работал в предыдущих выпусках без каких-либо изменений с моей стороны - отсюда моя способность сделать все до версии 4. Недавно я обновился до создания XCode 3.2.3 для iOS4, что может иметь какое-то отношение к этому,
Есть ли у кого-нибудь еще этот вопрос внезапно сейчас, как я? Кто-нибудь сумел обойти это? Спасибо.
PS. Для гуглеров, которые спотыкаются на этой странице, вот все соответствующие страницы, которые вы можете рассмотреть, ниже. К сожалению, ни одна из них не решила мою проблему.
- Внедрение "Автоматическая легкая миграция" для Core Data (iPhone)
- http://iphonedevelopment.blogspot.com/2009/09/core-data-migration-problems.html
- https://stackoverflow.com/info/2925918/iphone-core-data-lightweight-migration-error-reason-cant-find-model-for-sour
- Основные данные iPhone "Автоматическая легкая миграция"
- http://www.iphonedevsdk.com/forum/iphone-sdk-development/38545-coredata-migration-issues.html
UPDATE
Хотя это не является реальным исправлением, он избегает сценария сбойного клиента: просто удалите файл базы данных:
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
// Delete file
if ([[NSFileManager defaultManager] fileExistsAtPath:storeUrl.path]) {
if (![[NSFileManager defaultManager] removeItemAtPath:storeUrl.path error:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error])
{
// Handle the error.
NSLog(@"Error: %@",error);
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
ОБНОВЛЕНИЕ 2
Вот что происходит, когда я проверяю VersionInfo.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSManagedObjectModel_CurrentVersionName</key>
<string>Profile 5</string>
<key>NSManagedObjectModel_VersionHashes</key>
<dict>
<key>Profile</key>
<dict>
<key>Profile</key>
<data>
ZIICGgMBreuldkPXgXUhJwKamgwJzESM5FRTOUskomw=
</data>
</dict>
<key>Profile 2</key>
<dict>
<key>Profile</key>
<data>
tEB7HrETWOSUuoeDonJKLXzsxixv8ALHOoASQDUIZMA=
</data>
</dict>
<key>Profile 3</key>
<dict>
<key>Profile</key>
<data>
qyXOJyKkfQ8hdt9gcdFs7SxKmZ1JYrsXvKbtFQTTna8=
</data>
</dict>
<key>Profile 4</key>
<dict>
<key>Profile</key>
<data>
lyWDJJ0kGcs/pUOModd3Q1ymDvdRiNXui4NCpLxDFSw=
</data>
</dict>
<key>Profile 5</key>
<dict>
<key>Profile</key>
<data>
V4PyRK1ezj3xK1QFRCTVzGOqyJhEb7FRMzglrTsP0cI=
</data>
</dict>
</dict>
</dict>
</plist>
Вот код, который я написал для проверки моей модели (обратите внимание, что мне нужно было выйти и добавить кодировщик base64, поскольку это то, что находится в файле VersionInfo.plist)
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
NSDictionary *storeMeta = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:nil URL:storeUrl error:&error];
NSLog(@"%@",storeMeta);
id someObj = [[storeMeta objectForKey:@"NSStoreModelVersionHashes"] objectForKey:@"Profile"];
NSLog(@"%@",someObj);
NSLog(@"%@",[NSString base64StringFromData:someObj length:[someObj length]]);
И вот вывод отладки:
{
NSPersistenceFrameworkVersion = 310;
NSStoreModelVersionHashes = {
Profile = <97258324 9d2419cb 3fa5438c a1d77743 5ca60ef7 5188d5ee 8b8342a4 bc43152c>;
SerializedMessage = <4530863c d943479a edfb4dfb 5059c28d d6137dc4 d1153d36 ed52be49 11074f13>;
};
NSStoreModelVersionHashesVersion = 3;
NSStoreModelVersionIdentifiers = (
);
NSStoreType = SQLite;
NSStoreUUID = "823FD306-696F-4A0F-8311-2792825DC66E";
"_NSAutoVacuumLevel" = 2;
}
<97258324 9d2419cb 3fa5438c a1d77743 5ca60ef7 5188d5ee 8b8342a4 bc43152c>
lyWDJJ0kGcs/pUOModd3Q1ymDvdRiNXui4NCpLxDFSw=
Как вы можете видеть, последняя строка, начинающаяся с "ly", соответствует профилю 4 в VersionInfo.plist... поэтому я не вижу причин, по которым он должен быть неудачным. Любые другие идеи?