ORM для Swift (iOS/macOS): сравнение и примеры использования

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

ORM для Swift (iOS/macOS): сравнение и примеры

При разработке приложений для iOS и macOS часто возникает необходимость работы с локальными базами данных. ORM (Object-Relational Mapping) позволяет работать с данными через объекты языка программирования, абстрагируясь от SQL-запросов. В экосистеме Swift существует несколько популярных решений. В этой статье мы сравним Core Data, Realm, GRDB и SwiftData, приведём примеры кода и поможем выбрать подходящий инструмент для вашего проекта.

1. Core Data

Core Data — это встроенный фреймворк Apple, который предоставляет не только ORM, но и полный стек управления объектами (граф объектов, lazy loading, undo/redo). Работает с SQLite, XML или бинарным хранилищем. Основная идея — работа через NSManagedObjectContext.

Пример кода (Core Data)

import CoreData

// Создание контекста
let container = NSPersistentContainer(name: "Model")
container.loadPersistentStores { _, error in
    if let error = error { print(error) }
}

// Сохранение объекта
let context = container.viewContext
let user = User(context: context)
user.name = "Иван"
user.age = 30

try? context.save()

// Запрос
let request: NSFetchRequest<User> = User.fetchRequest()
let users = try? context.fetch(request)

Плюсы: полная интеграция с Xcode, автоматическое управление миграциями, поддержка iCloud.

Минусы: сложный порог входа, необходимость создавать модель данных в редакторе, много boilerplate-кода.

2. Realm

Realm — это кроссплатформенная ORM, работающая на собственном движке (не на SQLite). Она быстрее Core Data в большинстве операций и имеет более простой API. Поддерживает Swift, Objective-C, Kotlin, Java.

Пример кода (Realm)

import RealmSwift

// Определение модели
class User: Object {
    @Persisted var name: String = ""
    @Persisted var age: Int = 0
}

// Сохранение
let realm = try! Realm()
let user = User(value: ["name": "Мария", "age": 25])
try! realm.write {
    realm.add(user)
}

// Запрос
let users = realm.objects(User.self).filter("age > 18")

Плюсы: высокая производительность, удобный API, встроенная поддержка Live Objects (автоматическое обновление UI).

Минусы: проприетарная лицензия (с 2020 года — открытая, но с ограничениями), большой размер бинарника, сложности с миграциями.

3. GRDB

GRDB — это легковесная библиотека для работы с SQLite на Swift. Она предоставляет как низкоуровневый доступ к SQL, так и высокоуровневую ORM с Record-типами. Это отличный выбор для тех, кто хочет контролировать SQL-запросы, но не хочет писать их вручную.

Пример кода (GRDB)

import GRDB

// Определение структуры
struct User: Codable, FetchableRecord, PersistableRecord {
    var id: Int64?
    var name: String
    var age: Int
}

// Подключение к БД
let dbQueue = try DatabaseQueue(path: "/path/to/database.sqlite")

// Сохранение
try dbQueue.write { db in
    var user = User(name: "Алексей", age: 28)
    try user.insert(db)
}

// Запрос
let users = try dbQueue.read { db in
    try User.filter(Column("age") >= 18).fetchAll(db)
}

Плюсы: лёгкий вес, полный контроль над SQL, отличная документация, поддержка Combine и Swift Concurrency.

Минусы: требует ручного управления миграциями, не такая "магическая" как Realm.

4. SwiftData (новинка от Apple)

SwiftData — это современная ORM, представленная на WWDC 2023. Она построена поверх Core Data, но с использованием Swift-макросов (@Model, @Attribute, @Relationship). Позволяет описывать модели прямо в коде.

Пример кода (SwiftData)

import SwiftData
import SwiftUI

@Model
class User {
    var name: String
    var age: Int
    
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
}

// Использование в SwiftUI
struct ContentView: View {
    @Environment(\.modelContext) private var context
    @Query private var users: [User]
    
    var body: some View {
        List(users) { user in
            Text(user.name)
        }
    }
}

Плюсы: нативная интеграция с SwiftUI, минимум кода, автоматические миграции.

Минусы: доступна только с iOS 17 / macOS 14, ограниченная кастомизация запросов, ещё сырая экосистема.

Сравнительная таблица

Рекомендаций