Когда приложение хранит больше пары настроек, UserDefaults перестаёт справляться. Нужен нормальный инструмент: писать, читать, фильтровать, не терять данные при перезапуске. В iOS три основных варианта — Core Data, Realm и SwiftData. У каждого свой характер, и выбор между ними сильно влияет на то, как будет развиваться проект.
Core Data — ветеран, которого все боятся
Core Data появился ещё в эпоху Objective-C. Ему больше 15 лет, и он до сих пор в строю. Это не просто база данных — это ORM поверх SQLite, которую Apple встроила в саму систему.
Что хорошо:
- Отличная интеграция со SwiftUI через
@FetchRequest и с UIKit через NSFetchedResultsController
- Поддержка миграций — схему можно менять без потери данных
- Lazy loading: объекты загружаются по мере необходимости, не всё сразу в память
- iCloud sync через
NSPersistentCloudKitContainer — из коробки, почти без лишнего кода
- Работает с iOS 3 — если нужна совместимость, это единственный вариант
Что бесит:
- Бойлерплейт. Чтобы сохранить один объект, надо написать 10–15 строк
NSManagedObjectContext — одна из главных причин трудноуловимых багов. Контексты, потоки, merge policy — это отдельный мир, в котором легко запутаться
- Модель создаётся в
.xcdatamodeld — визуальный редактор есть, но декларативности нет
- Ошибки вылезают в рантайме, не в компайл-тайме
Пример — добавить задачу:
let context = persistentContainer.viewContext
let task = Task(context: context)
task.title = "Купить молоко"
task.createdAt = Date()
do {
try context.save()
} catch {
print("Ошибка: \(error)")
}
Выглядит терпимо, но это только начало. Когда добавляется фоновый поток, синхронизация, связи между объектами — сложность нарастает быстро.
Когда брать Core Data:
Если нужна синхронизация с iCloud — Core Data плюс CloudKit это самый короткий путь. Ещё если команда уже знает Core Data или проект долгосрочный и большой — есть смысл взять проверенное решение.
Realm — быстрый и дружелюбный
Realm — сторонняя библиотека, сейчас принадлежит MongoDB. Это не обёртка над SQLite — у Realm своя база данных. Именно это даёт скорость.
По открытым бенчмаркам Realm на операциях чтения быстрее Core Data в 5–15 раз в зависимости от сценария. На небольших объёмах разница незаметна, но когда записей десятки тысяч — ощутимо.
Что хорошо:
- Простой API. Минимум кода для базовых операций
- Live objects — объекты автоматически обновляются при изменении базы, не надо вручную слушать уведомления
- Безопасность потоков проще, чем в Core Data
- Realm Studio — отдельная программа для просмотра содержимого базы, очень помогает при отладке
- Realm Sync — готовая синхронизация с сервером через MongoDB Atlas
Что бесит:
- Сторонняя зависимость. Если MongoDB решит изменить политику — это риск
- Миграции схемы надо писать вручную, нет такого удобного инструмента, как в Core Data
- Объекты Realm наследуются от
Object — это иногда мешает при интеграции с другими частями архитектуры
- Realm Sync требует аккаунт MongoDB Atlas. Бесплатный план есть, но это cloud lock-in
Пример — та же задача:
let realm = try! Realm()
let task = Task()
task.title = "Купить молоко"
task.createdAt = Date()
try! realm.write {
realm.add(task)
}
Чище и короче. Транзакция явная — это хорошо, не нужно помнить про save() в нужный момент.
Когда брать Realm:
Когда важна скорость и простота. Хорошо подходит для приложений с большими объёмами данных, для прототипирования, для команд, которые хотят меньше возиться с настройкой инфраструктуры.
SwiftData — новичок от Apple
SwiftData появился в 2023 году вместе с iOS 17. По сути — это то, чем Core Data должна была быть с самого начала, но написанная с учётом современного Swift и его макросов.
Под капотом у SwiftData всё та же Core Data и SQLite. Это не новая база данных — это новый слой API поверх старого. Но API настолько лучше, что это реально меняет опыт разработки.
Что хорошо:
- Декларативные модели через макросы — никаких
.xcdatamodeld файлов
- Полная и плотная интеграция со SwiftUI
- Многие ошибки видны в компайл-тайме, а не в рантайме
- Кода в 3–4 раза меньше, чем в Core Data
- iCloud sync работает так же, как в Core Data — через то же самое под капотом
Что бесит:
- Только iOS 17+. Если надо поддерживать iOS 15 или 16 — не вариант
- Библиотека молодая, баги встречаются, API ещё может меняться
- Миграции пока слабее, чем в Core Data
- Сложные запросы — агрегации, вычисляемые поля — реализовать неудобно
Пример — та же задача:
@Model
class Task {
var title: String
var createdAt: Date
init(title: String, createdAt: Date = .now) {
self.title = title
self.createdAt = createdAt
}
}
// В SwiftUI-вью:
@Environment(\.modelContext) private var context
let task = Task(title: "Купить молоко")
context.insert(task)
Это уже читается как обычный Swift-код. Никаких контекстов, никаких save() вручную — SwiftData сохраняет сам при нужном моменте.
Когда брать SwiftData:
Новые приложения с минимальным iOS 17, команды на SwiftUI, проекты где важна читаемость кода и скорость разработки.
Сравнение по ключевым параметрам
| Параметр |
Core Data |
Realm |
SwiftData |
| Минимальный iOS |
iOS 3 |
iOS 13 |
iOS 17 |
| Скорость записи |
Средняя |
Высокая |
Средняя |
| Скорость чтения |
Средняя |
Очень высокая |
Средняя |
| Простота API |
Низкая |
Высокая |
Высокая |
| Миграции |
Хорошие |
Ручные |
Базовые |
| iCloud Sync |
Да |
Нет |
Да |
| Зависимость от Apple |
Полная |
Частичная |
Полная |
| Зрелость |
Высокая |
Высокая |
Низкая |
Производительность на реальных цифрах
Вот примерные результаты на 10 000 объектов (по открытым бенчмаркам, цифры зависят от устройства и структуры данных):
- Запись 10 000 записей: Realm — ~0.3 сек, Core Data — ~1.2 сек, SwiftData — ~1.0 сек
- Чтение с фильтрацией: Realm — ~0.05 сек, Core Data — ~0.3 сек, SwiftData — ~0.25 сек
- Пакетное удаление: Realm — ~0.1 сек, Core Data — ~0.8 сек, SwiftData — ~0.7 сек
Для большинства приложений эта разница незаметна пользователю. Но если приложение работает с геоданными, медиабиблиотеками или аналитическими выборками — преимущество Realm становится реальным.
Как выбрать под конкретный проект
Несколько практических сценариев:
Новое приложение, iOS 17+, команда пишет SwiftUI. SwiftData. Нет причин не брать. API приятный, интеграция со SwiftUI плотная, поддержка Apple гарантирована.
Приложение с поддержкой iOS 15+, нужна синхронизация с iCloud. Core Data. Да, больше кода, но это единственный нормальный вариант для CloudKit без третьих сторон.
Большой объём данных, частые запросы, скорость важна. Realm. Особенно если нужна синхронизация с бэкендом через Realm Sync.
Прототип, MVP, быстрый старт. Realm или SwiftData. Оба позволяют писать быстро. Core Data здесь избыточен по сложности.
Большой legacy-проект уже на Core Data. Не мигрировать ради миграции. Core Data стабильна, работает, жить можно.
Частая ошибка при выборе
Разработчики часто выбирают Core Data по инерции — «так всегда делали». Или берут Realm, потому что видели в туториале. Это не катастрофа, но лучше отталкиваться от реальных требований:
- Сколько записей будет максимум?
- Нужна ли синхронизация с облаком?
- Какой минимальный iOS поддерживаем?
- Есть ли в команде опыт с конкретной библиотекой?
Последнее часто важнее всего остального. Опытный разработчик на Core Data напишет лучше приложение, чем новичок, который неправильно настроил Realm и получает крэши на конкурентном доступе.
Если нужна помощь с архитектурой
Выбор базы данных — это часть более широкого решения: как приложение будет хранить данные, как синхронизировать их с сервером, как обеспечить офлайн-режим. Если разрабатываете приложение и не уверены, что подойдёт именно под вашу задачу — в REEXY можно обсудить архитектуру или заказать разработку с нуля. Такие вопросы лучше решать на старте, а не переписывать слой данных на середине проекта.
Выбор базы данных — это не вопрос «что лучше», а вопрос «что подходит под задачу». SwiftData — это будущее платформы, Realm — это скорость и удобство здесь и сейчас, Core Data — это надёжность и глубокая интеграция с экосистемой Apple. Понимая это, выбрать становится не так сложно.