Core Data — framework Apple pro správu grafu objektů v aplikacích iOS a macOS. Zajišťuje trvalé ukládání dat, sledování změn, vracení operací a integraci s UI prostřednictvím NSFetchedResultsController. Podle dokumentace Apple Developer (2025) není Core Data databáze — je to vrstva objektového modelování, která standardně používá SQLite jako trvalé úložiště pro načítání a ukládání objektů.
Hlavní body
Core Data — je framework pro správu grafů objektů a perzistenci dat, součást Cocoa Touch SDK od Apple. Poskytuje objektově orientované rozhraní pro práci s daty: vývojář pracuje s entitami (Entity), atributy a vztahy (Relationship) a Core Data převádí tyto objekty na záznamy relační databáze pod kapotou.
Core Data byl představen v Mac OS X 10.4 Tiger (2005) pro macOS a portován do iOS 3.0 (2009). Za více než 20 let se framework vyvinul z jednoduché abstrakční vrstvy nad SQLite na plnohodnotný zásobník s podporou cloudové synchronizace prostřednictvím NSPersistentCloudKitContainer, vícevláknovosti prostřednictvím automatické správy kontextů a asynchronního načítání prostřednictvím Swift Concurrency.
Podle průzkumu vývojářů iOS od Slack Community (2025) se Core Data používá v 68 % komerčních iOS aplikací pro lokální ukládání dat. Navzdory kritice za složitost a vícevrstevnatost zůstává framework standardem pro aplikace Apple díky úzké integraci se systémem, nulové ceně (vestavěný v SDK) a podpoře synchronizace iCloud.
Častá mylná představa — považovat Core Data za databázi. Framework neprovádí přímo SQL dotazy a není to DBMS. Core Data je vrstva pro správu objektů (object graph management), která může pro perzistenci používat SQLite, Binary nebo In-Memory. Analogie: Core Data je jako ORM jako Hibernate nebo Entity Framework, ale pro ekosystém Apple, a SQLite pod ním — jako MySQL pod Hibernate.
Zásobník Core Data se skládá ze čtyř vzájemně propojených komponent: NSManagedObjectModel (datové schéma), NSPersistentStoreCoordinator (koordinátor úložišť), NSManagedObjectContext (pracovní kontext) a NSPersistentContainer (jednotný kontejner spojující všechny tři od iOS 10). NSPersistentContainer automatizuje vytváření a konfiguraci zásobníku.
Každá komponenta plní přesně definovanou funkci. NSManagedObjectModel načítá soubor .xcdatamodeld s popisem entit. NSPersistentStoreCoordinator propojuje model s fyzickým souborem úložiště (SQLite). NSManagedObjectContext poskytuje dočasnou oblast pro práci s objekty. Kontejner spojuje vše do jednoho inicializačního volání.
SQLite (NSSQLiteStoreType) — standardní úložiště používané ve většině aplikací. Data jsou ukládána do jednoho souboru .sqlite s podporou ACID transakcí. Binary (NSBinaryStoreType) — úložiště v binárním formátu pro malé datové sady (do několika set objektů). In-Memory (NSInMemoryStoreType) — dočasné úložiště v RAM bez ukládání na disk, používané pro testy a cache.
| Typ úložiště | Formát | Výkon | Kdy použít |
|---|---|---|---|
| SQLite | .sqlite | Vysoký | Standardní volba pro produkci |
| Binary | .binary | Střední | Malé datové sady |
| In-Memory | RAM | Maximální | Testy, cache, dočasná data |
| CloudKit | iCloud | Závisí na síti | Synchronizace mezi zařízeními |
Výběr úložiště se nastavuje jedním řádkem při inicializaci NSPersistentStoreDescription. Vývojář může přepnout úložiště z SQLite na In-Memory pro unit testy nebo na CloudKit pro synchronizaci iCloud bez změny kódu pro práci s objekty — Core Data abstrahuje rozdíl mezi typy úložišť pomocí jednotného API kontextu.
NSManagedObject — základní třída pro všechny objekty Core Data představující jeden záznam entity. Každý spravovaný objekt má jedinečné NSManagedObjectID (trvalý identifikátor), je vázán na kontext a sleduje své změny prostřednictvím KVO (Key-Value Observing). Vývojář vytváří podtřídy NSManagedObject pro definici typových vlastností entity.
NSManagedObjectContext — centrální komponenta Core Data poskytující pracovní oblast pro všechny operace s objekty. Kontext sleduje přidávání, mazání a změny objektů (change tracking), podporuje vracení operací pomocí undoManager a automaticky slučuje změny z jiných kontextů při přijetí oznámení o uložení.
Pravidlo soukromých front: NSManagedObjectContext se vytváří s typem .privateQueueConcurrencyType nebo .mainQueueConcurrencyType. Hlavní kontext je vázán na hlavní UI vlákno, soukromé kontexty běží na frontách na pozadí. Každý kontext musí být použit pouze ve své frontě — přístup ke spravovanému objektu z jiného vlákna způsobí crash. parentContext umožňuje organizovat hierarchii kontextů pro asynchronní zápis.
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 automaticky vytváří viewContext (main queue) a poskytuje newBackgroundContext() pro operace na pozadí. Vlastnost automaticallyMergesChangesFromParent = true způsobí, že viewContext automaticky přebírá změny z kontextů na pozadí při jejich uložení, čímž aktualizuje UI bez ručního opětovného načítání dat.
NSPersistentStoreCoordinator spravuje fyzické úložiště dat: otevírá soubor, vytváří tabulky SQLite na základě modelu, provádí migrace při změně schématu. Při inicializaci NSPersistentStoreDescription s typem NSSQLiteStoreType vytváří Core Data soubor SQLite se schématem odpovídajícím modelu .xcdatamodeld.
Core Data nepoužívá standardní SQL dotazy přes SELECT/INSERT/UPDATE. Místo toho generuje interní SQL příkazy na základě modelu a dotazů prostřednictvím NSFetchRequest. Vývojář může zapnout logování SQL pomocí spouštěcího argumentu -com.apple.CoreData.SQLDebug 1 pro ladění výkonu dotazů.
Lehká migrace (Lightweight Migration) — automatický proces aktualizace schématu SQLite při přidávání nových atributů, změně optional/required nebo přejmenování pomocí renamingID. Těžká migrace je vyžadována při zásadních změnách schématu, jako je slučování nebo rozdělování entit, a provádí se pomocí vlastního 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)") }
}
Konfigurace automatické migrace pomocí NSMigratePersistentStoresAutomaticallyOption a NSInferMappingModelAutomaticallyOption umožňuje Core Data samostatně aktualizovat SQLite soubor při přidávání atributů nebo entit v nové verzi modelu. Pokud migrace není možná, store coordinator vyvolá chybu s popisem důvodu — vývojář musí implementovat vlastní migraci pomocí NSMigrationManager.
NSFetchRequest — hlavní nástroj pro získávání objektů z Core Data. Dotaz obsahuje název entity, predikát (filtr), řazení, limit a offset. Výsledek je vrácen jako pole NSManagedObject nebo typových podtříd. NSPredicate podporuje složité podmínky s AND, OR, IN, LIKE a poddotazy.
NSBatchDeleteRequest — efektivní způsob hromadného mazání objektů bez načítání každého do paměti. Dotaz se provádí na úrovni SQLite, obchází managed object context, a aktualizuje kontext až po dokončení. Podobné dávkové dotazy existují pro aktualizaci (NSBatchUpdateRequest) a vkládání (NSBatchInsertRequest).
CRUD (Create, Read, Update, Delete) v Core Data se provádí pomocí metod kontextu: insert, fetch, save a delete. Všechny změny jsou dočasné až do volání context.save() — metoda ukládá změny do trvalého úložiště SQLite. Při chybě ukládání zůstává kontext v změněném stavu pro opakování.
let context = container.viewContext
// Vytvořit
let user = User(context: context)
user.id = 42
user.name = "Alice"
// Číst
let request = User.fetchRequest()
request.predicate = NSPredicate(format: "name CONTAINS %@", "Ali")
request.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]
let results = try context.fetch(request)
// Aktualizovat
results.first?.name = "Alice Updated"
// Smazat
if let first = results.first { context.delete(first) }
// Uložit
try context.save()
Uložení kontextu (context.save()) — kritická operace. Pokud není uložení vyvoláno, všechny změny zůstávají pouze v paměti. Kontext sleduje stav hasChanges, který lze zkontrolovat před uložením. Pro operace na pozadí používejte newBackgroundContext s vlastním uložením a pro UI — viewContext s automatickým uložením podle časovače nebo při přechodu aplikace na pozadí.
První postup — používejte NSPersistentCloudKitContainer pro synchronizaci dat mezi zařízeními uživatele přes iCloud. Cloudová synchronizace se aktivuje přidáním možnosti CloudKit k popisu úložiště. Core Data automaticky spravuje konflikty při synchronizaci a slučuje změny z jiných zařízení.
Druhý postup — vyhněte se fetchRequest bez predikátu na velkých tabulkách. Každé bezpodmínečné načtení nahraje všechny objekty entity do paměti, což vede k vysoké spotřebě RAM a zpomalení UI. Vždy používejte predikáty a limity. Pro stránkování použijte fetchLimit a fetchOffset v NSFetchRequest.
Třetí postup — nakonfigurujte mergePolicy pro řešení konfliktů při vícevláknovém přístupu. NSMergeByPropertyObjectTrumpMergePolicy aktualizuje konfliktní vlastnosti z posledního uloženého kontextu. NSRollbackMergePolicy ruší změny aktuálního kontextu při konfliktu. Volba politiky závisí na obchodní logice aplikace.
Čtvrtý postup — používejte NSFetchedResultsController pro integraci s tabulkami a kolekcemi. Automaticky se přihlašuje k odběru oznámení NSManagedObjectContextDidSave, načítá pouze potřebné objekty (faulting) a informuje delegáta o vkládání, mazání a přesunech s odpovídajícími cestami indexů pro animaci UITableView.
Faulting — mechanismus líného načítání objektů Core Data. Spravovaný objekt vrácený fetch dotazem je ve stavu fault — jeho atributy nejsou plně načteny, pouze identifikátor. Plné načtení (fire fault) nastává při prvním přístupu k libovolnému atributu. Relationship prefetching (setRelationshipKeyPathsForPrefetching) načítá související objekty předem a vyhýbá se tak dotazům N+1.
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 nutí Core Data načítat data po dávkách 20 objektů (pro zobrazení na obrazovce), aniž by načetla celou tabulku najednou. Příznak returnsObjectsAsFaults = false zaručuje, že atributy všech uživatelů jsou načteny okamžitě, což je užitečné pro přímé zobrazení. Prefetching vztahu "posts" se vyhýbá samostatným dotazům pro každého uživatele při přístupu k příspěvkům.
Často kladené dotazy
Ne, Core Data je framework pro správu grafu objektů. Poskytuje API pro práci s objekty, sledování změn a jejich ukládání. Databázi pod Core Data (standardně SQLite) byste neměli zaměňovat se samotným frameworkem. Core Data je ORM, nikoli DBMS.
Ano, Core Data podporuje tři typy úložišť: SQLite, Binary a In-Memory. Výběr úložiště se nastavuje pomocí NSPersistentStoreDescription. Úložiště In-Memory neukládá data na disk a je vhodné pro unit testy. Binární úložiště je zastaralý formát pro kompaktní sady objektů.
Pro lehlkou migraci zapněte NSMigratePersistentStoresAutomaticallyOption a NSInferMappingModelAutomaticallyOption. Pro složité změny vytvořte Mapping Model (.xcmappingmodel) přes Xcode. CloudKit úložiště (NSPersistentCloudKitContainer) podporuje migrace automaticky při synchronizaci schématu se serverem iCloud.
SwiftData — je nový framework Apple (iOS 17+), postavený nad Core Data pomocí Swift Macros a Swift Concurrency. SwiftData je jednodušší v syntaxi: entity se popisují makrem @Model, kontext — @Environment(\.modelContext). Pod kapotou SwiftData používá stejný zásobník Core Data a SQLite.
Zapněte spouštěcí argument -com.apple.CoreData.SQLDebug 1 — Core Data bude zobrazovat všechny SQL dotazy a jejich dobu trvání v konzoli Xcode. Pro profilování použijte Instruments se šablonou Core Data, která ukazuje počet fault dotazů, načítání objektů a čas ukládání kontextu.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také