Arbeiten mit Kerndaten Schemaversioning und leichte Migrationen

Nach dem Lesen der ersten Schritte mit Core Data sehen wir uns in der Funktionsweise von Core Data und in der Frage, wie wir uns bei der Entwicklung datenintensiver Anwendungen unterstützen können, aufgeklärt. Die Oberfläche war jedoch nur zerkratzt, und in einigen Anwendungen müssen Sie sich vielleicht fragen, wie Sie bestimmte Funktionen implementieren.

Meine Erfahrung mit Core Data

In den letzten Monaten habe ich mit Core Data an einem Haustierprojekt gearbeitet. Es ist eine Anwendung, mit der Daten von einer Remote-Service-API abgerufen, in Core Data gespeichert und in einer Sammlung von UITableViews angezeigt werden. Im Laufe der Entwicklung hat es sich von einem Property List-basierten Datenspeicher (* shudder *) zu einem Core Data SQL-Store entwickelt. Nach drei vollständigen Umbauten und vielen langen Nächten des Debugging ist meine Anwendung endlich ein schnelles, absturzfreies und speicherfreies Projekt. Die Verwendung von Core Data hat meine Bewerbung zu dem gemacht, was sie sein sollte, und ich werde viel von dem teilen, was ich in diesen und zukünftigen Artikeln mit Ihnen gelernt habe.

In diesem Artikel bauen wir auf der vorherigen LapTimer-Anwendung auf und zeigen, wie Sie leichte Migrationen durchführen.

Schemaänderungen, Versionierung und Migrationen

Wenn Sie eine Anwendung entwickeln, wird das Schema beim ersten Mal so gut wie nie richtig sein. Daher unterstützt Core Data die Schemaversionierung und Datenmigration. Auf diese Weise können Sie eine neue Version des Core Data-Schemas definieren, indem Sie dem Geschäft ein neues Attribut oder eine neue Entität hinzufügen. Definieren Sie dann, wie der Store von einer Änderung zur anderen migrieren muss.

Ein neues xcdatamodel erstellen

Core Data behandelt Schema-Versionen anders als andere Frameworks, die Sie in der Vergangenheit verwendet haben. Wenn Sie die Entwicklung durchlaufen und ein neues Attribut oder eine neue Entität benötigen, müssen Sie diese hinzufügen, indem Sie eine neue Xcdatamodel-Datei für Ihre Anwendung erstellen. Diese neue Datei wird versioniert, enthält eine inkrementelle Nummer im Dateinamen und unterscheidet sich von älteren Schemaversionen. Erstellen Sie in der Anwendung LapTimer die neue Version des Datenmodells. Klicken Sie in Ihrer Anwendung auf die xcdatamodel-Datei und navigieren Sie dann zu dem Menüpunkt unter: Design> Datenmodell> Modellversion hinzufügen.

Sie haben jetzt einen Xcdatamodel-Baum, wobei das übergeordnete Element eine neue Xcdatamodel-Datei ist und eine neue Schemaversion mit der inkrementellen Nummer gekennzeichnet ist. Es gibt auch ein grünes Häkchen gegen das alte Schema. Dies zeigt an, welches Schema aktiv ist und welche Anwendung es verwenden wird. Es ist wichtig zu wissen, dass die sofortige Auswahl der neuen Version einige Probleme bei der Entwicklung verursachen kann. Da wir noch keine Migration für dieses neue Schema eingerichtet haben, wird der Simulator oder das Gerät beim Booten abstürzen, wenn wir das neue Schema als aktiv festlegen. Sehen Sie sich als Demonstration den folgenden Fehler an. Dies ist häufig der Fall, auf den die Leute beim ersten Versuch stoßen:

Es heißt im Grunde nur "Hey, Sie haben das aktive DB-Schema geändert und ich bleibe bei einer älteren Version." Dadurch wird verhindert, dass die Anwendung Konflikte und Fehler mit dem Core Data Store-Schema ändert. Es führt einen Vergleich anhand der Details des Schemas durch, mit dem die Filiale arbeitet. Wenn ihm eine neue Schemaversion zur Verfügung gestellt wird, sie jedoch nicht mit dem übereinstimmt, zu dem sie eingerichtet oder migriert wurde, wird diese Fehlermeldung angezeigt.

Wie kommen wir daran vorbei? Nun, es gibt zwei Möglichkeiten:

  1. Wenn sich die App in der Entwicklung befindet und Sie sich nicht für Daten in der Anwendung interessieren, löschen Sie die Anwendung einfach vom Gerät und installieren Sie sie erneut. Es löscht den Store und seinen Inhalt, erstellt jedoch die App mit dem neuen Schema. Dies ist nur eine Option in der Entwicklung.
  2. Verwenden Sie die einfache Migration, um kleine Schemaänderungen bei jeder Änderung automatisch zu übernehmen. Dies ist auf nur wenige Migrationen beschränkt, die im Folgenden näher beschrieben werden.

Leichte Migration

Dies ist ein einfach zu verwendendes und automatisches Feature von Core Data. Es ist jedoch nur auf einfache Migrationen beschränkt, weshalb es leicht ist. Sie können diese Methode nur verwenden, wenn sich folgende Änderungen ergeben:

  • Hinzufügen eines neuen Attributs / einer neuen Eigenschaft zu einer Entität.
  • Umbenennen einer Entität oder eines Attributs / einer Eigenschaft, wenn der 'Renaming Identifier' angegeben ist.
  • Ändern eines Attributs / einer Eigenschaft in optional oder nicht optional, unabhängig davon, ob für die Erstellung ein Wert erforderlich ist.

Hinweis: Bevor Sie eintauchen, müssen Sie, wenn Sie am LapTimer-Projekt arbeiten, das Projekt erstellen, bevor wir beginnen. Stellen Sie sicher, dass das aktive Xcdatamodel die erste Version ist, mit der die Anwendung erstellt wurde. Auf diese Weise können Sie die Migrationsarbeit sehen.

Zur Demonstration der LapTimer-Anwendung wird die Ereignisentität in Lap geändert. Damit müssen wir auch die Event.h- und Event.m-Klassen und deren Vorkommen in der Anwendung aktualisieren. Mit ein paar raffinierten Xcode-Funktionen ist dies schmerzlos.

In der neuen Version des xcdatamodel, die wir zuvor erstellt haben, werde ich die Änderung vornehmen, indem ich einfach die Werte im Fenster "Entity-Details" ändere. Jetzt müssen wir den 'Renaming Identifier' auf Event setzen. Klicken Sie also im selben Fenster auf den Schraubenschlüssel und geben Sie "Event" in das Feld Renaming Identifier ein:

Der nächste Schritt besteht darin, Core Data mitzuteilen, dass es beim Booten leichte Migrationen durchführen kann. Unter Bezugnahme auf die Anwendung LapTimer müssen wir in der Datei LapTimerAppDelegate.m der persistentenStoreCoordinator-Methode - (NSPersistentStoreCoordinator *) etwas Code hinzufügen:

 - (NSPersistentStoreCoordinator *) persistentStoreCoordinator if (persistentStoreCoordinator! = Nil) return persistentStoreCoordinator;  NSURL * storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @ "LapTimer.sqlite"]]; NSError * error = nil; persistentStoreCoordinator = [[NSPersistentStoreCoordinator-Zuordnung] initWithManagedObjectModel: [self managedObjectModel]]; NSDictionary * options = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool: YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool: YES], NSInferMappingModelAutomaticallyOption, nil]; if (! [persistentStoreCoordinator addPersistentStoreWithType: NSSQLiteStoreType Konfiguration: keine URL: storeUrl Optionen: Optionen Fehler: & Fehler]) / * Ersetzen Sie diese Implementierung durch Code, um den Fehler entsprechend zu behandeln. abort () veranlasst die Anwendung, ein Absturzprotokoll zu erstellen und zu beenden. Sie sollten diese Funktion nicht in einer Versandanwendung verwenden, obwohl sie während der Entwicklung nützlich sein kann. Wenn der Fehler nicht behoben werden kann, zeigen Sie eine Warnanzeige an, die den Benutzer anweist, die Anwendung durch Drücken der Home-Taste zu beenden. Zu den typischen Ursachen für einen Fehler gehören: * Auf den persistenten Speicher kann nicht zugegriffen werden. * Das Schema für den persistenten Speicher ist nicht mit dem aktuellen Modell für verwaltete Objekte kompatibel. Überprüfen Sie die Fehlernachricht, um das tatsächliche Problem zu ermitteln. * / NSLog (@ "Ungelöster Fehler% @,% @", Fehler, [Fehler UserInfo]); abbrechen();  return persistentStoreCoordinator;  

Der hinzugefügte Code bestand aus den Optionen NSDictionary, die Core Data anweisen, automatische Migrationen durchzuführen.

Wir sind fast fertig. Der nächste Schritt besteht darin, die Klassendateien für die Ereignisentität so zu ändern, dass sie den neuen Namen widerspiegeln. Dafür verwenden wir meine Lieblingsfunktion von Xcode, die Refactor-Funktion. Wie aus dem Namen hervorgeht, wird diese Funktion in solchen Situationen umgestaltet und ein erweitertes Suchen und Ersetzen für Ihr Projekt durchgeführt.

Dazu müssen Sie Event.m öffnen und den Text 'Event' für diese Datei auswählen. Gehen Sie dann zu: Bearbeiten> Refaktor (Befehlstaste + Umschalttaste + J). Nach oben wird ein Fenster mit Optionen und Feldern angezeigt (siehe Abbildung unten). Geben Sie im Feld "Ereignis an" das Wort Lap ein. Klicken Sie auf Vorschau und Sie erhalten die Ausgabe aller Änderungen:

Wenn Sie wissen möchten, was dies tun soll, klicken Sie auf eine der Dateien im Ergebnisbereich. Daraufhin werden Details zu den Änderungen angezeigt. Die Dateien Event.h und Event.m werden für uns ebenfalls umbenannt. Zu beachten ist, dass frühere Xcdatamodel-Dateien, bei denen die bestimmte NSManagedObject-Klasse ersetzt wurde, eine geringfügige Änderung aufweisen. Dadurch wird der Klassenname der Entität geändert, nicht der Entitätsname. Wenn ein Gerät die Migration durchlaufen muss, kann es dennoch die Entitäten-Klasse NSManagedObject und verwandte Methoden verwenden.

Klicken Sie auf "Anwenden". Das ist es. Als Sicherheitsmaßnahme wird auch ein Snapshot erstellt, ein weiteres großartiges Feature von XCode. Wenn alles schief geht, können Sie einfach zum vorherigen Snapshot zurückkehren, genau wie Time Machine, jedoch ohne alle Sterne und die swirly-Galaxie-Benutzeroberfläche.

Leider erfasst das nicht alle erforderlichen Änderungen. Es gibt immer noch einige Bits der LapTimer-Anwendung, die auf Event verweisen. Ein schnelles Suchen und Ersetzen ist also in Ordnung. Gehe zu: Bearbeiten> In Projekt suchen. Mit dem neuen Fenster geben Sie Event als Suche und Lap als Ersatz ein. Deaktivieren Sie "Fall ignorieren", da wir nur die strikte Großschreibung des Funds aufgreifen möchten. Ändern Sie dann das Dropdown-Menü, in dem 'Enthält' ausgewählt ist, und wählen Sie stattdessen 'Ganze Wörter' aus. Dies wird den Fund auf genau das beschränken, was wir brauchen.

Klicken Sie auf Suchen. Überprüfen Sie die Änderungen. Wenn alles gut gegangen ist, führen Sie den Austausch durch!

Aktives Schema ändern

Wir haben also eine neue Version des Schemas erstellt, einige Änderungen vorgenommen und jetzt ist es an der Zeit, die Anwendung in das neue Schema aufzunehmen.

Nichts hier knifflig. Wählen Sie das neue Schema aus, das Sie als aktiv festlegen möchten, und navigieren Sie zu: Design> Datenmodell> Aktuelle Version setzen. Das grüne Häkchen wechselt zum neuen Schema und alles ist bereit.

Erstellen Sie die Anwendung und führen Sie sie aus. Alles sollte in Ordnung sein und die Anwendung sollte geöffnet, migriert und ausgeführt werden. Sie werden diese Migration überhaupt nicht bemerken, nicht einmal eine Debugger-Ausgabe. Aber die Tatsache, dass der Code läuft und funktioniert, ist ein Beweis dafür, dass er migriert wurde.

Rekapitulieren

Die Anwendung hat jetzt einen geänderten Entitätsnamen. Dies kann bei der Entwicklung einer Anwendung von Zeit zu Zeit vorkommen. Mit dieser einfachen Migrationsmethode können Sie mit demselben Prozess neue Eigenschaften hinzufügen.

Wenn Sie den Typ einer Eigenschaft ändern oder erweiterte Änderungen vornehmen müssen, müssen Sie sich mit der Migration von Zuordnungsmodellobjekten befassen. Dies ist eine fortgeschrittenere Methode für das, was wir durchgeführt haben, und erfordert zusätzliche Konfigurationen und Code. Die Apple iOS-Dokumentation hat diesen fortgeschrittenen Migrationsprozess wirklich gut durchlaufen.