Advertisement
  1. Code
  2. iOS SDK

iPhone-Kerndaten: Ihre ersten Schritte

Scroll to top
Read Time: 16 min

German (Deutsch) translation by Tatsiana Bochkareva (you can also view the original English article)

Core Data ist ein Framework, das Apple Entwicklern zur Verfügung stellt und das als "schemagesteuertes Framework für die Verwaltung und Persistenz von Objektgraphen" bezeichnet wird. Was bedeutet das eigentlich? Das Framework verwaltet, wo Daten gespeichert werden, wie sie gespeichert werden, Daten zwischengespeichert und Speicher verwaltet. Es wurde von Mac OS X mit der Version 3.0 iPhone SDK auf das iPhone portiert.

In diesem Tutorial werde ich Sie durch den Prozess der Erstellung eines Projekts mit Core Data führen und Ihnen zeigen, wie Sie es mit einem einfachen UITableViewController verwenden. Es wird eine einfache Datenbank mit einer Tabelle sein, in der Rundenzeiten gespeichert und die Zeiten und ihre Aufteilungsunterschiede in einer UITableView angezeigt werden.

Warum Kerndaten verwenden?

Bevor wir beginnen, ist es wichtig zu verstehen, warum Sie Core Data mit SQLite möglicherweise zum Speichern über Eigenschaftslisten, ein benutzerdefiniertes XML-Format oder den direkten SQLite-Datenbankzugriff verwenden möchten. Mit der Core Data API können Entwickler eine relationale Datenbank erstellen und verwenden, eine Datensatzvalidierung durchführen und Abfragen unter SQL-freien Bedingungen durchführen. Im Wesentlichen können Sie mit SQLite in Objective-C interagieren und müssen sich nicht um Verbindungen oder die Verwaltung des Datenbankschemas kümmern. Die meisten dieser Funktionen sind Personen bekannt, die ORM-Technologien (Object Relational Mapping) wie die in Ruby implementierten verwendet haben auf Rails, CakePHP, LINQ oder anderen Bibliotheken und Frameworks, die den Zugriff auf die Datenbank abstrahieren. Der Hauptvorteil dieses Ansatzes besteht darin, dass die Entwicklungszeit entfällt, die ansonsten zum Schreiben komplexer SQL-Abfragen und zum manuellen Behandeln von SQL und Ausgabe dieser Vorgänge erforderlich ist.

Erstellen eines neuen iPhone-Projekts mit Core Data

Die Beispielanwendung, die wir heute erstellen werden, ist ein einfacher Runden-Timer. Für jede Runde, die wir machen, wird ein neuer Datensatz im Core Data Store erstellt. Das UITableView zeigt dann den Unterschied zwischen der aktuellen und der letzten Runde an.

core data lap timer final previewcore data lap timer final previewcore data lap timer final preview

Zunächst öffnen wir XCode und erstellen ein neues Projekt. Nennen Sie es, was Sie wünschen, ich habe es "LapTimer" genannt. Wir werden eine "fensterbasierte Anwendung" aus der Auswahl der neuen Projektvorlage erstellen. Stellen Sie sicher, dass "Kerndaten für die Speicherung verwenden" aktiviert ist.

new core data project screennew core data project screennew core data project screen

Das Projekt sollte mit dem vertraut sein, was Sie möglicherweise zuvor gesehen haben, wenn Sie zuvor iPhone-Anwendungen entwickelt haben.

Einrichten der Kerndatenstruktur

Es ist nicht viel einzurichten, da die Option "Kerndaten für die Speicherung verwenden" in der Vorlage "Fensterbasierte Anwendung" automatisch einige wichtige Variablen festgelegt und Dateien im Projekt für uns erstellt hat.

In der Datei LapTimer.xcdatamodel definieren wir das Schema für unsere SQLite-Datenbank. Das Core Data Framework wurde ebenfalls zum Projekt hinzugefügt, um die Dateien für den API-Zugriff einzuschließen. Die anderen Änderungen werden in den Standardanwendungsdateien vorgenommen. Insbesondere verfügen die Anwendungsdelegatdateien über die Methoden, um den Kerndatenspeicher in unserer Anwendung einzurichten und in untergeordneten UIViewControllern zu referenzieren.

Was uns momentan interessiert, ist die Datei LapTimer.xcdatamodel unter "Ressourcen". Diese Datei bietet Ihnen eine visuelle Karte Ihres Schemas mit Entitäten und Attributen.

In Core Data werden verschiedene Begriffe und Ausdrücke verwendet, die sich lose auf reguläre Datenbanknamen beziehen können, aber nicht identisch sind.

Eine "Entität", auch als "verwaltetes Objekt" bezeichnet, ähnelt einer Tabelle. Dies ist die Definition eines Objekts, das eine Sammlung von Daten enthält. Ein Entitätsobjekt enthält "Attribute". Diese können lose mit Spalten verknüpft werden, aber diese Attribute sind nicht nur auf die Datenspeicherung beschränkt. Attribute können eine Beziehung zwischen zwei Entitäten definieren, eine dynamisch abgerufene Eigenschaft, oder eine Eigenschaft für die Datenspeicherung definieren.

iphone core data diagramiphone core data diagramiphone core data diagram

Aus dem obigen Diagramm können Sie ein Gefühl dafür gewinnen, wie flexibel Objekte sind, die von Core Data-Entitäten abgeleitet sind. Für diese Beispielanwendung benötigen wir eine wirklich einfache Entität. Wir werden die Entität "Ereignis" nennen, das Aufzeichnungen unserer Runden speichert.

iphone core data modeliphone core data modeliphone core data model

Um diese Entität zu erstellen, klicken Sie auf die Schaltfläche [+] in der ersten (von links) oberen Spalte. Dadurch wird eine neue Entität in der Liste und visuell in der Schemakarte unter den Spalten erstellt.

iphone core data managed objectiphone core data managed objectiphone core data managed object

Dies ist ein schöner visueller Editor für Ihr Modell. Core Data leistet wirklich viel Arbeit, wenn es um den "M" -Teil (Modell) von MVC geht. Der visuelle Editor zeigt die Beziehungen, Eigenschaften und Entitäten des Geschäfts an, während das Schema dynamisch erstellt und für Sie verwaltet wird. Dies ähnelt dem Interface Builder, da es das Zuweisen, Verwalten und Platzieren von Objekten für Sie in einer UIView ohne eine einzige Codezeile übernimmt.

Mit der neuen Ereignisentität möchten wir eine "Eigenschaft" erstellen. Da diese Eigenschaft Daten speichert, legen wir sie als "Attribut" fest. In diesem neuen Attribut wird also nur das aktuelle Datum für die Erstellung des Datensatzes gespeichert. In unserer Beispielanwendung werden wir dies verwenden, um unsere Rundenzeiten zu referenzieren.

In der nächsten Spalte rechts definieren wir unsere Eigenschaften (stellen Sie sicher, dass die Ereignisentität ausgewählt ist). Erstellen Sie also eine neue Eigenschaft mit der Schaltfläche [+] in der Spalte und wählen Sie "Attribut hinzufügen".

iphone core data attributesiphone core data attributesiphone core data attributes

Wir werden das Attribut "timeStamp" aufrufen und seinen Typ auf "Date" setzen. In der Dropdown-Liste Typauswahl gibt es ähnliche Spaltendatentypen wie in relationalen Datenbanksystemen wie PostgreSQL oder MySQL, einschließlich Datentypen wie Ganzzahlen, Gleitkommazahlen, Zeichenfolgen, Booleschen Werten, Datumsangaben und Binärdaten (Blobs).

Für dieses Attribut müssen keine anderen Optionen ausgewählt oder geändert werden.

Das ist es für die xcdatamodel-Datei, und wir können sie in unsere App integrieren. Jetzt ist ein guter Zeitpunkt, um Ihre Arbeit zu retten.

Erstellen unserer Modelldateien

Wenn Sie ein MVC-Framework verwendet haben, das Datenbankmodelldefinitionen enthält, die die Struktur oder das Verhalten einer Tabelle definieren, ist dies eine vertraute Aufgabe.

Wir müssen zunächst eine Definition der Entität erstellen. Dazu erstellen wir eine NSManagedObject-Klasse der Entität und definieren die Variablen, über die der Speicher verfügt.

Dies ist ein einfacher Vorgang. Wählen Sie die Ereignisentität in der Datei LapTimer.xcdatamodel aus und gehen Sie zu Datei > Neue Datei. Sie werden sehen, dass es im Abschnitt "Cocoa Touch Class" eine neue Dateivorlage mit dem Namen "Managed Object Class" gibt.

new managed object classnew managed object classnew managed object class

Wählen Sie die Vorlage aus und klicken Sie auf "Weiter". Der nächste Bildschirm definiert nur, wo wir die Datei und das Ziel speichern, in das sie aufgenommen werden soll. Dies ist standardmäßig alles korrekt. Klicken Sie also erneut auf "Weiter". Im nächsten Bildschirm definieren Sie, für welche Entitäten Sie NSManagedObject-Klassen erstellen möchten. Wenn es nicht ausgewählt ist, wählen Sie Ereignis und stellen Sie sicher, dass die Kontrollkästchen "Accessors generieren" und "Obj-C 2.0-Eigenschaften generieren" aktiviert sind. Derzeit sind keine Überprüfungen erforderlich. Klicken Sie auf Fertig stellen.

managed object class generationmanaged object class generationmanaged object class generation

Jetzt haben wir 2 neue Dateien in unserer Anwendung. Event.m und Event.h. Sie definieren die NSManagedObject-Klasse für die Ereignisentität, die wir in unserem Kerndatenspeicher erstellt haben. Sie definieren das Feld timeStamp, damit wir auf das Attribut zugreifen können, wenn wir die Event-Klasse verwenden möchten.

Event.h

Event.m

Wie bei Modelldefinitionen in anderen Frameworks und Sprachen können Sie benutzerdefinierte Methoden für alle Datensätze in der Ereignisentität hinzufügen. Sie werden feststellen, dass das Attribut timeStamp hinzugefügt und als NSDate-Objekt zugewiesen wurde.

Kerndaten und KVC

Mit der Einrichtung von Core Data ist es jetzt an der Zeit, einen Teil der Controller-Logik in der Anwendung zu bearbeiten. Wir werden einen UITableViewController als Hauptschnittstelle der App verwenden, um die Rundenzeiten anzuzeigen und eine neue Zeit zu protokollieren.

Also werden wir den neuen UITableViewController mit Datei > Neue Datei erstellen. Wählen Sie dann im iPhone-Bereich "UIViewController-Unterklasse" aus und aktivieren Sie "UITableViewController-Unterklasse", ohne jedoch die Kontrollkästchen zu aktivieren, die sich auf die Verwendung von XIBs oder das Targeting für ein iPad beziehen. Wir werden kein XIB für diesen Controller verwenden. Rufen Sie die neue Datei "TimeTableController" auf und beenden Sie den Datei-Assistenten.

In diesem Controller benötigen wir zwei Eigenschaften, einen Verweis auf den NSManagedObjectContext und ein Array zum Speichern der Datensätze für die UITableView. Wir definieren nicht nur diese Eigenschaften, sondern importieren auch die Datei Event.h, damit wir die Klasse verwenden können.

TimeTableController.h

Was ist ein NSManagedObjectContext? Es wird in der Anwendung als "Notizblock" für Kerndaten bezeichnet, um das Abrufen, Aktualisieren und Erstellen von Datensätzen im Geschäft zu verwalten. Es verwaltet auch einige grundlegende Funktionen in Core Data, einschließlich Validierungen und Rückgängig-/Wiederherstellungsverwaltung für die Datensätze.

