Core Data ist ein Apple-Framework zur Verwaltung eines Objektgraphen in iOS- und macOS-Anwendungen. Es bietet Datenpersistenz, Änderungsverfolgung, Rückgängig-Operationen und UI-Integration über NSFetchedResultsController. Laut Apple Developer-Dokumentation (2025) ist Core Data keine Datenbank — es ist eine Objektmodellierungsschicht, die standardmäßig SQLite als persistenten Speicher zum Laden und Speichern von Objekten verwendet.
Das Wichtigste
Core Data ist ein Framework zur Objektgraphenverwaltung und Persistenz, das Teil des Cocoa Touch SDK von Apple ist. Es bietet eine objektorientierte Schnittstelle zur Arbeit mit Daten: Der Entwickler arbeitet mit Entitäten, Attributen und Beziehungen, während Core Data diese Objekte unter der Haube in relationale Datenbankdatensätze umwandelt.
Core Data wurde in Mac OS X 10.4 Tiger (2005) für macOS eingeführt und auf iOS 3.0 (2009) portiert. In über 20 Jahren hat sich das Framework von einer einfachen Abstraktionsebene über SQLite zu einem vollwertigen Stack mit Cloud-Synchronisation über NSPersistentCloudKitContainer, Multithreading durch automatische Kontextverwaltung und asynchronem Laden via Swift Concurrency entwickelt.
Laut einer iOS-Entwicklerumfrage der Slack Community (2025) wird Core Data in 68% der kommerziellen iOS-Anwendungen zur lokalen Datenspeicherung verwendet. Trotz Kritik an Komplexität und Mehrschichtigkeit bleibt das Framework der Standard für Apple-Anwendungen dank enger Systemintegration, Nullkosten (im SDK enthalten) und iCloud-Synchronisationsunterstützung.
Ein häufiges Missverständnis ist, Core Data für eine Datenbank zu halten. Das Framework führt keine SQL-Abfragen direkt aus und ist kein DBMS. Core Data ist eine Objektgraphenverwaltungsschicht, die SQLite, Binary oder In-Memory-Speicher für die Persistenz nutzen kann. Analogie: Core Data ist wie Hibernate oder Entity Framework, aber für das Apple-Ökosystem, und SQLite darunter ist wie MySQL unter Hibernate.
Der Core Data-Stack besteht aus vier miteinander verbundenen Komponenten: NSManagedObjectModel (Datenschema), NSPersistentStoreCoordinator (Speicherkoordinator), NSManagedObjectContext (Arbeitskontext) und NSPersistentContainer (ein einheitlicher Container, der alle drei seit iOS 10 vereint). NSPersistentContainer automatisiert die Stack-Erstellung und -Konfiguration.
Jede Komponente erfüllt eine streng definierte Funktion. NSManagedObjectModel lädt die .xcdatamodeld-Datei mit Entitätsbeschreibungen. NSPersistentStoreCoordinator verbindet das Modell mit der physischen Speicherdatei (SQLite). NSManagedObjectContext bietet einen temporären Bereich für die Arbeit mit Objekten. Der Container vereint alles in einem einzigen Initialisierungsaufruf.
SQLite (NSSQLiteStoreType) ist der in den meisten Anwendungen verwendete Standardspeicher. Daten werden in einer einzigen .sqlite-Datei mit ACID-Transaktionsunterstützung gespeichert. Binary (NSBinaryStoreType) ist ein Binärformat-Speicher für kleine Datensätze (bis zu einigen hundert Objekten). In-Memory (NSInMemoryStoreType) ist ein temporärer Speicher im RAM ohne Festplattenpersistenz, der für Tests und Caching verwendet wird.
| Speichertyp | Format | Leistung | Verwendungszweck |
|---|---|---|---|
| SQLite | .sqlite | Hoch | Standardwahl für Produktion |
| Binary | .binary | Mittel | Kleine Datensätze |
| In-Memory | RAM | Maximal | Tests, Cache, temporäre Daten |
| CloudKit | iCloud | Netzwerkabhängig | Geräteübergreifende Synchronisation |
Der Speichertyp wird mit einer einzigen Zeile bei der Initialisierung von NSPersistentStoreDescription festgelegt. Der Entwickler kann von SQLite auf In-Memory für Unit-Tests oder auf CloudKit für iCloud-Synchronisation umschalten, ohne den Objektmanipulationscode zu ändern — Core Data abstrahiert die Unterschiede zwischen Speichertypen durch eine einheitliche Kontext-API.
NSManagedObject ist die Basisklasse für alle Core Data-Objekte und repräsentiert einen einzelnen Entitätsdatensatz. Jedes verwaltete Objekt hat eine eindeutige NSManagedObjectID (persistente Kennung), ist an einen Kontext gebunden und verfolgt seine Änderungen über KVO (Key-Value Observing). Entwickler erstellen NSManagedObject-Unterklassen, um typisierte Entitätseigenschaften zu definieren.
NSManagedObjectContext ist die zentrale Core Data-Komponente, die einen Arbeitsbereich für alle Objektoperationen bereitstellt. Der Kontext verfolgt Hinzufügungen, Löschungen und Änderungen (Change Tracking), unterstützt das Rückgängigmachen von Operationen über undoManager und führt beim Empfang von Speicherbenachrichtigungen automatisch Änderungen aus anderen Kontexten zusammen.
Die Regel privater Warteschlangen: NSManagedObjectContext wird mit .privateQueueConcurrencyType oder .mainQueueConcurrencyType erstellt. Der Hauptkontext ist an den Haupt-UI-Thread gebunden, während private Kontexte auf Hintergrundwarteschlangen laufen. Jeder Kontext darf nur in seiner eigenen Warteschlange verwendet werden — der Zugriff auf ein verwaltetes Objekt von einem anderen Thread führt zu einem Absturz. parentContext ermöglicht die Organisation einer Hierarchie von Kontexten für asynchrone Schreibvorgänge.
struct CoreDataStack {
let container: NSPersistentContainer
init(name: String) {
container = NSPersistentContainer(name: name)
container.loadPersistentStores { _, error in
if let error = error {
fatalError("Failed to load store: \(error)")
}
}
container.viewContext.automaticallyMergesChangesFromParent = true
}
func backgroundContext() -> NSManagedObjectContext {
let context = container.newBackgroundContext()
context.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
return context
}
}
NSPersistentContainer erstellt automatisch viewContext (main queue) und stellt newBackgroundContext() für Hintergrundoperationen bereit. Die Einstellung automaticallyMergesChangesFromParent = true bewirkt, dass viewContext automatisch Änderungen aus Hintergrundkontexten übernimmt, wenn diese speichern, und die UI ohne manuelles erneutes Abrufen der Daten aktualisiert.
NSPersistentStoreCoordinator verwaltet den physischen Datenspeicher: Er öffnet die Datei, erstellt SQLite-Tabellen basierend auf dem Modell und führt Migrationen bei Schemaänderungen durch. Bei der Initialisierung von NSPersistentStoreDescription mit NSSQLiteStoreType erstellt Core Data eine SQLite-Datei mit einem Schema, das dem .xcdatamodeld-Modell entspricht.
Core Data verwendet keine Standard-SQL-Abfragen über SELECT/INSERT/UPDATE. Stattdessen generiert es interne SQL-Befehle basierend auf dem Modell und Abfragen, die über NSFetchRequest durchgeführt werden. Der Entwickler kann die SQL-Protokollierung mit dem Startargument -com.apple.CoreData.SQLDebug 1 zur Abfrageleistungsdebugging aktivieren.
Leichte Migration (Lightweight Migration) ist ein automatischer Prozess zur Aktualisierung des SQLite-Schemas beim Hinzufügen neuer Attribute, Ändern von optional/required-Flags oder Umbenennen mit renamingID. Schwere Migration ist bei grundlegenden Schemaänderungen wie dem Zusammenführen oder Aufteilen von Entitäten erforderlich und wird über einen benutzerdefinierten NSMigrationManager durchgeführt.
let description = NSPersistentStoreDescription()
description.url = FileManager.default
.urls(for: .documentDirectory, in: .userDomainMask)
.first?
.appendingPathComponent("Model.sqlite")
description.setOption(true as NSNumber,
forKey: NSMigratePersistentStoresAutomaticallyOption)
description.setOption(true as NSNumber,
forKey: NSInferMappingModelAutomaticallyOption)
let container = NSPersistentContainer(name: "AppModel")
container.persistentStoreDescriptions = [description]
container.loadPersistentStores { _, error in
if let error = error { print("Migration error: \(error)") }
}
Die Einrichtung der automatischen Migration über NSMigratePersistentStoresAutomaticallyOption und NSInferMappingModelAutomaticallyOption ermöglicht es Core Data, die SQLite-Datei beim Hinzufügen von Attributen oder Entitäten in einer neuen Modellversion unabhängig zu aktualisieren. Ist eine Migration nicht möglich, wirft der Store-Koordinator einen Fehler mit einer Beschreibung der Ursache — der Entwickler muss dann eine benutzerdefinierte Migration über NSMigrationManager implementieren.
NSFetchRequest ist das primäre Werkzeug zum Abrufen von Objekten aus Core Data. Eine Anfrage enthält den Entitätsnamen, ein Prädikat (Filter), Sortierbeschreibungen, Limit und Offset. Das Ergebnis wird als Array von NSManagedObject oder typisierten Unterklassen zurückgegeben. NSPredicate unterstützt komplexe Bedingungen mit AND, OR, IN, LIKE und Unterabfragen.
NSBatchDeleteRequest ist eine effiziente Möglichkeit, Objekte massenhaft zu löschen, ohne jedes einzelne in den Speicher zu laden. Die Anfrage wird auf SQLite-Ebene ausgeführt, umgeht den verwalteten Objektkontext und aktualisiert den Kontext erst nach Abschluss. Ähnliche Batch-Anfragen existieren zum Aktualisieren (NSBatchUpdateRequest) und Einfügen (NSBatchInsertRequest).
CRUD (Create, Read, Update, Delete) in Core Data wird über Kontextmethoden ausgeführt: insert, fetch, save und delete. Alle Änderungen sind temporär, bis context.save() aufgerufen wird — diese Methode speichert Änderungen im persistenten SQLite-Speicher. Bei einem Speicherfehler bleibt der Kontext für einen erneuten Versuch im geänderten Zustand.
let context = container.viewContext
// Erstellen
let user = User(context: context)
user.id = 42
user.name = "Alice"
// Lesen
let request = User.fetchRequest()
request.predicate = NSPredicate(format: "name CONTAINS %@", "Ali")
request.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]
let results = try context.fetch(request)
// Aktualisieren
results.first?.name = "Alice Updated"
// Löschen
if let first = results.first { context.delete(first) }
// Speichern
try context.save()
Das Speichern des Kontexts (context.save()) ist ein kritischer Vorgang. Wenn save nicht aufgerufen wird, bleiben alle Änderungen nur im Speicher. Der Kontext verfolgt den hasChanges-Status, der vor dem Speichern überprüft werden kann. Für Hintergrundoperationen verwenden Sie newBackgroundContext mit eigenem Speichern und für die UI viewContext mit automatischem Speichern per Timer oder beim Eintritt der App in den Hintergrund.
Erste Praxis — verwenden Sie NSPersistentCloudKitContainer zur Synchronisation von Daten zwischen Benutzergeräten über iCloud. Die Cloud-Synchronisation wird durch Hinzufügen der CloudKit-Option zur Persistent Store-Beschreibung aktiviert. Core Data verwaltet Synchronisationskonflikte automatisch und führt Änderungen von anderen Geräten zusammen.
Zweite Praxis — vermeiden Sie fetchRequest ohne Prädikat bei großen Tabellen. Jeder bedingungslose Fetch lädt alle Entitätsobjekte in den Speicher, was zu hohem RAM-Verbrauch und UI-Verlangsamung führt. Verwenden Sie immer Prädikate und Limits. Für Paginierung verwenden Sie fetchLimit und fetchOffset in NSFetchRequest.
Dritte Praxis — konfigurieren Sie mergePolicy zur Lösung von Konflikten beim Multithread-Zugriff. NSMergeByPropertyObjectTrumpMergePolicy aktualisiert konfliktierende Eigenschaften aus dem zuletzt gespeicherten Kontext. NSRollbackMergePolicy verwirft aktuelle Kontextänderungen bei Konflikten. Die Wahl der Richtlinie hängt von der Geschäftslogik der Anwendung ab.
Vierte Praxis — verwenden Sie NSFetchedResultsController für die Integration mit Tabellen und Sammlungen. Er abonniert automatisch NSManagedObjectContextDidSave-Benachrichtigungen, lädt nur erforderliche Objekte (Faulting) und benachrichtigt den Delegierten über Einfügungen, Löschungen und Verschiebungen mit entsprechenden Indexpfaden für UITableView-Animationen.
Faulting ist der Lazy-Loading-Mechanismus von Core Data. Ein von einer Fetch-Anfrage zurückgegebenes verwaltetes Objekt befindet sich im Fault-Zustand — seine Attribute sind nicht vollständig geladen, nur die Kennung. Das vollständige Laden (Fire Fault) erfolgt beim ersten Zugriff auf ein Attribut. Relationship Prefetching (setRelationshipKeyPathsForPrefetching) lädt verwandte Objekte im Voraus und vermeidet N+1-Abfragen.
extension UserRepository {
func fetchUsersWithPosts() throws -> [User] {
let request = User.fetchRequest()
request.predicate = NSPredicate(format: "isActive == YES")
request.relationshipKeyPathsForPrefetching = ["posts"]
request.returnsObjectsAsFaults = false
request.fetchBatchSize = 20
let context = container.viewContext
return try context.fetch(request)
}
}
fetchBatchSize = 20 veranlasst Core Data, Daten in Batches von 20 Objekten zu laden (zur Bildschirmanzeige), ohne die gesamte Tabelle auf einmal zu laden. Das Flag returnsObjectsAsFaults = false stellt sicher, dass alle Benutzerattribute sofort geladen werden, was für die direkte Anzeige nützlich ist. Das Prefetching der “posts”-Beziehung vermeidet separate Abfragen für jeden Benutzer beim Zugriff auf Beiträge.
Häufig gestellte Fragen
Nein, Core Data ist ein Framework zur Objektgraphenverwaltung. Es bietet eine API zum Arbeiten mit Objekten, Verfolgen von Änderungen und deren Persistierung. Die Datenbank unter der Haube von Core Data (standardmäßig SQLite) sollte nicht mit dem Framework selbst verwechselt werden. Core Data ist ein ORM, kein DBMS.
Ja, Core Data unterstützt drei Speichertypen: SQLite, Binary und In-Memory. Der Speichertyp wird über NSPersistentStoreDescription festgelegt. In-Memory-Speicher persistiert keine Daten auf der Festplatte und eignet sich für Unit-Tests. Binary-Speicher ist ein Legacy-Format für kompakte Objektsätze.
Für die leichte Migration aktivieren Sie NSMigratePersistentStoresAutomaticallyOption und NSInferMappingModelAutomaticallyOption. Für komplexe Änderungen erstellen Sie ein Mapping Model (.xcmappingmodel) über Xcode. CloudKit-Speicher (NSPersistentCloudKitContainer) unterstützt Migrationen automatisch beim Synchronisieren des Schemas mit dem iCloud-Server.
SwiftData ist ein neues Apple-Framework (iOS 17+), das auf Core Data aufbaut und Swift Macros und Swift Concurrency verwendet. SwiftData hat eine einfachere Syntax: Entitäten werden mit dem @Model-Makro beschrieben, Kontext mit @Environment(\.modelContext). Unter der Haube verwendet SwiftData denselben Core Data-Stack und SQLite.
Aktivieren Sie das Startargument -com.apple.CoreData.SQLDebug 1 — Core Data gibt alle SQL-Abfragen und deren Dauer in der Xcode-Konsole aus. Zur Profilerstellung verwenden Sie Instruments mit der Core Data-Vorlage, die die Anzahl der Fault-Anfragen, Objektladezeiten und Kontextspeicherdauer anzeigt.
Zusammenfassung
Wir entwickeln eine mobile Applikation schlüsselfertig
IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.
Lesen Sie auch