Core Data — це фреймворк керування даними від Apple, що надає об'єктно-реляційне відображення для 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 використовується в 52% iOS-застосунків, що працюють із локальними даними. Незважаючи на появу сучасних альтернатив (SwiftData, Realm), Core Data залишається основним фреймворком у наявних проєктах Apple завдяки зрілості та глибокій інтеграції з системою.
Використовуйте Core Data для проєктів із моделлю даних середньої складності, де потрібні зв'язки між об'єктами, відкочування змін та автоматичне кешування через faulting-механізм.
Архітектура Core Data побудована навколо концепції Managed Object Context — робочої області, яка відстежує всі зміни об'єктів. Контекст підтримує скасування/повторення (undo/redo) через вбудований NSUndoManager, що дозволяє реалізувати чернетки та скасування дій без ручного збереження знімків стану. При виклику 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 (унікальні обмеження), індекси для прискорення запитів та значення за замовчуванням для атрибутів. Усі зміни моделі компілюються у файл .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 — головний контекст, прив'язаний до головного потоку. Усі читання та оновлення інтерфейсу виконуються через нього. Запис даних для продуктивності рекомендується виконувати на фоновому дочірньому контексті з подальшою синхронізацією.
Координатор 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 для читання.
Дочірній контекст зберігається в батьківський, а потім батьківський — у сховище на диску. Це гарантує, що зміни не блокують головний потік і що інтерфейс завжди бачить консистентний стан через mergeChanges або автоматичне оновлення viewContext при збереженні.
Core Data використовує faulting — механізм відкладеного завантаження пов'язаних об'єктів. При отриманні User без запиту його адрес, пов'язані Address не завантажуються, доки до них не відбудеться звернення через крапкову нотацію. Faulting економить пам'ять і прискорює завантаження, але може викликати неочікувані звернення до диску на головному потоці, якщо не контролювати доступ у фонових контекстах.
Для ефективної багатопотоковості використовуйте NSBatchInsertRequest та NSBatchDeleteRequest для масового вставлення та видалення без завантаження об'єктів у пам'ять — це критично для синхронізації даних із сервером.
Пакетні операції виконуються безпосередньо на рівні NSPersistentStoreCoordinator, минаючи контекст та граф об'єктів. Це дозволяє вставити 10 000 записів за кілька мілісекунд без створення 10 000 екземплярів NSManagedObject у пам'яті. Після виконання пакетного запиту контекст необхідно оновити через mergeChangesFromContextDidSaveNotification, щоб інтерфейс відобразив нові дані. Apple рекомендує пакетні операції для початкового завантаження даних та нічної синхронізації з сервером.
Для відстеження змін у 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. Lightweight міграція вмикається прапорцем shouldMigrateAutomatically в NSPersistentStoreDescription.
Так, Core Data інтегрується зі SwiftUI через обгортку @FetchRequest для запитів та @ObservedObject для підписки на зміни. SwiftUI автоматично оновлює View при зміні ManagedObject, що робить Core Data та SwiftUI сумісним стеком для керування станом.
Fault — це легка заглушка в графі Core Data, що не містить даних пов'язаного об'єкта. При встановленні fault (через refreshObject:) дані вивантажуються з пам'яті. При зверненні до властивості fault автоматично заповнюється даними зі сховища — це механізм відкладеного завантаження, який оптимізує використання пам'яті.
Для тестування використовуйте In-Memory тип сховища: NSPersistentStoreDescription з NSInMemoryStoreType. Контейнер створюється з моделлю з тестового бандла. Після кожного тесту видаляйте всі об'єкти або перестворюйте контейнер — це гарантує ізоляцію тестових кейсів один від одного.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також