Der verwaltete Objektkontext ist die Verbindung zwischen Ihrem Code und dem Datenspeicher. Alle Vorgänge, die Sie für Core Data ausführen, werden im Kontext des verwalteten Objekts ausgeführt. Wenn eine Anforderung ausgeführt wird, spricht der Kontext des verwalteten Objekts mit dem persistenten Speicherkoordinator, der für die Zuordnung der Objekte zu Daten für den Datenspeicher verantwortlich ist. Dadurch können die Kerndaten zwischen verschiedenen Datenspeicherformaten flexibel sein. Hier ist ein Diagramm, wie das aussieht.

iphone core data diagram 2

Wenn die Header-Datei definiert ist, müssen die zugewiesenen Eigenschaften und Methoden in der Implementierungsdatei weitergegeben werden.

TimeTableController.m

Das ist ein gutes Stück Code, also lassen Sie es uns für jede Methode einzeln durchgehen. Es gibt Code von, wenn Sie die Datei aus der Vorlage erstellen, auskommentierte Methoden wie viewDidUnload, die ich gerade aus dem oben genannten weggelassen habe.

viewDidLoad

Wir beginnen mit dem üblichen Anruf in der Superklasse. Dann definieren wir den Titel der UINavigationBar. Danach müssen wir die Schaltfläche definieren, mit der wir dem Core Data Store einen Datensatz hinzufügen. Wenn die Taste gedrückt wird, wird der Selektor addTime aufgerufen, der dann mit Core Data interagiert. Nach den erforderlichen Releases rufen wir die unten erläuterte Funktion fetchRecords auf.

addTime:(id)sender

Dies wird ausgelöst, wenn das UIBarButtonItem oben rechts in der UINavigationBar gedrückt wird. Wir müssen einen neuen Ereignisdatensatz mit dem aktuellen NSDate erstellen und in der Datenbank speichern.

Wir erstellen einen neuen Ereignisdatensatz, der als NSEntityDescription bezeichnet wird. Dies ist Ihre Zeile in der Datenbank für den neuen Datensatz. Dazu definieren wir den Entitätsnamen, zu dem der Datensatz gehört, und stellen den NSManagedObjectContext bereit. Das aktuelle Datum wird dann gegen das Attribut timeStamp gesetzt.

Der Speichervorgang wird dann ausgeführt, es ist jedoch vorgesehen, einen Fehler zu behandeln, wenn das Einfügen fehlschlägt. Normalerweise werfen Sie eine UIAlertView, die besagt, dass der Datensatz nicht erstellt wurde, und weisen den Benutzer möglicherweise an, es erneut zu versuchen oder die Anwendung zu schließen und erneut zu öffnen.

Der Datensatz muss dem Array hinzugefügt werden, aus dem UITableView gespeist wird. Dann muss die UITableView angewiesen werden, die Daten neu zu laden. Sie können dies grafischer mit einer Animation tun, aber für das Tutorial lassen Sie es uns einfach halten.

fetchData

Diese Methode ruft die Daten aus dem Speicher ab und fügt sie dem Array hinzu, das wir im Controller haben. Weitere Informationen zum Abrufen von Datensätzen finden Sie unter NSFetchRequest.

Daten aus dem Datenspeicher abrufen

Core Data verfolgt einen anderen Ansatz zum Abrufen von Daten aus seiner Datenbank. Es ist ein NoSQL-Datenspeicher, dh alle Bedingungen einer Abfrage basieren auf Methoden. Dies ist großartig, da der Basisspeicher, bei dem es sich um SQLite handelt, auf eine andere Datenbanktechnologie geändert werden kann und nur die Verbindung und die Treiber für die Datenbank geändert werden müssen.

Um eine Anfrage zu erstellen, erstellen wir ein NSFetchRequest-Objekt. Dies ist das Basisobjekt, für das die Abfragebedingungen festgelegt werden. Wir können Bedingungen für die Übereinstimmung mit einer bestimmten Eigenschaft basierend auf der Reihenfolge der Datensätze definieren. Weitere Informationen zu Core Data und seinen Bedingungen für NSFetchRequests finden Sie in der Dokumentation.

Das Erstellen einer neuen NSFetch-Anforderung ist einfach. Sie müssen nur die Entität definieren, von der Sie Datensätze erhalten möchten, und den NSManagedObjectContext.

Die Entität wird mithilfe eines NSEntityDescription-Objekts definiert, für das der Entitätsname und der NSManagedObjectContext erforderlich sind. Die Abrufanforderung wird dann unter Übergabe der Entitätsbeschreibung erstellt. Dies würde dem ersten Teil einer SQL-Anweisung entsprechen:

In unserer Beispielanwendung sortieren wir die Daten absteigend nach dem Zeitstempel. Dazu verwenden wir einen NSSortDescriptor.

Der NSSortDescriptor wird erstellt und wir definieren das Attribut, das wir sortieren möchten, und ob es aufsteigend ist. In diesem Fall möchten wir, dass es absteigt, sodass es auf NO gesetzt wird. Die Abrufanforderung kann viele Sortierdeskriptoren enthalten, sodass beim Festlegen der Sortierdeskriptoren ein Array akzeptiert wird. Da wir nur eines wollen, müssen wir nur ein Array mit einem Objekt darin erstellen. Wir setzen das Deskriptor-Array gegen die Abrufanforderung und das ist es.

Um eine Bedingung zu definieren, die mit dem Inhalt eines Datensatzes übereinstimmt, kommt die NSPredicate-Klasse ins Spiel. Es ermöglicht die Übereinstimmung der Abrufanforderung oder die Definition eines Bereichs, den der Inhalt eines Datensatzes erfüllen muss. Dies entspricht Ihrer Gleichheit, größer und kleiner als Übereinstimmungen in SQL. Es enthält mehr als Ihre grundlegenden SQL-Funktionen, die Sie hier sehen können.

Das Festlegen eines Prädikats kann sehr einfach sein.

Verwenden von NSPredicate predicateWithFormat: ist eine einfache und vertraute Methode, mit der Sie die Bedingungen der Abfrage definieren können. Für eine ausführliche Erklärung zu NSPredicates enthält die Apple-Dokumentation einige großartige Anleitungen.

Wenn Sie die Bedingungen in Ihrer Abrufanforderung definiert haben, können Sie diese ausführen.

Dadurch wird ein Array von Entitätsobjekten, NSManagedObjects, zur Verwendung in Ihrer Datenausgabe zurückgegeben.

Auffüllen der UITableView aus Kerndaten

Mit den Daten, die aus den Kerndaten abgerufen und im eventArray gespeichert wurden, können wir diese Datensätze jetzt in UITableView ausgeben.

Als erstes müssen Sie der Tabelle mitteilen, dass wir nur einen Abschnitt benötigen und wie viele Zeilen wir verwenden müssen.

Auszug aus TimeTableController.m

Wenn Sie zuvor einen UITableViewController verwendet haben, sollte die nächste Funktion einfach sein.

In der Zelle werden 2 Werte angezeigt, die den UITableViewCellStyleValue1-Stil verwenden. Links ist die Zeit der Runde und rechts ist die Differenz in Sekunden zum vorherigen Rekord.

Da diese Methode iteriert, müssen wir besonders vorsichtig mit der Last umgehen, unter die das Gerät gestellt werden kann, wenn es nicht richtig verwaltet wird. Aus diesem Grund wird der NSDatFormatter als statische Variable gespeichert, sodass er in jeder Iteration wiederverwendet werden kann, ohne ihn jedes Mal zuzuweisen und freizugeben.

Lazy Loading

Lazy Loading ist eine Technik, bei der Sie die Anforderung oder Zuweisung einer Eigenschaft so weit wie möglich verzögern. Dies hilft, den Speicher niedrig zu halten, und während iterativer Funktionen ist dies von größter Bedeutung. Zu wissen, wann und wie Daten zuzuweisen sind, ist entscheidend, um eine mobile App schnell zu halten. Die Freigabe des Objekts ist ebenso wichtig: Je früher, desto besser.

cellForRowAtIndexPath: ist eine iterative Methode, und alle Daten, die in dieser Methode verarbeitet oder zugewiesen werden, müssen auf ein Minimum beschränkt werden. Diese Methode wird immer dann ausgeführt, wenn eine Zelle angezeigt wird. Wenn ein Benutzer schnell einen Bildlauf durchführt, kann diese bestimmte Methode abhängig von der Größe des Datensatzes sehr häufig nacheinander aufgerufen werden.

Die nächste Aufgabe besteht darin, das Ereignisobjekt abzurufen, das der Tabellenzeile zugeordnet ist, die gerendert werden muss. Da wir den vorherigen Datensatz für den Zeitvergleich abrufen müssen, gibt es eine einfache Überprüfung, um festzustellen, ob ein vorheriger Datensatz vorhanden ist, und um ihn in previousEvent zu speichern. Wenn das vorherige Ereignis vorhanden ist, berechnen wir die Aufteilung mit [NSDate timeIntervalSinceDate: (NSDate)]. Das textLabel und das detailTextLabel werden dann mit den von uns berechneten Werten festgelegt.

Bewerbung beenden

Mit dem UITableViewController-Setup und der Tabellendatenquelle, die mit dem Core Data Store zusammenarbeitet, muss der Controller beim Laden der Anwendung nur geladen werden.

Im Anwendungscontroller muss eine UINavigationController-Eigenschaft definiert werden. Dann muss die applicationDidFinishLaunching-Methode nur noch den Controller zuweisen, und wir sind fertig.

LapTimerAppDelegate.h

Auszug aus LapTimerAppDelegate.m

Die Datei TimeTableController.h wird in den Anwendungsdelegierten aufgenommen und dann einem UINavigationController zugewiesen.

Das sollte es sein. Erstellen Sie die Anwendung, um nach Fehlern zu suchen. Einige der Codebeispiele waren nur Auszüge. Keiner der Codes, die beim Erstellen einer Datei generiert wurden, wurde entfernt und nur ausgefüllt. Wenn Sie auf Fehler stoßen, die Sie nicht knacken können, können Sie die diesem Tutorial beigefügte Projektdatei herunterladen, die Sie dann kompilieren und vergleichen können.

Führen Sie die Anwendung aus. Sie sehen den Navigationscontroller und die Schaltfläche Hinzufügen. Drücken Sie die Add-Taste und Sie erhalten eine neue Zeit in der Tabelle.

Rekapitulieren

In diesem Tutorial haben wir eine Beispielanwendung zum Speichern einfacher Daten in einem Core Data Store erstellt. Die Anwendung hat beim Erstellen einer Anwendung mit Core Data die anfängliche Einrichtung durchlaufen, die Datenstruktur definiert und Datensätze aus dem Datenspeicher abgerufen.

Hoffentlich haben Sie eine Einführung in Core Data erhalten und können sehen, wie einfach es zu verwenden ist und wie es die Leistung und Funktionalität Ihrer Anwendungen verbessern kann.

Wenn Sie mehr über Core Data erfahren oder einen detaillierten Blick auf die Struktur des Frameworks werfen möchten, ist die Apple Developer Documentation der perfekte Ort.

Ressourcen

Apple Developer Documentation:

Einführung in die Kerndatenprogrammierung

Migration und Versionierung von Kerndaten

NSPredicate-Programmierhandbuch:

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.