Core Data — فریمورک اپل برای مدیریت گراف اشیاء در برنامههای iOS و macOS. این فریمورک ذخیرهسازی دادهها، ردیابی تغییرات، لغو عملیات و ادغام با UI را از طریق NSFetchedResultsController فراهم میکند. بر اساس مستندات Apple Developer (2025)، Core Data یک پایگاه داده نیست — این یک لایه مدلسازی شیء است که به طور پیشفرض از SQLite به عنوان ذخیرهگاه دائمی برای بارگیری و ذخیره اشیاء استفاده میکند.
نکات اصلی
Core Data — فریمورک مدیریت گراف اشیاء و ماندگاری دادهها است که بخشی از Cocoa Touch SDK اپل میباشد. این فریمورک رابط شیءگرا برای کار با دادهها فراهم میکند: توسعهدهنده با موجودیتها (Entity)، ویژگیها و روابط (Relationship) کار میکند و Core Data این اشیاء را به رکوردهای پایگاه داده رابطهای در پشت صحنه تبدیل میکند.
Core Data در Mac OS X 10.4 Tiger (2005) برای macOS معرفی شد و به iOS 3.0 (2009) منتقل گردید. در طول بیش از 20 سال، این فریمورک از یک لایه انتزاعی ساده بر روی SQLite به یک پشته کامل با پشتیبانی از همگامسازی ابری از طریق NSPersistentCloudKitContainer، چندنخی از طریق مدیریت خودکار زمینهها و بارگیری ناهمگام از طریق Swift Concurrency تکامل یافته است.
بر اساس نظرسنجی توسعهدهندگان iOS از Slack Community (2025)، Core Data در 68% از برنامههای تجاری iOS برای ذخیرهسازی محلی دادهها استفاده میشود. علیرغم انتقاد از پیچیدگی و چندلایه بودن، این فریمورک به دلیل ادغام نزدیک با سیستم، هزینه صفر (تعبیه شده در SDK) و پشتیبانی از همگامسازی iCloud استاندارد برنامههای اپل باقی مانده است.
یک باور غلط رایج — این است که Core Data را یک پایگاه داده در نظر بگیرند. این فریمورک مستقیماً کوئریهای SQL را اجرا نمیکند و یک DBMS نیست. Core Data یک لایه مدیریت اشیاء (object graph management) است که میتواند از SQLite، Binary یا In-Memory برای ماندگاری استفاده کند. تشبیه: Core Data مانند ORMهایی مثل Hibernate یا Entity Framework اما برای اکوسیستم اپل است و 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) — ذخیرهگاه موقت در حافظه رم بدون ذخیره بر روی دیسک، برای تستها و کش استفاده میشود.
| نوع ذخیرهگاه | فرمت | عملکرد | زمان استفاده |
|---|---|---|---|
| SQLite | .sqlite | بالا | انتخاب استاندارد برای production |
| Binary | .binary | متوسط | مجموعه دادههای کوچک |
| In-Memory | RAM | حداکثر | تستها، کش، دادههای موقت |
| CloudKit | iCloud | وابسته به شبکه | همگامسازی بین دستگاهها |
انتخاب ذخیرهگاه با یک خط در هنگام مقداردهی NSPersistentStoreDescription تعیین میشود. توسعهدهنده میتواند ذخیرهگاه را از SQLite به In-Memory برای تستهای واحد یا به CloudKit برای همگامسازی iCloud بدون تغییر کد کار با اشیاء تغییر دهد — Core Data تفاوت بین انواع ذخیرهگاهها را با API یکپارچه زمینه انتزاع میکند.
NSManagedObject — کلاس پایه برای تمام اشیاء Core Data که یک رکورد موجودیت را نشان میدهد. هر managed object دارای NSManagedObjectID منحصربهفرد (شناسه دائمی) است، به یک زمینه متصل است و تغییرات خود را از طریق KVO (Key-Value Observing) ردیابی میکند. توسعهدهنده زیرکلاسهای NSManagedObject را برای تعریف ویژگیهای تایپشده موجودیت ایجاد میکند.
NSManagedObjectContext — جزء مرکزی Core Data که یک فضای کاری برای تمام عملیات روی اشیاء فراهم میکند. زمینه اضافهکردن، حذف و تغییر اشیاء (change tracking) را ردیابی میکند، از لغو عملیات از طریق undoManager پشتیبانی میکند و پس از دریافت اعلانهای ذخیره، تغییرات را از سایر زمینهها به طور خودکار ادغام میکند.
قانون صفهای خصوصی: NSManagedObjectContext با نوع .privateQueueConcurrencyType یا .mainQueueConcurrencyType ایجاد میشود. زمینه اصلی به نخ اصلی UI متصل است و زمینههای خصوصی در صفهای پسزمینه اجرا میشوند. هر زمینه فقط باید در صف خود استفاده شود — دسترسی به managed object از یک نخ دیگر باعث crash میشود. 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 را به طور مستقل بهروزرسانی کند. اگر مهاجرت غیرممکن باشد، store coordinator خطایی با شرح دلیل ایجاد میکند — توسعهدهنده باید مهاجرت سفارشی را از طریق 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 با ذخیره خودکار بر اساس تایمر یا هنگام رفتن برنامه به پسزمینه استفاده کنید.
روش اول — برای همگامسازی دادهها بین دستگاههای کاربر از طریق iCloud از NSPersistentCloudKitContainer استفاده کنید. همگامسازی ابری با افزودن گزینه CloudKit به توضیحات ذخیرهگاه فعال میشود. Core Data به طور خودکار تعارضات را در هنگام همگامسازی مدیریت میکند و تغییرات را از دستگاههای دیگر ادغام میکند.
روش دوم — از fetchRequest بدون محمول در جدولهای بزرگ خودداری کنید. هر واکشی بدون شرط تمام اشیاء موجودیت را در حافظه بارگیری میکند که منجر به مصرف بالای RAM و کندی UI میشود. همیشه از محمولها و محدودیتها استفاده کنید. برای صفحهبندی از fetchLimit و fetchOffset در NSFetchRequest استفاده کنید.
روش سوم — mergePolicy را برای حل تعارضات در دسترسی چندنخی پیکربندی کنید. NSMergeByPropertyObjectTrumpMergePolicy ویژگیهای متعارض را از آخرین زمینه ذخیرهشده بهروزرسانی میکند. NSRollbackMergePolicy تغییرات زمینه فعلی را در صورت تعارض لغو میکند. انتخاب خطمشی به منطق تجاری برنامه بستگی دارد.
روش چهارم — برای ادغام با جداول و مجموعهها از NSFetchedResultsController استفاده کنید. این کلاس به طور خودکار در اعلانهای NSManagedObjectContextDidSave مشترک میشود، فقط اشیاء ضروری را بارگیری میکند (faulting) و نماینده را در مورد درجها، حذفها و جابهجاییها با مسیرهای شاخص مربوطه برای انیمیشن UITableView مطلع میکند.
Faulting — مکانیزم بارگیری تنبل اشیاء Core Data. Managed object بازگرداندهشده توسط درخواست واکشی در حالت 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 است، نه یک DBMS.
بله، Core Data از سه نوع ذخیرهگاه پشتیبانی میکند: SQLite، Binary و In-Memory. انتخاب ذخیرهگاه از طریق NSPersistentStoreDescription تعیین میشود. ذخیرهگاه In-Memory دادهها را روی دیسک ذخیره نمیکند و برای تستهای واحد مناسب است. ذخیرهگاه Binary یک فرمت قدیمی برای مجموعههای فشرده از اشیاء است.
برای مهاجرت سبک، NSMigratePersistentStoresAutomaticallyOption و NSInferMappingModelAutomaticallyOption را فعال کنید. برای تغییرات پیچیده، Mapping Model (.xcmappingmodel) را از طریق Xcode ایجاد کنید. ذخیرهگاه CloudKit (NSPersistentCloudKitContainer) مهاجرتها را هنگام همگامسازی طرح با سرور iCloud به طور خودکار پشتیبانی میکند.
SwiftData — فریمورک جدید اپل (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 از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید