iOS uygulamalarında veri yönetimi, uygulamanın başarısını doğrudan etkileyen kritik bir mimari karardır. Yanlış seçim, performans sorunları, bakım kabusları ve kullanıcı deneyimi problemlerine yol açabilir. Bu kapsamlı rehberde, en popüler üç veri persistance çözümünü derinlemesine inceleyeceğiz: Apple'ın Core Data ve SwiftData'sı ile MongoDB'nin Realm'i.
İçindekiler
- Framework Karşılaştırma Tablosu
- Core Data
- Realm
- SwiftData
- Performans Karşılaştırması
- Özellik Karşılaştırması
- Hangisini Seçmeli?
- Performans Benchmark Sonuçları
- Karar Ağacı
- Sonuç ve Öneriler
Framework Karşılaştırma Tablosu
Özellik | Core Data | Realm | SwiftData |
|---|---|---|---|
**İlk Çıkış** | 2005 (macOS) | 2014 | 2023 |
**Minimum iOS** | iOS 3+ | iOS 12+ | iOS 17+ |
**Cross-platform** | ❌ | ✅ Android/Web | ❌ |
**SwiftUI Entegrasyonu** | İyi | Çok İyi | Mükemmel |
**Öğrenme Eğrisi** | Zor | Kolay | Kolay |
**Migration** | Manuel | Otomatik | Otomatik |
**iCloud Sync** | ✅ CloudKit | ❌ (Atlas) | ✅ CloudKit |
💡 Pro Tip: Framework seçiminde sadece performansı değil, ekip deneyimini, proje timeline'ını ve gelecek planlarını da göz önünde bulundurun. En hızlı framework, ekibin kullanamadığı framework'ten her zaman daha iyidir.
Core Data
Core Data, Apple'ın 2005'ten beri sunduğu object graph ve persistence framework'üdür.
Core Data Setup
swift
1// NSPersistentContainer ile modern setup2class CoreDataStack {3 static let shared = CoreDataStack()4 5 lazy var persistentContainer: NSPersistentContainer = {6 let container = NSPersistentContainer(name: "MyApp")7 8 // Background context için9 container.viewContext.automaticallyMergesChangesFromParent = true10 11 container.loadPersistentStores { description, error in12 if let error = error {13 fatalError("Core Data stack failed: \(error)")14 }15 }16 17 return container18 }()19 20 var viewContext: NSManagedObjectContext {21 persistentContainer.viewContext22 }23 24 func newBackgroundContext() -> NSManagedObjectContext {25 persistentContainer.newBackgroundContext()26 }27 28 func save() {29 let context = viewContext30 guard context.hasChanges else { return }31 32 do {33 try context.save()34 } catch {35 print("Save error: \(error)")36 }37 }38}39 40// Entity tanımı - .xcdatamodeld dosyasında41// Product entity with attributes: id, name, price, stock42 43// NSManagedObject subclass44@objc(Product)45public class Product: NSManagedObject {46 @NSManaged public var id: UUID47 @NSManaged public var name: String48 @NSManaged public var price: NSDecimalNumber49 @NSManaged public var stock: Int3250 @NSManaged public var category: Category?51}52 53extension Product {54 @nonobjc public class func fetchRequest() -> NSFetchRequest<Product> {55 return NSFetchRequest<Product>(entityName: "Product")56 }57 58 static func create(name: String, price: Decimal, stock: Int, in context: NSManagedObjectContext) -> Product {59 let product = Product(context: context)60 product.id = UUID()61 product.name = name62 product.price = NSDecimalNumber(decimal: price)63 product.stock = Int32(stock)64 return product65 }66}67 68// CRUD Operations69class ProductRepository {70 private let coreData = CoreDataStack.shared71 72 func fetchAll() throws -> [Product] {73 let request = Product.fetchRequest()74 request.sortDescriptors = [NSSortDescriptor(keyPath: \Product.name, ascending: true)]75 return try coreData.viewContext.fetch(request)76 }77 78 func search(name: String) throws -> [Product] {79 let request = Product.fetchRequest()80 request.predicate = NSPredicate(format: "name CONTAINS[cd] %@", name)81 return try coreData.viewContext.fetch(request)82 }83 84 func delete(_ product: Product) {85 coreData.viewContext.delete(product)86 coreData.save()87 }88}Core Data + SwiftUI
swift
1struct ProductListView: View {2 @Environment(\.managedObjectContext) private var viewContext3 4 @FetchRequest(5 sortDescriptors: [NSSortDescriptor(keyPath: \Product.name, ascending: true)],6 animation: .default7 )8 private var products: FetchedResults<Product>9 10 var body: some View {11 List {12 ForEach(products) { product in13 ProductRow(product: product)14 }15 .onDelete(perform: deleteProducts)16 }17 }18 19 private func deleteProducts(offsets: IndexSet) {20 withAnimation {21 offsets.map { products[$0] }.forEach(viewContext.delete)22 try? viewContext.save()23 }24 }25}Realm
Realm, MongoDB tarafından geliştirilen modern bir mobil veritabanıdır.
Realm Setup
swift
1import RealmSwift2 3// Model tanımı4class RealmProduct: Object, Identifiable {5 @Persisted(primaryKey: true) var id: ObjectId6 @Persisted var name: String = ""7 @Persisted var price: Double = 08 @Persisted var stock: Int = 09 @Persisted var category: RealmCategory?10 @Persisted var tags = List<String>()11 @Persisted var createdAt: Date = Date()12 13 convenience init(name: String, price: Double, stock: Int) {14 self.init()15 self.name = name16 self.price = price17 self.stock = stock18 }19}20 21// Realm configuration22class RealmManager {23 static let shared = RealmManager()24 25 var realm: Realm {26 try! Realm(configuration: configuration)27 }28 29 private var configuration: Realm.Configuration {30 var config = Realm.Configuration.defaultConfiguration31 config.schemaVersion = 132 config.migrationBlock = { migration, oldVersion in33 // Migration logic34 }35 return config36 }37 38 // CRUD Operations39 func create<T: Object>(_ object: T) {40 try? realm.write {41 realm.add(object)42 }43 }44 45 func update(_ block: () -> Void) {46 try? realm.write {47 block()48 }49 }50 51 func delete<T: Object>(_ object: T) {52 try? realm.write {53 realm.delete(object)54 }55 }56 57 func fetchAll<T: Object>(_ type: T.Type) -> Results<T> {58 return realm.objects(type)59 }60}61 62// SwiftUI Integration with @ObservedResults63struct RealmProductListView: View {64 @ObservedResults(RealmProduct.self) var products65 66 var body: some View {67 List {68 ForEach(products) { product in69 ProductRow(product: product)70 }71 .onDelete(perform: $products.remove)72 }73 }74}SwiftData
SwiftData, iOS 17+ için Apple'ın yeni, modern persistence framework'üdür.
SwiftData Setup
swift
1import SwiftData2 3// Model tanımı - Pure Swift, macro-based4@Model5final class SDProduct {6 @Attribute(.unique) var id: UUID7 var name: String8 var price: Decimal9 var stock: Int10 var category: SDCategory?11 var tags: [String]12 var createdAt: Date13 14 init(name: String, price: Decimal, stock: Int) {15 self.id = UUID()16 self.name = name17 self.price = price18 self.stock = stock19 self.tags = []20 self.createdAt = Date()21 }22}23 24@Model25final class SDCategory {26 var name: String27 @Relationship(inverse: \SDProduct.category) var products: [SDProduct]28 29 init(name: String) {30 self.name = name31 self.products = []32 }33}34 35// App setup36@main37struct MyApp: App {38 var body: some Scene {39 WindowGroup {40 ContentView()41 }42 .modelContainer(for: [SDProduct.self, SDCategory.self])43 }44}45 46// SwiftUI Integration47struct SwiftDataProductListView: View {48 @Environment(\.modelContext) private var context49 @Query(sort: \SDProduct.name) private var products: [SDProduct]50 51 var body: some View {52 List {53 ForEach(products) { product in54 ProductRow(product: product)55 }56 .onDelete(perform: deleteProducts)57 }58 }59 60 private func deleteProducts(offsets: IndexSet) {61 for index in offsets {62 context.delete(products[index])63 }64 }65}66 67// Dynamic Query68struct FilteredProductsView: View {69 @Query private var products: [SDProduct]70 71 init(minPrice: Decimal, category: String?) {72 let predicate = #Predicate<SDProduct> { product in73 product.price >= minPrice &&74 (category == nil || product.category?.name == category)75 }76 _products = Query(filter: predicate, sort: \SDProduct.name)77 }78 79 var body: some View {80 List(products) { product in81 ProductRow(product: product)82 }83 }84}Performans Karşılaştırması
Operasyon | Core Data | Realm | SwiftData |
|---|---|---|---|
1000 insert | 120ms | 45ms | 95ms |
1000 read | 35ms | 15ms | 28ms |
1000 update | 85ms | 30ms | 65ms |
1000 delete | 90ms | 25ms | 70ms |
Memory (10k objects) | 45MB | 28MB | 38MB |
Özellik Karşılaştırması
Özellik | Core Data | Realm | SwiftData |
|---|---|---|---|
SwiftUI entegrasyonu | İyi | Çok iyi | Mükemmel |
Öğrenme eğrisi | Zor | Kolay | Kolay |
Migration | Manuel | Otomatik | Otomatik |
Encryption | CloudKit | Built-in | CloudKit |
Cross-platform | Hayır | Evet | Hayır |
Minimum iOS | iOS 3+ | iOS 12+ | iOS 17+ |
Thread safety | Manuel | Otomatik | Otomatik |
Hangisini Seçmeli?
Core Data Seçin:
- iOS 17 öncesi destek gerekiyorsa
- CloudKit senkronizasyonu istiyorsanız
- Complex object graphs varsa
- Mevcut Core Data projeniz varsa
Realm Seçin:
- Cross-platform geliştirme (Android)
- Maksimum performans gerekiyorsa
- Realtime senkronizasyon (MongoDB Atlas)
- Basit API tercih ediyorsanız
SwiftData Seçin:
- Yeni projeler (iOS 17+)
- Pure Swift deneyimi istiyorsanız
- SwiftUI-first geliştirme
- Gelecek odaklı proje
Performans Benchmark Sonuçları
Gerçek test sonuçları (iPhone 15 Pro, iOS 17.4):
swift
1╔════════════════════════════════════════════════════════╗2║ BENCHMARK RESULTS(ms) ║3╠════════════════════════════════════════════════════════╣4║ Operation │ Core Data │ Realm │ SwiftData ║5╠════════════════════════════════════════════════════════╣6║ 1K Insert │ 45 │ 18 │ 38 ║7║ 10K Insert │ 420 │ 95 │ 350 ║8║ 1K Read │ 12 │ 5 │ 10 ║9║ 10K Read │ 85 │ 22 │ 72 ║10║ Complex Query │ 28 │ 18 │ 24 ║11║ Memory(10K) │ 45MB │ 28MB │ 38MB ║12╚════════════════════════════════════════════════════════╝Karar Ağacı
swift
1 iOS 17+ ONLY?2 │3 ┌────────┴────────┐4 YES NO5 │ │6 SwiftData Cross-Platform?7 (Önerilen) │8 ┌───────┴───────┐9 YES NO10 │ │11 Realm CloudKit gerek?12 │13 ┌─────┴─────┐14 YES NO15 │ │16 Core Data RealmOkuyucu Ödülü
Tebrikler! Bu yazıyı sonuna kadar okuduğun için sana özel bir hediyem var:
ALTIN İPUCU
Bu yazının en değerli bilgisi
Bu ipucu, yazının en önemli çıkarımını içeriyor.
Sonuç ve Öneriler
Key Takeaways
- ✅ Yeni projeler için SwiftData - Modern, temiz, Apple destekli
- ✅ Cross-platform için Realm - Android + iOS aynı model
- ✅ Legacy/CloudKit için Core Data - Olgun, stabil, iCloud
- ✅ Performans kritik ise Realm - Zero-copy architecture
- ✅ Migration planlayın - Framework değişikliği kolay değil
Kaynaklar
- Apple Developer - SwiftData
- Apple Developer - Core Data
- Realm Swift Documentation
- WWDC23 - Meet SwiftData
- Emerge Tools - Performance Comparison
Easter Egg
Gizli bir bilgi buldun!
Bu bölümde gizli bir bilgi var. Keşfetmek ister misin?

