wake-up-neo.net

iPhone Core Data "Automatische Leichtmigration"

Ich versuche, eine App zu aktualisieren, die einen Kerndatenspeicher implementiert. Ich füge einer der Entitäten ein Attribut hinzu. 

Ich habe der Delegatklasse den folgenden Code hinzugefügt:

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

Dies war von der folgenden URL: Doc

Beim Ausführen des Codes wird folgende Fehlermeldung angezeigt:

2009-12-01 20: 04: 22.877

Shoppee [25633: 207] Fehler: Fehler

Domäne = NSCocoaErrorDomain Code = 134130

UserInfo = 0x1624d20 "Vorgang konnte nicht abgeschlossen werden. (Cocoa-Fehler 134130.)" 2009-12-01 20: 04: 22.879 Shoppee [25633: 207] Fehler nicht gelöst Fehlerdomäne = NSCocoaErrorDomain-Code = 134130 UserInfo = 0x1624d20 "Vorgang konnte nicht abgeschlossen werden. (Cocoa-Fehler 134130.)", { URL = Datei: //localhost/Users/Eric/Library/Application%20Support/iPhone%20Simulator/User/Applications/A8A8FB73-9AB9-4EB7-8F83-82F5B4467AF1/Documents/MyApp.sqlite; Metadaten = { NSPersistenceFrameworkVersion = 241; NSStoreModelVersionHashes = { Item = <869d4b20 088e5c44 5c345006 87d245cd 67ab9bc4 14cadf45 180251e9 f741a98f>; Store = <47c250f4 895e6fd1 5033ab42 22d2d493 7819ba75 3c0acffc 2dc54515 8deeed7a>; }; NSStoreModelVersionHashesVersion = 3; NSStoreModelVersionIdentifiers = (); NSStoreType = SQLite; NSStoreUUID = "8DC65301-3BC5-42BE-80B8-E44577B8F8E1"; }; reason = "Modell für Quellspeicher nicht gefunden"; }

Es scheint, dass ich irgendwie das ursprüngliche Datenmodell verwenden muss, aber ich bin mir nicht sicher, wie ich das tun soll. Irgendwelche Vorschläge?

63
Eric

Zusammenfassend/vollständige Anleitung:

  1. Bevor Sie Änderungen vornehmen, erstellen Sie eine neue Modellversion. 

    In Xcode 4: Wählen Sie Ihren .xcdatamodel -> Editor -> Modellversion hinzufügen aus. 

    In Xcode 3: Design -> Datenmodell -> Modellversion hinzufügen. 

    Sie sehen, dass ein neuer .xcdatamodel in Ihrem .xcdatamodeld -Ordner erstellt wird (der auch erstellt wird, wenn Sie keinen haben).

  2. Sparen.

  3. Wählen Sie Ihren neuen .xcdatamodel aus, und nehmen Sie die Änderung vor, die Sie gemäß der Lightweight Migration -Dokumentation anwenden möchten.

  4. Sparen.

  5. Setzen Sie das aktuelle/aktive Schema auf das neu erstellte Schema. 

    Wenn der Ordner .xcdatamodeld ausgewählt ist:

    In der Seitenleiste von Xcode 4: Dienstprogramme -> Dateiinspektor -> Versioniertes Kerndatenmodell -> Wählen Sie das neue Schema aus. 

    In Xcode 3: Design> Datenmodell> Aktuelle Version setzen. 

    Das grüne Häkchen auf dem Symbol .xcdatamodel wird in das neue Schema verschoben.

  6. Sparen.

  7. Implementieren Sie den erforderlichen Code, um die Migration zur Laufzeit durchzuführen. 

    Ersetzen Sie NSPersistentStoreCoordinator für den Parameter options durch den folgenden Code, wenn Ihre nil (normalerweise AppDelegate-Klasse) erstellt wird:

    [NSDictionary dictionaryWithObjectsAndKeys:
                      [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, 
                      [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]
    
  8. Führen Sie Ihre App aus. Wenn es keinen Absturz gibt, sind Sie wahrscheinlich erfolgreich migriert :)

  9. Nach einer erfolgreichen Migration kann der Migrationscode (Schritt 7) entfernt werden. (Es ist Sache des Entwicklers, zu bestimmen, wann die Benutzer einer veröffentlichten App als migriert gelten können.)

WICHTIG: Alte Modellversionen/-schemas nicht löschen. Core Data benötigt die alte Version, um auf die neue Version zu migrieren.

142
Stian Høiland

Ich habe es herausgefunden. 

Design> Datenmodell> Modellversion hinzufügen

26
Eric

Auch für Googlers müssen Sie Folgendes tun (vorausgesetzt, Sie haben bereits eine Lightweight-Migration eingerichtet):

  1. Bevor Sie Änderungen vornehmen, machen Sie Design -> Datenmodell -> Modellversion hinzufügen (Sie werden sehen, dass ein neuer .xcdatamodel in Ihrem .xcdatamodeld-Ordner erstellt wird)
  2. Sparen
  3. Nehmen Sie Ihre Änderung vor
  4. Sparen
  5. App ausführen

Schritt # 1 ist entscheidend für diese Arbeit. Ich bin auf dieses Problem gestoßen, weil ich diese Schritte befolgt habe, um ein neues Feld hinzuzufügen. Das hat funktioniert. Ich habe ein zweites neues Feld hinzugefügt, aber "Add Model Version" vergessen, und die Dinge sind explodiert.

15
davetron5000

Auch für Googler. Einfache Regel, niemals eine alte nummerierte Version löschen/bearbeiten. Wenn Sie eine Modellversion hinzufügen, erhöht sich das Nummernsuffix um 2..3..4, dh 2 ist die älteste 3 nächste usw., aber die zu bearbeitende Aktuelle Version ist die nicht nummerierte Version.

Löschen Sie keine alten Modellversionen, da Benutzer mit einer früheren Datenbankversion, die eine ältere Modellversion verwendet, nicht auf Ihr aktuelles Datenbankmodell migrieren können, ohne alte und neueste Schemas zu vergleichen.

11
Gmu

Nur eine Anmerkung für diejenigen, die diesem Googling begegnen. Es scheint, dass Sie selbst bei der automatischen (magischen) Migration immer noch eine Version Ihres ursprünglichen Stores und eine neue erstellen und die neue als aktuelle Version festlegen müssen.

5
rustyshelf

Bisher sehe ich nur, wie ich die Fehlermeldung vermeiden kann.

Aber wie können wir es beheben - falls wir die Dinge schon vermasselt haben? 

Die folgende Lösung das Problem behoben, aber Sie verlieren die Daten in der DB:

Löschen/Umbenennen der sqlite-Datei der bereitgestellten/installierten Anwendung.
.__ Die Dateinamen und der Speicherort werden direkt nach der Fehlermeldung angegeben. z.B.:

reason = Modell für Quellspeicher nicht gefunden}, {
URL= "file: //localhost/Users/yourName/Library/Application%20Support/iPhone%20Simulator/4.3/Applications/62F342D4-F007-4F6F-96D2-68F902D3719A/Documents/Locations.sqlat

1

Was Sie bei einer leichten Migration beachten sollten -

Wenn Sie vorhaben, Attribute umzubenennen/zu ändern, müssen Sie den Wert "Umbenennungs-ID" im neuen oder im alten Modell festlegen. Um Apples eigenes Beispiel zu verwenden, wählen Sie in XCode 4.3 im neuen Modell paintColor aus> wechseln Sie in den Datenmodell-Inspektor>> Setzen Sie das Feld "Umbenennungs-ID" im Abschnitt "Versionierung" auf Farbe. Wenn ich diesen Schritt nicht mache, führte dies zu einem Laufzeitfehler. Der gleiche Fehler ist auch hier behandelt . Als neuer Benutzer darf ich keine Bilder posten. Daher ist hier ein imgur link (kein Spam, wirklich).

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

Sie können diesen Fehler auch erhalten, wenn Sie eine Änderung am Datenmodell vornehmen und auf einer installierten App mit einer anderen Version der sqlite-Datei ausführen. In diesem Fall löschen Sie einfach die installierte App und führen Sie sie erneut aus.

0
John Mead