Core Data یک فریمورک مدیریت داده از اپل است که نگاشت شیء-رابطهای را برای iOS، macOS، tvOS و watchOS فراهم میکند. این فریمورک ذخیرهسازی، بازیابی و فیلتر کردن اشیاء در برنامه را خودکار میکند و بر روی SQLite، XML یا ذخیرهسازی باینری کار میکند. بر اساس Apple Core Data Documentation، این فریمورک از مفاهیم Managed Object Context و NSPersistentContainer برای مدیریت پشته ماندگاری استفاده میکند.
نکات اصلی
Core Data — یک فریمورک مدیریت گراف اشیاء و ماندگاری است که بخشی از Cocoa Touch میباشد. برخلاف تصور رایج، Core Data یک پایگاه داده نیست، بلکه لایهای برای مدیریت اشیاء است که میتواند از SQLite به عنوان یکی از ذخیرهگاهها استفاده کند. وظیفه اصلی Core Data ردیابی تغییرات اشیاء، مدیریت چرخه حیات آنها و همگامسازی وضعیت با دیسک است.
این فریمورک گراف اشیاء را فراهم میکند، جایی که هر Managed Object توسط زمینه برای تغییرات ردیابی میشود. هنگام ذخیره زمینه، همه اشیاء تغییر یافته، اضافه شده و حذف شده در یک تراکنش در ذخیرهگاه دائمی ثبت میشوند. این کار برنامهنویس را از نوشتن پرسوجوهای SQL و مدیریت دستی تراکنشها بینیاز میکند.
بر اساس آمار Swift Developer Survey (2025)، Core Data در ۵۲٪ از برنامههای iOS که با دادههای محلی کار میکنند استفاده میشود. با وجود ظهور جایگزینهای مدرن (SwiftData، Realm)، Core Data به دلیل بلوغ و یکپارچگی عمیق با سیستم، فریمورک اصلی در پروژههای موجود اپل باقی مانده است.
از Core Data برای پروژههایی با مدل داده با پیچیدگی متوسط که نیاز به روابط بین اشیاء، بازگردانی تغییرات و کش خودکار از طریق مکانیزم faulting دارند استفاده کنید.
معماری Core Data حول مفهوم Managed Object Context ساخته شده است — فضای کاری که تمام تغییرات اشیاء را ردیابی میکند. زمینه از بازگردانی (undo/redo) از طریق NSUndoManager داخلی پشتیبانی میکند که امکان پیادهسازی پیشنویسها و لغو عملیات را بدون ذخیره دستی snapshotهای وضعیت فراهم میکند. هنگام فراخوانی save()، زمینه تمام تغییرات را در یک تراکنش در ذخیرهگاه دائمی ثبت میکند و اتمی بودن و سازگاری دادهها را تضمین میکند.
مدل داده Core Data در فایل .xcdatamodeld — ویرایشگر بصری Xcode تعریف میشود، جایی که همه Entityها، ویژگیها و روابط آنها توصیف میشوند. هنگام کامپایل، مدل به .momd سریال میشود و از طریق NSManagedObjectModel بارگذاری میشود.
Entity — توصیف نوع داده، مشابه جدول در SQL است. هر Entity شامل مجموعهای از Attributes — فیلدهای نامگذاری شده با نوع داده (String، Integer، Date، Boolean، Data) میباشد. برخلاف Room، Core Data نیاز به انتخاب صریح نوع برای هر ویژگی از طریق ویرایشگر مدل دارد.
Relationship — رابطه بین Entityها، مشابه کلید خارجی در SQL است. Core Data از همه انواع روابط پشتیبانی میکند: یک-به-یک، یک-به-چند و چند-به-چند. برای هر رابطه Delete Rule (Cascade، Nullify، Deny) — رفتار هنگام حذف شیء مرتبط پیکربندی میشود.
| Delete Rule | رفتار هنگام حذف | مثال کاربرد |
|---|---|---|
| Cascade | همه اشیاء مرتبط را حذف میکند | حذف سفارش همراه با آیتمها |
| Nullify | رابطه معکوس را صفر میکند | حذف نویسنده بدون حذف کتابها |
| Deny | اگر اشیاء مرتبط وجود داشته باشند حذف را مسدود میکند | جلوگیری از حذف دسته با محصولات |
انتخاب Delete Rule برای یکپارچگی دادهها حیاتی است: Cascade بدون بررسی میتواند یک سوم پایگاه داده را حذف کند و Deny میتواند عملیات را با خطای نامفهوم مسدود کند. در کد تولیدی، Nullify با پردازش دستی رکوردهای یتیم توصیه میشود.
در ویرایشگر مدل Xcode، برنامهنویس میتواند نه تنها Entity و ویژگیها، بلکه constraints (محدودیتهای یکتایی)، ایندکسها برای سرعت بخشیدن به پرسوجوها و default values برای ویژگیها را تنظیم کند. همه تغییرات مدل به فایل .momd کامپایل میشوند که هنگام راهاندازی NSPersistentContainer بارگذاری میشود. نسخهبندی مدل (Model Versioning) امکان نگهداری چندین نسخه از طرح و انجام مهاجرت بین آنها را فراهم میکند.
NSPersistentContainer — یک شیء یکپارچه است که پشته Core Data را از iOS 10 و macOS 10.12 مدیریت میکند. این شیء NSManagedObjectModel، NSPersistentStoreCoordinator و NSManagedObjectContext را کپسوله میکند و بارگذاری مدل و پیکربندی ذخیرهگاه را خودکار میکند. برای نسخههای قدیمیتر، پشته به صورت دستی ساخته میشد، اما اکنون این کار توصیه نمیشود.
let container = NSPersistentContainer(name: "DataModel")
container.loadPersistentStores { _, error in
if let error { fatalError("Core Data load failed: \(error)") }
}
let context = container.viewContext
viewContext — زمینه اصلی متصل به نخ اصلی است. همه خواندنها و بهروزرسانیهای UI از طریق آن انجام میشوند. برای عملکرد بهتر، نوشتن دادهها در زمینه فرزند با صف خصوصی و همگامسازی بعدی توصیه میشود.
هماهنگکننده NSPersistentStoreCoordinator مدل را با ذخیرهگاه فیزیکی روی دیسک متصل میکند. Core Data از چندین نوع ذخیرهگاه پشتیبانی میکند: SQLite (توصیه شده)، Binary و In-Memory. ذخیرهگاه SQLite از مهاجرتها، پشتیبانگیری افزایشی و مقاومت در برابر خرابیها در طول فرآیند نوشتن پشتیبانی میکند.
NSFetchRequest — شیءای است که پرسوجو به ذخیرهگاه Core Data را توصیف میکند. این شیء شامل نام Entity، محمول فیلتر کردن، مرتبسازی و تنظیمات بازیابی است. پرسوجو از طریق context.fetch() اجرا میشود که آرایهای از NSManagedObject را برمیگرداند.
let request = NSFetchRequest<User>(entityName: "User")
request.predicate = NSPredicate(format: "age >= %d", 18)
request.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]
request.fetchLimit = 50
let results = try context.fetch(request)
NSPredicate از شرایط پیچیده پشتیبانی میکند: LIKE، IN، BETWEEN، CONTAINS[c] (بدون حساسیت به حروف بزرگ و کوچک)، SUBQUERY برای پرسوجوهای تو در تو روی Entityهای مرتبط. Core Data همچنین از NSFetchedResultsController پشتیبانی میکند — کلاسی برای بارگذاری واکنشی دادهها در UITableView که به طور خودکار تغییرات را ردیابی میکند و جدول را با بخشهای متحرک بهروز میکند.
کار با Core Data در برنامه چندنخی نیاز به رعایت دقیق قوانین دارد: NSManagedObject را نمیتوان مستقیماً بین نخها منتقل کرد. هر نخ (یا صف) باید از زمینه خود استفاده کند. رویکرد اصلی — ایجاد NSManagedObjectContext فرزند با صف خصوصی (NSPrivateQueueConcurrencyType) برای نوشتن و viewContext برای خواندن است.
زمینه فرزند در والد ذخیره میشود و سپس والد — در ذخیرهگاه روی دیسک. این تضمین میکند که تغییرات نخ اصلی را مسدود نمیکنند و UI همیشه وضعیت سازگار را از طریق mergeChanges یا بهروزرسانی خودکار viewContext هنگام ذخیره میبیند.
Core Data از faulting استفاده میکند — مکانیزم بارگذاری تأخیری اشیاء مرتبط. هنگام بازیابی User بدون درخواست addresses آن، Addressهای مرتبط تا زمانی که از طریق نماد نقطهای به آنها دسترسی پیدا نشود بارگذاری نمیشوند. Faulting حافظه را ذخیره میکند و بارگذاری را تسریع میکند، اما میتواند باعث دسترسیهای غیرمنتظره به دیسک در نخ اصلی شود اگر دسترسی در زمینههای پسزمینه کنترل نشود.
برای چندنخی کارآمد از NSBatchInsertRequest و NSBatchDeleteRequest برای درج و حذف انبوه بدون بارگذاری اشیاء در حافظه استفاده کنید — این برای همگامسازی دادهها با سرور حیاتی است.
عملیات Batch مستقیماً در سطح NSPersistentStoreCoordinator اجرا میشوند و از زمینه و گراف اشیاء عبور میکنند. این امکان را فراهم میکند که ۱۰٬۰۰۰ رکورد در چند میلیثانیه بدون ایجاد ۱۰٬۰۰۰ نمونه NSManagedObject در حافظه درج شود. پس از اجرای پرسوجوی batch، زمینه باید از طریق mergeChangesFromContextDidSaveNotification بهروزرسانی شود تا UI دادههای جدید را منعکس کند. اپل عملیات batch را برای بارگذاری اولیه دادهها و همگامسازی شبانه با سرور توصیه میکند.
برای ردیابی تغییرات در Core Data از NSPersistentHistoryTracking استفاده میشود — مکانیزمی که هر تراکنش (درج، بهروزرسانی، حذف) را در یک تاریخچه جداگانه ثبت میکند. فعالسازی history tracking امکان همگامسازی دادهها را بین فرآیندها و برنامههای مختلف که با یک فایل SQLite کار میکنند فراهم میکند، مثلاً بین برنامه اصلی و Notification Service Extension. فعالسازی از طریق NSPersistentStoreDescription با پرچم persistentHistoryTrackingKey و خواندن از طریق NSPersistentHistoryChangeRequest با فیلتر بر اساس تاریخ و نوع تراکنش انجام میشود.
برای دیباگ و پروفایل عملکرد Core Data از ابزار Core Data Profiler از مجموعه Instruments در Xcode روی macOS استفاده میشود. این ابزار تمام عملیات بازیابی، درج، حذف و ذخیره را با مدت زمان هر عملیات و تعداد اشیاء بارگذاری شده در جداول و نمودارهای خط زمانی نشان میدهد. برنامهنویس میتواند بخشهای مشکلدار را شناسایی کند: بازیابیهای متعدد همان پرسوجو (عدم کش)، نشت اشیاء fault هنگام اسکرول جدول یا مسدود شدن نخ اصلی به دلیل بارگذاری همزمان موجودیتهای مرتبط. توصیه میشود پروفایلینگ روی دستگاه واقعی انجام شود نه روی شبیهساز، زیرا عملکرد شبیهساز رفتار واقعی برنامه را در iPhone یا iPad منعکس نمیکند.
سوالات متداول
Core Data — یک پایگاه داده نیست، بلکه لایه مدیریت اشیاء است که میتواند از SQLite به عنوان ذخیرهگاه استفاده کند. برخلاف SQLite مستقیم، Core Data تغییرات اشیاء را ردیابی میکند، بازگردانیها را مدیریت میکند و گراف اشیاء با faulting و کش ارائه میدهد. SQLite کنترل بیشتری روی پرسوجوها میدهد، اما نیاز به نوشتن SQL و مدیریت دستی تراکنشها دارد.
Core Data از مهاجرت سبک (Lightweight Migration) برای تغییرات غیرتخریبی پشتیبانی میکند: اضافه کردن ویژگی، تغییر نام، تنظیم مقدار پیشفرض. برای تغییرات پیچیده، Mapping Model ایجاد میشود. مهاجرت سبک با پرچم shouldMigrateAutomatically در NSPersistentStoreDescription فعال میشود.
بله، Core Data با SwiftUI از طریق wrapper @FetchRequest برای پرسوجوها و @ObservedObject برای اشتراک تغییرات یکپارچه میشود. SwiftUI به طور خودکار View را هنگام تغییر ManagedObject بهروز میکند که Core Data و SwiftUI را به پشتهای سازگار برای مدیریت وضعیت تبدیل میکند.
Fault — یک placeholder سبک در گراف Core Data است که دادههای شیء مرتبط را شامل نمیشود. هنگام تنظیم fault (از طریق refreshObject:) دادهها از حافظه تخلیه میشوند. هنگام دسترسی به ویژگی، fault به طور خودکار با دادههای ذخیرهگاه پر میشود — این مکانیزم بارگذاری تأخیری است که استفاده از حافظه را بهینه میکند.
برای تست از نوع ذخیرهگاه In-Memory استفاده کنید: NSPersistentStoreDescription با NSInMemoryStoreType. کانتینر با مدل از باندل تست ایجاد میشود. پس از هر تست، همه اشیاء را حذف کنید یا کانتینر را بازسازی کنید — این ایزوله بودن موارد تست را از یکدیگر تضمین میکند.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید