Core Data, iOS ve macOS uygulamalarında nesne grafiğini yönetmek için Apple framework'üdür. Veri kalıcılığı, değişiklik takibi, işlemleri geri alma ve NSFetchedResultsController aracılığıyla UI entegrasyonu sağlar. Apple Developer belgelerine (2025) göre Core Data bir veritabanı değildir — varsayılan olarak SQLite'ı kalıcı depo olarak kullanan bir nesne modelleme katmanıdır.
Önemli Noktalar
Core Data, Apple'ın Cocoa Touch SDK'sının bir parçası olan bir nesne grafiği yönetimi ve kalıcılık framework'üdür. Verilerle çalışmak için nesne yönelimli bir arayüz sağlar: geliştirici varlıklar, nitelikler ve ilişkilerle çalışırken, Core Data bu nesneleri perde arkasında ilişkisel veritabanı kayıtlarına dönüştürür.
Core Data, Mac OS X 10.4 Tiger (2005)'da macOS için tanıtıldı ve iOS 3.0 (2009)'a taşındı. 20 yılı aşkın sürede framework, SQLite üzerinde basit bir soyutlama katmanından NSPersistentCloudKitContainer ile bulut senkronizasyonu, otomatik bağlam yönetimi ile çoklu iş parçacığı ve Swift Concurrency ile asenkron yükleme desteğine sahip tam özellikli bir yığına dönüştü.
Slack Community (2025) iOS geliştirici anketine göre, Core Data ticari iOS uygulamalarının %68'inde yerel veri depolama için kullanılmaktadır. Karmaşıklığı ve katmanlı mimarisi nedeniyle eleştirilmesine rağmen, sistemle sıkı entegrasyonu, sıfır maliyeti (SDK'ya dahil) ve iCloud senkronizasyon desteği sayesinde framework, Apple uygulamaları için standart olmaya devam etmektedir.
Yaygın bir yanılgı Core Data'yı bir veritabanı olarak düşünmektir. Framework doğrudan SQL sorguları çalıştırmaz ve bir DBMS değildir. Core Data, kalıcılık için SQLite, Binary veya In-Memory depolarını kullanabilen bir nesne grafiği yönetim katmanıdır. Analoji: Core Data, Apple ekosistemi için Hibernate veya Entity Framework gibidir ve altındaki SQLite, Hibernate'in altındaki MySQL gibidir.
Core Data yığını dört birbirine bağlı bileşenden oluşur: NSManagedObjectModel (veri şeması), NSPersistentStoreCoordinator (depo koordinatörü), NSManagedObjectContext (çalışma bağlamı) ve NSPersistentContainer (iOS 10'dan itibaren üçünü birleştiren birleşik bir kapsayıcı). NSPersistentContainer yığın oluşturmayı ve yapılandırmayı otomatikleştirir.
Her bileşen kesin olarak tanımlanmış bir işlevi yerine getirir. NSManagedObjectModel varlık açıklamalarını içeren .xcdatamodeld dosyasını yükler. NSPersistentStoreCoordinator modeli fiziksel depo dosyasına (SQLite) bağlar. NSManagedObjectContext nesnelerle çalışmak için geçici bir alan sağlar. Kapsayıcı her şeyi tek bir başlatma çağrısında birleştirir.
SQLite (NSSQLiteStoreType) çoğu uygulamada kullanılan standart depodur. Veriler ACID işlem desteğiyle tek bir .sqlite dosyasına kaydedilir. Binary (NSBinaryStoreType) küçük veri kümeleri (birkaç yüz nesneye kadar) için ikili biçim depodur. In-Memory (NSInMemoryStoreType) diskte kalıcılık olmadan RAM'de geçici depodur, testler ve önbellekleme için kullanılır.
| Depo Türü | Biçim | Performans | Ne Zaman Kullanılır |
|---|---|---|---|
| SQLite | .sqlite | Yüksek | Üretim için standart seçim |
| Binary | .binary | Orta | Küçük veri kümeleri |
| In-Memory | RAM | Maksimum | Testler, önbellek, geçici veriler |
| CloudKit | iCloud | Ağa bağlı | Cihazlar arası senkronizasyon |
Depo türü, NSPersistentStoreDescription başlatılırken tek bir satırla ayarlanır. Geliştirici, nesne işleme kodunu değiştirmeden birim testleri için SQLite'dan In-Memory'e veya iCloud senkronizasyonu için CloudKit'e geçebilir — Core Data, birleşik bağlam API'si aracılığıyla depo türleri arasındaki farklılıkları soyutlar.
NSManagedObject tüm Core Data nesneleri için temel sınıftır ve tek bir varlık kaydını temsil eder. Her yönetilen nesnenin benzersiz bir NSManagedObjectID'si (kalıcı tanımlayıcı) vardır, bir bağlama bağlıdır ve değişikliklerini KVO (Key-Value Observing) aracılığıyla izler. Geliştiriciler, türü belirtilmiş varlık özelliklerini tanımlamak için NSManagedObject alt sınıfları oluşturur.
NSManagedObjectContext tüm nesne işlemleri için bir çalışma alanı sağlayan Core Data'nın merkezi bileşenidir. Bağlam, eklemeleri, silmeleri ve değişiklikleri izler (değişiklik takibi), undoManager aracılığıyla işlemleri geri almayı destekler ve kaydetme bildirimleri aldığında diğer bağlamlardaki değişiklikleri otomatik olarak birleştirir.
Özel kuyruk kuralı: NSManagedObjectContext, .privateQueueConcurrencyType veya .mainQueueConcurrencyType ile oluşturulur. Ana bağlam, ana UI iş parçacığına bağlıyken, özel bağlamlar arka plan kuyruklarında çalışır. Her bağlam yalnızca kendi kuyruğunda kullanılmalıdır — başka bir iş parçacığından yönetilen bir nesneye erişmek çökmeye neden olur. parentContext, asenkron yazmalar için bir bağlam hiyerarşisi düzenlemeye olanak tanır.
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 otomatik olarak viewContext (ana kuyruk) oluşturur ve arka plan işlemleri için newBackgroundContext() sağlar. automaticallyMergesChangesFromParent = true olarak ayarlamak, viewContext'in arka plan bağlamları kaydettiğinde değişiklikleri otomatik olarak almasını sağlayarak, manuel veri yeniden getirme olmadan UI'yi günceller.
NSPersistentStoreCoordinator fiziksel veri deposunu yönetir: dosyayı açar, modele dayalı SQLite tabloları oluşturur ve şema değiştiğinde geçişler gerçekleştirir. NSSQLiteStoreType ile NSPersistentStoreDescription başlatılırken Core Data, .xcdatamodeld modeliyle eşleşen bir şemaya sahip bir SQLite dosyası oluşturur.
Core Data, SELECT/INSERT/UPDATE aracılığıyla standart SQL sorguları kullanmaz. Bunun yerine, modele ve NSFetchRequest aracılığıyla yapılan sorgulara dayalı olarak dahili SQL komutları oluşturur. Geliştirici, sorgu performansını hata ayıklamak için -com.apple.CoreData.SQLDebug 1 başlatma argümanıyla SQL günlüğünü etkinleştirebilir.
Hafif Geçiş (Lightweight Migration), yeni nitelikler eklerken, optional/required bayraklarını değiştirirken veya renamingID ile yeniden adlandırırken SQLite şemasını otomatik olarak güncelleme işlemidir. Varlıkları birleştirme veya bölme gibi köklü şema değişiklikleri için ağır geçiş gerekir ve özel bir NSMigrationManager aracılığıyla gerçekleştirilir.
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 ve NSInferMappingModelAutomaticallyOption aracılığıyla otomatik geçiş ayarı, Core Data'nın modelin yeni bir sürümünde nitelikler veya varlıklar eklendiğinde SQLite dosyasını bağımsız olarak güncellemesine olanak tanır. Geçiş mümkün değilse, depo koordinatörü neden açıklamasıyla bir hata fırlatır — geliştirici daha sonra NSMigrationManager aracılığıyla özel bir geçiş uygulamalıdır.
NSFetchRequest Core Data'dan nesneleri getirmek için birincil araçtır. Bir istek, varlık adını, yüklemi (filtre), sıralama tanımlayıcılarını, limiti ve ofseti içerir. Sonuç, NSManagedObject veya türü belirtilmiş alt sınıflardan oluşan bir dizi olarak döndürülür. NSPredicate, AND, OR, IN, LIKE ve alt sorgularla karmaşık koşulları destekler.
NSBatchDeleteRequest her nesneyi belleğe yüklemeden toplu olarak silmenin verimli bir yoludur. İstek SQLite düzeyinde yürütülür, yönetilen nesne bağlamını atlar ve yalnızca tamamlandıktan sonra bağlamı günceller. Güncelleme (NSBatchUpdateRequest) ve ekleme (NSBatchInsertRequest) için benzer toplu istekler mevcuttur.
CRUD (Oluşturma, Okuma, Güncelleme, Silme) Core Data'da bağlam yöntemleri aracılığıyla gerçekleştirilir: insert, fetch, save ve delete. Tüm değişiklikler context.save() çağrılana kadar geçicidir — bu yöntem değişiklikleri kalıcı SQLite deposuna kaydeder. Kaydetme hatasında bağlam, yeniden deneme için değiştirilmiş durumunda kalır.
let context = container.viewContext
// Oluştur
let user = User(context: context)
user.id = 42
user.name = "Alice"
// Oku
let request = User.fetchRequest()
request.predicate = NSPredicate(format: "name CONTAINS %@", "Ali")
request.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]
let results = try context.fetch(request)
// Güncelle
results.first?.name = "Alice Updated"
// Sil
if let first = results.first { context.delete(first) }
// Kaydet
try context.save()
Bağlamı kaydetme (context.save()) kritik bir işlemdir. Save çağrılmazsa, tüm değişiklikler yalnızca bellekte kalır. Bağlam, kaydetmeden önce kontrol edilebilen hasChanges durumunu izler. Arka plan işlemleri için kendi kaydetmesiyle newBackgroundContext kullanın ve UI için zamanlayıcıda veya uygulama arka plana geçtiğinde otomatik kaydetmeyle viewContext kullanın.
Birinci uygulama — kullanıcı cihazları arasında iCloud aracılığıyla veri senkronizasyonu için NSPersistentCloudKitContainer kullanın. Bulut senkronizasyonu, kalıcı depo açıklamasına CloudKit seçeneği eklenerek etkinleştirilir. Core Data, senkronizasyon çakışmalarını otomatik olarak yönetir ve diğer cihazlardaki değişiklikleri birleştirir.
İkinci uygulama — büyük tablolarda yüklem olmadan fetchRequest kullanmaktan kaçının. Her koşulsuz getirme, tüm varlık nesnelerini belleğe yükleyerek yüksek RAM tüketimine ve UI yavaşlamasına neden olur. Her zaman yüklemler ve limitler kullanın. Sayfalama için NSFetchRequest'te fetchLimit ve fetchOffset kullanın.
Üçüncü uygulama — çoklu iş parçacığı erişiminde çakışmaları çözmek için mergePolicy'yi yapılandırın. NSMergeByPropertyObjectTrumpMergePolicy, en son kaydedilen bağlamdan çakışan özellikleri günceller. NSRollbackMergePolicy, çakışma durumunda geçerli bağlam değişikliklerini atar. Politika seçimi uygulamanın iş mantığına bağlıdır.
Dördüncü uygulama — tablo ve koleksiyon entegrasyonu için NSFetchedResultsController kullanın. NSManagedObjectContextDidSave bildirimlerine otomatik olarak abone olur, yalnızca gerekli nesneleri yükler (faulting) ve UITableView animasyonu için uygun indeks yollarıyla ekleme, silme ve taşıma işlemleri hakkında temsilciyi bilgilendirir.
Faulting Core Data'nın tembel yükleme mekanizmasıdır. Bir getirme isteği tarafından döndürülen yönetilen nesne, fault durumundadır — öznitelikleri tam olarak yüklenmemiştir, yalnızca tanımlayıcı yüklenmiştir. Tam yükleme (fire fault), herhangi bir özniteliğe ilk erişimde gerçekleşir. İlişki ön getirme (setRelationshipKeyPathsForPrefetching) ilgili nesneleri önceden yükleyerek N+1 sorgularını önler.
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'nın tüm tabloyu bir kerede yüklemeden verileri 20 nesnelik gruplar halinde yüklemesini (ekran görüntülemesi için) sağlar. returnsObjectsAsFaults = false bayrağı, tüm kullanıcı özniteliklerinin hemen yüklenmesini sağlar ve bu doğrudan görüntüleme için kullanışlıdır. “posts” ilişkisinin ön getirmesi, gönderilere erişirken her kullanıcı için ayrı sorguları önler.
Sıkça Sorulan Sorular
Hayır, Core Data bir nesne grafiği yönetim framework'üdür. Nesnelerle çalışmak, değişiklikleri izlemek ve kalıcı hale getirmek için bir API sağlar. Core Data'nın perde arkasındaki veritabanı (varsayılan olarak SQLite) framework'ün kendisiyle karıştırılmamalıdır. Core Data bir ORM'dir, DBMS değildir.
Evet, Core Data üç depo türünü destekler: SQLite, Binary ve In-Memory. Depo türü NSPersistentStoreDescription aracılığıyla ayarlanır. In-Memory depo, verileri diske kaydetmez ve birim testleri için uygundur. Binary depo, kompakt nesne kümeleri için eski bir biçimdir.
Hafif geçiş için NSMigratePersistentStoresAutomaticallyOption ve NSInferMappingModelAutomaticallyOption'ı etkinleştirin. Karmaşık değişiklikler için Xcode aracılığıyla bir Mapping Model (.xcmappingmodel) oluşturun. CloudKit deposu (NSPersistentCloudKitContainer), şemayı iCloud sunucusuyla senkronize ederken geçişleri otomatik olarak destekler.
SwiftData, Swift Macros ve Swift Concurrency kullanarak Core Data üzerine inşa edilmiş yeni bir Apple framework'üdür (iOS 17+). SwiftData daha basit bir sözdizimine sahiptir: varlıklar @Model makrosuyla, bağlam @Environment(\.modelContext) ile tanımlanır. Perde arkasında SwiftData aynı Core Data yığınını ve SQLite'ı kullanır.
Başlatma argümanı -com.apple.CoreData.SQLDebug 1'i etkinleştirin — Core Data tüm SQL sorgularını ve sürelerini Xcode konsolunda görüntüleyecektir. Profil oluşturma için Core Data şablonuyla Instruments'ı kullanın; bu, fault isteklerinin sayısını, nesne yükleme sürelerini ve bağlam kaydetme süresini gösterir.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun