iPhone Core Data Автоматична лека миграция

Опитвам се да актуализирам приложение, което внедрява основно хранилище на данни. Добавям атрибут към един от обектите.

Добавих следния код към моя делегатен клас:

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {

    if (persistentStoreCoordinator != nil) {
        return persistentStoreCoordinator;
    }

    NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"Shoppee.sqlite"]];

    NSError *error = nil;
    persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

    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;
}

Това беше от следния URL адрес: Документ

Получавам следната грешка при изпълнение на кода:

2009-12-01 20:04:22.877

Shoppee [25633:207] Грешка: Грешка

Домейн=NSCocoaErrorДомен Код=134130

UserInfo=0x1624d20 "Операцията не може да бъде завършена. (Грешка в Cocoa 134130.)" 2009-12-01 20:04:22.879 Shoppee[25633:207] Неразрешена грешка Error Domain=NSCocoaErrorDomain Code=134130 UserInfo=0x1624d20 "Oper не може да бъде завършено. (Грешка в Cocoa 134130.)", { URL = file://localhost/Users/Eric/Library/Application%20Support/iPhone%20Simulator/User/Applications/A8A8FB73-9AB9-4EB7-8F83-82F5B4467AF1/Documents/MyApp .sqlite; метаданни = { NSPersistenceFrameworkVersion = 241; NSStoreModelVersionHashes = { Елемент = ‹869d4b20 088e5c44 5c345006 87d245cd 67ab9bc4 14cadf45 180251e9 f741a98f>; Магазин = ‹47c250f4 895e6fd1 5033ab42 22d2d493 7819ba75 3c0acffc 2dc54515 8deeed7a>; }; NSStoreModelVersionHashesVersion = 3; NSStoreModelVersionIdentifiers = (); NSStoreType = SQLite; NSStoreUUID = "8DC65301-3BC5-42BE-80B8-E44577B8F8E1"; }; причина = "Не мога да намеря модел за магазин източник"; }

Изглежда, че по някакъв начин трябва да включа оригиналния модел на данни, но не съм сигурен как да направя това. Някакви предположения?


person Eric    schedule 02.12.2009    source източник


Отговори (9)


За обобщение/Пълно ръководство:

  1. Преди да направите каквато и да е промяна, създайте нова версия на модела.

    В Xcode 4: Изберете своя .xcdatamodel -> Редактор -> Добавяне на версия на модела.

    В Xcode 3: Дизайн -> Модел на данни -> Добавяне на версия на модела.

    Ще видите, че е създаден нов .xcdatamodel във вашата папка .xcdatamodeld (която също е създадена, ако нямате такава).

  2. Запазване.

  3. Изберете вашия нов .xcdatamodel и направете промяната, която искате да използвате в съответствие с документацията за лека миграция.

  4. Запазване.

  5. Задайте текущата/активна схема на новосъздадената схема.

    С избрана папка .xcdatamodeld:

    В Xcode 4: Странична лента на помощните програми -> Инспектор на файлове -> Версионен модел на основни данни -> Изберете новата схема.

    В Xcode 3: Дизайн > Модел на данни > Задаване на текуща версия.

    Зелената отметка върху иконата .xcdatamodel ще се премести към новата схема.

  6. Запазване.

  7. Внедрете необходимия код за извършване на миграция по време на изпълнение.

    Където е създаден вашият NSPersistentStoreCoordinator (обикновено клас AppDelegate), за параметъра options заменете nil със следния код:

    [NSDictionary dictionaryWithObjectsAndKeys:
                      [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, 
                      [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]
    
  8. Стартирайте приложението си. Ако няма срив, вероятно сте мигрирали успешно :)

  9. Когато сте мигрирали успешно, кодът за миграция (стъпка 7) може да бъде премахнат. (От разработчика зависи кога потребителите на публикувано приложение могат да се считат за мигрирани.)

ВАЖНО: Не изтривайте стари версии/схеми на модели. Core Data се нуждае от старата версия, за да мигрира към новата версия.

person Stian Høiland    schedule 02.12.2011
comment
Наистина ли е необходима стъпка 9? И ако да защо? - person CGee; 31.08.2012
comment
Опитах се да изтрия файл със схеми на стар модел, след което стартирах приложението, изглежда работи добре. Не знам защо. (xcode4.6) - person tristan; 28.02.2013
comment
Благодаря ви и +1! Не забравяйте идентификатора за преименуване, когато преименувате атрибути или обекти... - person Christoph; 28.05.2013
comment
Благодаря ти! +1! имам малък проблем: имам приложение, базирано на документи, и моят документ Е базата данни. Заседнал съм в точка 7, тъй като не знам къде, как и какъв код да внедря. Благодаря! - person sharkyenergy; 22.08.2013
comment
+1 за стъпка 3! Получих тази грешка, когато преименувах обект и релация. Документацията, свързана в стъпка 3, ми помогна да преименувам по правилния начин и да отстраня този проблем. - person Bocaxica; 07.07.2014
comment
Как да изтрия новосъздадения? Сякаш създадох версия 2, но тя не е правилната. Така че искам да го изтрия и да направя отново тази версия? - person Swayambhu; 24.04.2015
comment
Един проблем, с който се сблъсках: След стъпка 1 файлът на модела се премества в директория, която Xcode обработва вместо вас. Компилираният модел обаче ще има и различно файлово разширение от сега, което е momd вместо mom. Може да се наложи да адаптирате своя [[NSBundle mainBundle] URLForResource:@"ModelName" withExtension:@"mom"] код съответно. Възможно е това да е само проблем с наследения код и приложенията, генерирани от по-нови шаблони, използват структурата на директорията от самото начало. - person hagi; 01.12.2015

Разбрах го.

Дизайн > Модел на данни > Добавяне на версия на модела

person Eric    schedule 02.12.2009
comment
Имам абсолютно същия проблем. Опитах много различни неща, но все още получавам същата причина = Не мога да намеря модел за грешка в хранилището на източника. Когато вие и другите плакати казвате, че трябва да добавите оригиналния магазин, какво имате предвид? публикувах: stackoverflow.com/questions/2925918/ - person tony.tc.leung; 28.05.2010
comment
Обърнете внимание, че в Xcode 4 тази опция от менюто я няма... автоматична ли е? - person makdad; 23.06.2011
comment
@makdad - Не. За Xcode 4 изберете своя xcdatamodeld в дървото на проекта и след това изберете Редактор -› Добавяне на версия на модел... от лентата с менюта - person dreyln; 23.07.2011

Отново за служители на Google, това е, което трябва да направите (ако приемем, че вече сте настроили Lightweight Migration):

  1. Преди да направите промени, Направете дизайн -> Модел на данни -> Добавяне на версия на модел (ще видите, че е създаден нов .xcdatamodel във вашата папка .xcdatamodeld)
  2. Запазване
  3. Направете вашата промяна
  4. Запазване
  5. Стартирайте приложението

Стъпка №1 е от решаващо значение за осъществяването на тази работа. Сблъсках се с този проблем, защото бях следвал тези стъпки, за да добавя ново поле. Това проработи. Добавих второ ново поле, но забравих да "Добавяне на версия на модела" и нещата се взривиха.

person davetron5000    schedule 27.06.2010
comment
Докато се опитвах да преименувам атрибут, попаднах на тази публикация, която очертава целия процес стъпка по стъпка. Надяваме се, че ще помогне на други, които не са наясно с целия процес. mobile.tutsplus.com/tutorials/iphone/ - person Jason George; 06.07.2011

Също така за потребители на Google.. Просто правило, никога не изтривайте/редактирайте стари номерирани версии. Когато добавите версия на модела, числовият суфикс ще се увеличи като 2..3..4, което означава, че 2 е най-старият, 3 следващ и т.н., но текущата за редактиране е неномерираната версия.

Не изтривайте старите версии на модела, тъй като потребителите с предишна база данни, използващи версия на стар модел, няма да могат да мигрират към най-новия модел на база данни, без да сравняват стари и най-нови схеми.

person Gmu    schedule 18.01.2010

Само бележка за тези, които се натъкват на това търсене в Гугъл, изглежда, че дори при автоматична (магическа) миграция все още трябва да създадете версия на оригиналния си магазин и нов, и да зададете новия като текуща версия.

person rustyshelf    schedule 08.12.2009
comment
можеш ли да разясниш това малко повече? Какво имаш предвид да създадеш версия на оригиналния си магазин и нова? Трябва ли просто да направя StationStore 3.xcdatamodel? - person tony.tc.leung; 28.05.2010
comment
да, и след това използвайте Дизайн -> Модел на данни -> Задаване на текуща версия, докато тази нова версия е маркирана - person rustyshelf; 03.06.2010

Засега виждам само как да избегна съобщението за грешка.

Но как да го поправим - в случай че вече сме объркали нещата??

Следното решение коригира проблема, но ще загубите данните в DB:

Изтриване/преименуване на sqlite файла на разгърнатото/инсталирано приложение.
Имената на файловете и местоположението се дават директно след съобщението за грешка. напр.:

причина=Не мога да намеря модел за магазин източник}, {
URL = "file://localhost/Users/yourName/Library/Application%20Support/iPhone%20Simulator/4.3/Applications/ 62F342D4-F007-4F6F-96D2-68F902D3719A/Documents/Locations.sqlite";

person Thorsten Niehues    schedule 01.08.2012

Нещо, което трябва да имате предвид, когато правите лека миграция -

Ако планирате да преименувате/модифицирате атрибути, не забравяйте да зададете стойността „Идентификатор на преименуване“ в новия или в стария модел. За да използвате собствения пример на Apple, в XCode 4.3 изберете paintColor в новия модел > превключете към Data Model Inspector > Задайте полето „Renaming ID“ на Color в раздела „Versioning“. За мен неизпълнението на тази стъпка доведе до грешка по време на изпълнение. Същата грешка също е разгледана тук. Като нов потребител нямам право да публикувам изображения, така че ето imgur връзка (не спам, наистина).

    (Cocoa error 134140.)" UserInfo=0x622b350 {reason=Can't find or automatically infer mapping model for migration
person Sai Ramachandran    schedule 03.02.2013

Можете също да получите тази грешка, когато правите промяна в модела на данни и работите на инсталирано приложение, което има различна версия на sqlite файла. В този случай просто изтрийте инсталираното приложение и го стартирайте отново.

person John Mead    schedule 21.03.2013

Само в случай, че някой се сблъска с този сценарий и нито едно от горните не работи... Изтривах приложението си от симулатора, почиствах и т.н., но нищо нямаше да работи. Трябваше да отида в директорията на симулатора и ръчно да заредя файла .sqlite, за да накарам приложението да работи отново. Никаква представа...

person shawnwall    schedule 18.06.2012