Core Data — το πλαίσιο της Apple για διαχείριση γράφου αντικειμένων σε εφαρμογές iOS και macOS. Παρέχει αποθήκευση δεδομένων, παρακολούθηση αλλαγών, αναίρεση λειτουργιών και ενσωμάτωση με το UI μέσω του NSFetchedResultsController. Σύμφωνα με την τεκμηρίωση του Apple Developer (2025), το Core Data δεν είναι βάση δεδομένων — είναι ένα επίπεδο αντικειμενοστρεφούς μοντελοποίησης που από προεπιλογή χρησιμοποιεί SQLite ως μόνιμη αποθήκευση για φόρτωση και αποθήκευση αντικειμένων.
Κύρια Σημεία
Core Data — είναι ένα πλαίσιο διαχείρισης γράφου αντικειμένων και μονιμότητας δεδομένων, μέρος του Cocoa Touch SDK της Apple. Παρέχει μια αντικειμενοστρεφή διεπαφή για εργασία με δεδομένα: ο προγραμματιστής λειτουργεί με οντότητες (Entity), ιδιότητες και σχέσεις (Relationship), και το Core Data μετατρέπει αυτά τα αντικείμενα σε εγγραφές σχεσιακής βάσης δεδομένων κάτω από το καπό.
Το Core Data παρουσιάστηκε στο Mac OS X 10.4 Tiger (2005) για macOS και μεταφέρθηκε στο iOS 3.0 (2009). Για περισσότερα από 20 χρόνια, το πλαίσιο εξελίχθηκε από ένα απλό επίπεδο αφαίρεσης πάνω από την SQLite σε μια πλήρη στοίβα με υποστήριξη συγχρονισμού cloud μέσω NSPersistentCloudKitContainer, πολυνηματικότητα μέσω αυτόματης διαχείρισης περιβάλλοντος και ασύγχρονη φόρτωση μέσω Swift Concurrency.
Σύμφωνα με έρευνα προγραμματιστών iOS από το Slack Community (2025), το Core Data χρησιμοποιείται στο 68% των εμπορικών εφαρμογών iOS για τοπική αποθήκευση δεδομένων. Παρά την κριτική για πολυπλοκότητα και πολυεπίπεδοτη αρχιτεκτονική, το πλαίσιο παραμένει το πρότυπο για εφαρμογές Apple χάρη στη στενή ενσωμάτωση με το σύστημα, το μηδενικό κόστος (ενσωματωμένο στο SDK) και την υποστήριξη συγχρονισμού iCloud.
Μια κοινή παρανόηση — να θεωρείται το Core Data ως βάση δεδομένων. Το πλαίσιο δεν εκτελεί απευθείας SQL ερωτήματα και δεν είναι ΣΔΒΔ. Το Core Data είναι ένα επίπεδο διαχείρισης αντικειμένων (object graph management) που μπορεί να χρησιμοποιήσει SQLite, Binary ή In-Memory για μονιμότητα. Αναλογία: Το Core Data είναι σαν ORM όπως Hibernate ή Entity Framework, αλλά για το οικοσύστημα Apple, και η SQLite από κάτω — όπως η MySQL κάτω από το Hibernate.
Η στοίβα Core Data αποτελείται από τέσσερα διασυνδεδεμένα στοιχεία: NSManagedObjectModel (σχήμα δεδομένων), NSPersistentStoreCoordinator (συντονιστής αποθήκευσης), NSManagedObjectContext (περιβάλλον εργασίας) και NSPersistentContainer (ενιαίο δοχείο που συνδυάζει και τα τρία από το iOS 10). Το NSPersistentContainer αυτοματοποιεί τη δημιουργία και διαμόρφωση της στοίβας.
Κάθε στοιχείο εκτελεί μια αυστηρά καθορισμένη λειτουργία. NSManagedObjectModel φορτώνει το αρχείο .xcdatamodeld με την περιγραφή των οντοτήτων. NSPersistentStoreCoordinator συνδέει το μοντέλο με το φυσικό αρχείο αποθήκευσης (SQLite). NSManagedObjectContext παρέχει μια προσωρινή περιοχή για εργασία με αντικείμενα. Το Container συνδυάζει τα πάντα σε μια κλήση προετοιμασίας.
SQLite (NSSQLiteStoreType) — η τυπική αποθήκευση που χρησιμοποιείται στις περισσότερες εφαρμογές. Τα δεδομένα αποθηκεύονται σε ένα αρχείο .sqlite με υποστήριξη συναλλαγών ACID. Binary (NSBinaryStoreType) — αποθήκευση σε δυαδική μορφή για μικρά σύνολα δεδομένων (έως μερικές εκατοντάδες αντικείμενα). In-Memory (NSInMemoryStoreType) — προσωρινή αποθήκευση στη μνήμη RAM χωρίς αποθήκευση σε δίσκο, χρησιμοποιείται για δοκιμές και προσωρινή μνήμη.
| Τύπος αποθήκευσης | Μορφή | Απόδοση | Πότε να χρησιμοποιηθεί |
|---|---|---|---|
| SQLite | .sqlite | Υψηλή | Τυπική επιλογή για production |
| Binary | .binary | Μεσαία | Μικρά σύνολα δεδομένων |
| In-Memory | RAM | Μέγιστη | Δοκιμές, προσωρινή μνήμη, προσωρινά δεδομένα |
| CloudKit | iCloud | Εξαρτάται από δίκτυο | Συγχρονισμός μεταξύ συσκευών |
Η επιλογή αποθήκευσης ορίζεται με μία γραμμή κατά την προετοιμασία του NSPersistentStoreDescription. Ο προγραμματιστής μπορεί να αλλάξει την αποθήκευση από SQLite σε In-Memory για δοκιμές μονάδας ή σε CloudKit για συγχρονισμό iCloud χωρίς να αλλάξει τον κώδικα εργασίας με αντικείμενα — το Core Data αφαιρεί τη διαφορά μεταξύ τύπων αποθήκευσης με ένα ενιαίο API περιβάλλοντος.
NSManagedObject — η βασική κλάση για όλα τα αντικείμενα Core Data, που αντιπροσωπεύει μία εγγραφή οντότητας. Κάθε διαχειριζόμενο αντικείμενο έχει ένα μοναδικό NSManagedObjectID (μόνιμο αναγνωριστικό), είναι συνδεδεμένο με ένα περιβάλλον και παρακολουθεί τις αλλαγές του μέσω KVO (Key-Value Observing). Ο προγραμματιστής δημιουργεί υποκλάσεις του NSManagedObject για να ορίσει τυποποιημένες ιδιότητες της οντότητας.
NSManagedObjectContext — το κεντρικό στοιχείο του Core Data που παρέχει ένα χώρο εργασίας για όλες τις λειτουργίες με αντικείμενα. Το περιβάλλον παρακολουθεί προσθήκες, διαγραφές και τροποποιήσεις αντικειμένων (change tracking), υποστηρίζει αναίρεση λειτουργιών μέσω undoManager και συγχωνεύει αυτόματα αλλαγές από άλλα περιβάλλοντα όταν λαμβάνει ειδοποιήσεις αποθήκευσης.
Κανόνας ιδιωτικών ουρών: Το NSManagedObjectContext δημιουργείται με τύπο .privateQueueConcurrencyType ή .mainQueueConcurrencyType. Το κύριο περιβάλλον είναι συνδεδεμένο με το κύριο νήμα UI, τα ιδιωτικά περιβάλλοντα εκτελούνται σε ουρές παρασκηνίου. Κάθε περιβάλλον πρέπει να χρησιμοποιείται μόνο στη δική του ουρά — η πρόσβαση σε ένα διαχειριζόμενο αντικείμενο από άλλο νήμα προκαλεί σφάλμα. parentContext επιτρέπει την οργάνωση μιας ιεραρχίας περιβαλλόντων για ασύγχρονη εγγραφή.
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 δημιουργεί αυτόματα viewContext (main queue) και παρέχει newBackgroundContext() για λειτουργίες παρασκηνίου. Η ιδιότητα automaticallyMergesChangesFromParent = true κάνει το viewContext να λαμβάνει αυτόματα αλλαγές από περιβάλλοντα παρασκηνίου κατά την αποθήκευσή τους, ενημερώνοντας το UI χωρίς χειροκίνητη εκ νέου λήψη δεδομένων.
NSPersistentStoreCoordinator διαχειρίζεται τη φυσική αποθήκευση δεδομένων: ανοίγει το αρχείο, δημιουργεί πίνακες SQLite βάσει του μοντέλου, εκτελεί μεταναστεύσεις κατά την αλλαγή σχήματος. Κατά την προετοιμασία NSPersistentStoreDescription με τύπο NSSQLiteStoreType, το Core Data δημιουργεί ένα αρχείο SQLite με σχήμα που αντιστοιχεί στο μοντέλο .xcdatamodeld.
Το Core Data δεν χρησιμοποιεί τυπικά SQL ερωτήματα μέσω SELECT/INSERT/UPDATE. Αντίθετα, δημιουργεί εσωτερικές εντολές SQL βάσει του μοντέλου και ερωτημάτων μέσω NSFetchRequest. Ο προγραμματιστής μπορεί να ενεργοποιήσει την καταγραφή SQL μέσω της παραμέτρου εκκίνησης -com.apple.CoreData.SQLDebug 1 για αποσφαλμάτωση απόδοσης ερωτημάτων.
Ελαφριά μετανάστευση (Lightweight Migration) — η αυτόματη διαδικασία ενημέρωσης του σχήματος SQLite κατά την προσθήκη νέων ιδιοτήτων, αλλαγής optional/required ή μετονομασίας με renamingID. Η βαριά μετανάστευση απαιτείται για ριζικές αλλαγές σχήματος, όπως συγχώνευση ή διαίρεση οντοτήτων, και εκτελείται μέσω προσαρμοσμένου 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)") }
}
Η διαμόρφωση αυτόματης μετανάστευσης μέσω NSMigratePersistentStoresAutomaticallyOption και NSInferMappingModelAutomaticallyOption επιτρέπει στο Core Data να ενημερώνει ανεξάρτητα το αρχείο SQLite κατά την προσθήκη ιδιοτήτων ή οντοτήτων σε νέα έκδοση του μοντέλου. Εάν η μετανάστευση δεν είναι δυνατή, ο συντονιστής αποθήκευσης ρίχνει σφάλμα με περιγραφή της αιτίας — ο προγραμματιστής πρέπει να υλοποιήσει προσαρμοσμένη μετανάστευση μέσω NSMigrationManager.
NSFetchRequest — το κύριο εργαλείο για ανάκτηση αντικειμένων από το Core Data. Το ερώτημα περιέχει το όνομα οντότητας, κατηγόρημα (φίλτρο), ταξινομήσεις, όριο και μετατόπιση (offset). Το αποτέλεσμα επιστρέφεται ως πίνακας NSManagedObject ή τυποποιημένων υποκλάσεων. Το NSPredicate υποστηρίζει σύνθετες συνθήκες με AND, OR, IN, LIKE και υποερωτήματα.
NSBatchDeleteRequest — ένας αποτελεσματικός τρόπος μαζικής διαγραφής αντικειμένων χωρίς φόρτωση καθενός στη μνήμη. Το ερώτημα εκτελείται σε επίπεδο SQLite, παρακάμπτοντας το managed object context, και ενημερώνει το περιβάλλον μόνο μετά την ολοκλήρωση. Παρόμοια μαζικά ερωτήματα υπάρχουν για ενημέρωση (NSBatchUpdateRequest) και εισαγωγή (NSBatchInsertRequest).
CRUD (Create, Read, Update, Delete) στο Core Data εκτελείται μέσω μεθόδων περιβάλλοντος: insert, fetch, save και delete. Όλες οι αλλαγές είναι προσωρινές μέχρι την κλήση context.save() — η μέθοδος αποθηκεύει αλλαγές στη μόνιμη αποθήκευση SQLite. Σε σφάλμα αποθήκευσης, το περιβάλλον παραμένει σε τροποποιημένη κατάσταση για επανάληψη.
let context = container.viewContext
// Δημιουργία
let user = User(context: context)
user.id = 42
user.name = "Alice"
// Ανάγνωση
let request = User.fetchRequest()
request.predicate = NSPredicate(format: "name CONTAINS %@", "Ali")
request.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]
let results = try context.fetch(request)
// Ενημέρωση
results.first?.name = "Alice Updated"
// Διαγραφή
if let first = results.first { context.delete(first) }
// Αποθήκευση
try context.save()
Αποθήκευση περιβάλλοντος (context.save()) — κρίσιμη λειτουργία. Εάν η αποθήκευση δεν κληθεί, όλες οι αλλαγές παραμένουν μόνο στη μνήμη. Το περιβάλλον παρακολουθεί την κατάσταση hasChanges, η οποία μπορεί να ελεγχθεί πριν από την αποθήκευση. Για λειτουργίες παρασκηνίου χρησιμοποιήστε newBackgroundContext με δική του αποθήκευση, και για UI — viewContext με αυτόματη αποθήκευση βάσει χρονοδιακόπτη ή όταν η εφαρμογή πηγαίνει στο παρασκήνιο.
Πρώτη πρακτική — χρησιμοποιήστε NSPersistentCloudKitContainer για συγχρονισμό δεδομένων μεταξύ συσκευών χρήστη μέσω iCloud. Ο συγχρονισμός cloud ενεργοποιείται με προσθήκη επιλογής CloudKit στην περιγραφή αποθήκευσης. Το Core Data διαχειρίζεται αυτόματα συγκρούσεις κατά τον συγχρονισμό και συγχωνεύει αλλαγές από άλλες συσκευές.
Δεύτερη πρακτική — αποφύγετε fetchRequest χωρίς κατηγόρημα σε μεγάλους πίνακες. Κάθε ανεπιφύλακτη ανάκτηση φορτώνει όλα τα αντικείμενα της οντότητας στη μνήμη, οδηγώντας σε υψηλή κατανάλωση RAM και επιβράδυνση UI. Πάντα χρησιμοποιείτε κατηγορήματα και όρια. Για σελιδοποίηση, εφαρμόστε fetchLimit και fetchOffset στο NSFetchRequest.
Τρίτη πρακτική — διαμορφώστε το mergePolicy για επίλυση συγκρούσεων σε πολυνηματική πρόσβαση. Το NSMergeByPropertyObjectTrumpMergePolicy ενημερώνει συγκρουόμενες ιδιότητες από το τελευταίο αποθηκευμένο περιβάλλον. Το NSRollbackMergePolicy ακυρώνει αλλαγές του τρέχοντος περιβάλλοντος σε σύγκρουση. Η επιλογή πολιτικής εξαρτάται από την επιχειρηματική λογική της εφαρμογής.
Τέταρτη πρακτική — χρησιμοποιήστε NSFetchedResultsController για ενσωμάτωση με πίνακες και συλλογές. Εγγράφεται αυτόματα σε ειδοποιήσεις NSManagedObjectContextDidSave, φορτώνει μόνο τα απαραίτητα αντικείμενα (faulting) και ειδοποιεί τον εκπρόσωπο για εισαγωγές, διαγραφές και μετακινήσεις με αντίστοιχες διαδρομές ευρετηρίου για κινούμενα σχέδια UITableView.
Faulting — ο μηχανισμός τεμπέλικης φόρτωσης αντικειμένων Core Data. Το διαχειριζόμενο αντικείμενο που επιστρέφεται από ένα ερώτημα fetch βρίσκεται σε κατάσταση fault — οι ιδιότητές του δεν είναι πλήρως φορτωμένες, μόνο το αναγνωριστικό. Η πλήρης φόρτωση (fire fault) συμβαίνει κατά την πρώτη πρόσβαση σε οποιαδήποτε ιδιότητα. Relationship prefetching (setRelationshipKeyPathsForPrefetching) φορτώνει σχετικά αντικείμενα εκ των προτέρων, αποφεύγοντας ερωτήματα 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 αναγκάζει το Core Data να φορτώνει δεδομένα σε δόσεις των 20 αντικειμένων (για εμφάνιση στην οθόνη), χωρίς να φορτώνει ολόκληρο τον πίνακα ταυτόχρονα. Η σημαία returnsObjectsAsFaults = false εγγυάται ότι οι ιδιότητες όλων των χρηστών φορτώνονται αμέσως, χρήσιμο για άμεση εμφάνιση. Το prefetching της σχέσης "posts" αποφεύγει ξεχωριστά ερωτήματα για κάθε χρήστη κατά την πρόσβαση σε αναρτήσεις.
Συχνές Ερωτήσεις
Όχι, το Core Data είναι ένα πλαίσιο διαχείρισης γράφου αντικειμένων. Παρέχει API για εργασία με αντικείμενα, παρακολούθηση αλλαγών και αποθήκευσή τους. Η βάση δεδομένων κάτω από το Core Data (από προεπιλογή SQLite) δεν πρέπει να συγχέεται με το ίδιο το πλαίσιο. Το Core Data είναι ORM, όχι ΣΔΒΔ.
Ναι, το Core Data υποστηρίζει τρεις τύπους αποθήκευσης: SQLite, Binary και In-Memory. Η επιλογή αποθήκευσης ορίζεται μέσω NSPersistentStoreDescription. Η αποθήκευση In-Memory δεν αποθηκεύει δεδομένα σε δίσκο και είναι κατάλληλη για δοκιμές μονάδας. Η αποθήκευση Binary είναι μια παρωχημένη μορφή για συμπαγή σύνολα αντικειμένων.
Για ελαφριά μετανάστευση ενεργοποιήστε τα NSMigratePersistentStoresAutomaticallyOption και NSInferMappingModelAutomaticallyOption. Για σύνθετες αλλαγές δημιουργήστε Mapping Model (.xcmappingmodel) μέσω Xcode. Η αποθήκευση CloudKit (NSPersistentCloudKitContainer) υποστηρίζει μεταναστεύσεις αυτόματα κατά τον συγχρονισμό σχήματος με τον διακομιστή iCloud.
SwiftData — είναι ένα νέο πλαίσιο Apple (iOS 17+), χτισμένο πάνω από το Core Data χρησιμοποιώντας Swift Macros και Swift Concurrency. Το SwiftData είναι απλούστερο στη σύνταξη: οι οντότητες περιγράφονται με το μακρο @Model, το περιβάλλον — με @Environment(\.modelContext). Κάτω από το καπό, το SwiftData χρησιμοποιεί την ίδια στοίβα Core Data και SQLite.
Ενεργοποιήστε την παράμετρο εκκίνησης -com.apple.CoreData.SQLDebug 1 — το Core Data θα εμφανίζει όλα τα SQL ερωτήματα και τη διάρκειά τους στην κονσόλα Xcode. Για προφίλ απόδοσης χρησιμοποιήστε το Instruments με το πρότυπο Core Data, που δείχνει τον αριθμό ερωτημάτων fault, φόρτωση αντικειμένων και χρόνο αποθήκευσης περιβάλλοντος.
Σύνοψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης