Core Data — Apples ramverk för hantering av objektgrafer i iOS- och macOS-applikationer. Det ger datapersistens, spårning av ändringar, ångra operationer och integrering med UI via NSFetchedResultsController. Enligt Apple Developer-dokumentationen (2025) är Core Data inte en databas — det är ett objektmodelleringslager som som standard använder SQLite som permanent lagring för att ladda och spara objekt.
Huvudpunkter
Core Data — är ett ramverk för objektgrafshantering och datapersistens, en del av Apples Cocoa Touch SDK. Det ger ett objektorienterat gränssnitt för att arbeta med data: utvecklaren arbetar med entiteter (Entity), attribut och relationer (Relationship), och Core Data omvandlar dessa objekt till poster i en relationell databas under huven.
Core Data introducerades i Mac OS X 10.4 Tiger (2005) för macOS och porterades till iOS 3.0 (2009). Under mer än 20 år har ramverket utvecklats från ett enkelt abstraktionslager över SQLite till en fullständig stack med stöd för molnsynkronisering via NSPersistentCloudKitContainer, flertrådning via automatisk kontexthantering och asynkron laddning via Swift Concurrency.
Enligt en undersökning av iOS-utvecklare från Slack Community (2025) används Core Data i 68% av kommersiella iOS-applikationer för lokal datalagring. Trots kritik för komplexitet och flerskiktighet förblir ramverket standard för Apple-applikationer tack vare nära integration med systemet, noll kostnad (inbyggt i SDK) och stöd för iCloud-synkronisering.
En vanlig missuppfattning — att betrakta Core Data som en databas. Ramverket utför inte SQL-frågor direkt och är inget DBMS. Core Data är ett objekthanteringslager (object graph management) som kan använda SQLite, Binary eller In-Memory för persistens. Analogi: Core Data är som ORM såsom Hibernate eller Entity Framework, men för Apples ekosystem, och SQLite under det — som MySQL under Hibernate.
Core Data-stacken består av fyra sammankopplade komponenter: NSManagedObjectModel (dataschema), NSPersistentStoreCoordinator (lagringskoordinator), NSManagedObjectContext (arbetskontext) och NSPersistentContainer (enhetlig behållare som kombinerar alla tre från iOS 10). NSPersistentContainer automatiserar skapandet och konfigurationen av stacken.
Varje komponent utför en strikt definierad funktion. NSManagedObjectModel laddar .xcdatamodeld-filen med beskrivning av entiteter. NSPersistentStoreCoordinator kopplar modellen till den fysiska lagringsfilen (SQLite). NSManagedObjectContext tillhandahåller ett tillfälligt område för att arbeta med objekt. Behållaren kombinerar allt i ett enda initialiseringsanrop.
SQLite (NSSQLiteStoreType) — standardlagring som används i de flesta applikationer. Data sparas i en .sqlite-fil med stöd för ACID-transaktioner. Binary (NSBinaryStoreType) — lagring i binärt format för små datamängder (upp till några hundra objekt). In-Memory (NSInMemoryStoreType) — tillfällig lagring i RAM utan lagring på disk, används för tester och cache.
| Lagringstyp | Format | Prestanda | När ska användas |
|---|---|---|---|
| SQLite | .sqlite | Hög | Standardval för produktion |
| Binary | .binary | Medel | Små datamängder |
| In-Memory | RAM | Maximal | Tester, cache, tillfällig data |
| CloudKit | iCloud | Beror på nätverk | Synkronisering mellan enheter |
Valet av lagring ställs in med en enda rad vid initialisering av NSPersistentStoreDescription. Utvecklaren kan växla lagring från SQLite till In-Memory för enhetstester eller till CloudKit för iCloud-synkronisering utan att ändra koden för att arbeta med objekt — Core Data abstraherar skillnaden mellan lagringstyper via ett enhetligt kontext-API.
NSManagedObject — basklassen för alla Core Data-objekt som representerar en entitetspost. Varje hanterat objekt har ett unikt NSManagedObjectID (permanent identifierare), är bundet till en kontext och spårar sina ändringar via KVO (Key-Value Observing). Utvecklaren skapar underklasser av NSManagedObject för att definiera typade egenskaper för entiteten.
NSManagedObjectContext — den centrala komponenten i Core Data som tillhandahåller en arbetsyta för alla operationer med objekt. Kontexten spårar tillägg, borttagningar och ändringar av objekt (change tracking), stöder ångra operationer via undoManager och slår automatiskt samman ändringar från andra kontexter vid mottagande av sparningsmeddelanden.
Regel för privata köer: NSManagedObjectContext skapas med typen .privateQueueConcurrencyType eller .mainQueueConcurrencyType. Huvudkontexten är bunden till huvud-UI-tråden, privata kontexter körs på bakgrundsköer. Varje kontext får endast användas i sin egen kö — åtkomst till ett hanterat objekt från en annan tråd orsakar en krasch. parentContext gör det möjligt att organisera en hierarki av kontexter för asynkron skrivning.
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 skapar automatiskt viewContext (main queue) och tillhandahåller newBackgroundContext() för bakgrundsoperationer. Egenskapen automaticallyMergesChangesFromParent = true får viewContext att automatiskt hämta ändringar från bakgrundskontexter när de sparas, vilket uppdaterar UI utan manuell återhämtning av data.
NSPersistentStoreCoordinator hanterar den fysiska datalagringen: öppnar filen, skapar SQLite-tabeller baserat på modellen, utför migreringar vid schemaändringar. Vid initialisering av NSPersistentStoreDescription med typen NSSQLiteStoreType skapar Core Data en SQLite-fil med schema som motsvarar .xcdatamodeld-modellen.
Core Data använder inte standard SQL-frågor via SELECT/INSERT/UPDATE. Istället genererar det interna SQL-kommandon baserat på modellen och frågor via NSFetchRequest. Utvecklaren kan aktivera SQL-loggning via startargumentet -com.apple.CoreData.SQLDebug 1 för felsökning av frågeprestanda.
Lätt migrering (Lightweight Migration) — den automatiska processen att uppdatera SQLite-schemat vid tillägg av nya attribut, ändring av optional/required eller omdöpning med hjälp av renamingID. Tung migrering krävs vid genomgripande schemaändringar såsom sammanslagning eller delning av entiteter och utförs via en anpassad NSMigrationManager.
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)") }
}
Konfiguration av automatisk migrering via NSMigratePersistentStoresAutomaticallyOption och NSInferMappingModelAutomaticallyOption gör det möjligt för Core Data att självständigt uppdatera SQLite-filen vid tillägg av attribut eller entiteter i en ny version av modellen. Om migrering inte är möjlig kastar lagringskoordinatorn ett fel med beskrivning av orsaken — utvecklaren måste implementera en anpassad migrering via NSMigrationManager.
NSFetchRequest — det huvudsakliga verktyget för att hämta objekt från Core Data. Frågan innehåller entitetsnamn, predikat (filter), sorteringar, gräns och offset. Resultatet returneras som en array av NSManagedObject eller typade underklasser. NSPredicate stöder komplexa villkor med AND, OR, IN, LIKE och underfrågor.
NSBatchDeleteRequest — ett effektivt sätt att massradera objekt utan att ladda varje objekt i minnet. Frågan körs på SQLite-nivå, förbigår managed object context och uppdaterar endast kontexten efter slutförande. Liknande batch-frågor finns för uppdatering (NSBatchUpdateRequest) och infogning (NSBatchInsertRequest).
CRUD (Create, Read, Update, Delete) i Core Data utförs via kontextmetoder: insert, fetch, save och delete. Alla ändringar är tillfälliga tills anropet av context.save() — metoden sparar ändringar i den permanenta SQLite-lagringen. Vid sparfel förblir kontexten i ändrat tillstånd för nytt försök.
let context = container.viewContext
// Skapa
let user = User(context: context)
user.id = 42
user.name = "Alice"
// Läsa
let request = User.fetchRequest()
request.predicate = NSPredicate(format: "name CONTAINS %@", "Ali")
request.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]
let results = try context.fetch(request)
// Uppdatera
results.first?.name = "Alice Updated"
// Ta bort
if let first = results.first { context.delete(first) }
// Spara
try context.save()
Spara kontexten (context.save()) — en kritisk operation. Om spara inte anropas förblir alla ändringar endast i minnet. Kontexten spårar tillståndet hasChanges, som kan kontrolleras före sparande. För bakgrundsoperationer, använd newBackgroundContext med eget sparande, och för UI — viewContext med automatiskt sparande baserat på timer eller när appen går i bakgrunden.
Första praxis — använd NSPersistentCloudKitContainer för att synkronisera data mellan användarens enheter via iCloud. Molnsynkronisering aktiveras genom att lägga till CloudKit-alternativet till lagringsbeskrivningen. Core Data hanterar automatiskt konflikter under synkronisering och slår samman ändringar från andra enheter.
Andra praxis — undvik fetchRequest utan predikat på stora tabeller. Varje ovillkorlig hämtning laddar alla objekt i entiteten i minnet, vilket leder till hög RAM-förbrukning och långsamt UI. Använd alltid predikat och gränser. För paginering, använd fetchLimit och fetchOffset i NSFetchRequest.
Tredje praxis — konfigurera mergePolicy för att lösa konflikter vid flertrådad åtkomst. NSMergeByPropertyObjectTrumpMergePolicy uppdaterar konfliktande egenskaper från den senast sparade kontexten. NSRollbackMergePolicy ångrar ändringar i den aktuella kontexten vid konflikt. Valet av policy beror på applikationens affärslogik.
Fjärde praxis — använd NSFetchedResultsController för integration med tabeller och samlingar. Den prenumererar automatiskt på NSManagedObjectContextDidSave-meddelanden, laddar endast nödvändiga objekt (faulting) och meddelar delegaten om insättningar, borttagningar och flyttningar med motsvarande indexsökvägar för UITableView-animering.
Faulting — mekanismen för lat laddning av Core Data-objekt. Ett hanterat objekt som returneras av en fetch-fråga är i fault-tillstånd — dess attribut är inte fullt laddade, endast identifieraren. Full laddning (fire fault) sker vid första åtkomst till ett attribut. Relationship prefetching (setRelationshipKeyPathsForPrefetching) laddar relaterade objekt i förväg och undviker N+1-frågor.
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 tvingar Core Data att ladda data i portioner om 20 objekt (för visning på skärmen), utan att ladda hela tabellen på en gång. Flaggan returnsObjectsAsFaults = false garanterar att alla användares attribut laddas omedelbart, vilket är användbart för direkt visning. Prefetching av relationen "posts" undviker separata frågor för varje användare vid åtkomst till inlägg.
Vanliga frågor
Nej, Core Data är ett ramverk för objektgrafshantering. Det tillhandahåller API för att arbeta med objekt, spåra ändringar och spara dem. Databasen under Core Data (som standard SQLite) ska inte förväxlas med själva ramverket. Core Data är ett ORM, inte ett DBMS.
Ja, Core Data stöder tre typer av lagring: SQLite, Binary och In-Memory. Valet av lagring ställs in via NSPersistentStoreDescription. In-Memory-lagring sparar inte data på disk och är lämplig för enhetstester. Binary-lagring är ett föråldrat format för kompakta objektsamlingar.
För lätt migrering, aktivera NSMigratePersistentStoresAutomaticallyOption och NSInferMappingModelAutomaticallyOption. För komplexa ändringar, skapa en Mapping Model (.xcmappingmodel) via Xcode. CloudKit-lagring (NSPersistentCloudKitContainer) stöder migreringar automatiskt vid synkronisering av schemat med iCloud-servern.
SwiftData — är ett nytt Apple-ramverk (iOS 17+), byggt ovanpå Core Data med Swift Macros och Swift Concurrency. SwiftData är enklare i syntax: entiteter beskrivs med @Model-makrot, kontext — med @Environment(\.modelContext). Under huven använder SwiftData samma Core Data-stack och SQLite.
Aktivera startargumentet -com.apple.CoreData.SQLDebug 1 — Core Data kommer att visa alla SQL-frågor och deras varaktighet i Xcode-konsolen. För profilering, använd Instruments med Core Data-mallen, som visar antalet fault-frågor, objektladdning och kontextsparningstid.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också