ORM for Swift (iOS/macOS): Comparison and Examples
When developing applications for iOS and macOS, the need to work with local databases often arises. ORM (Object-Relational Mapping) allows you to work with data through programming language objects, abstracting away from SQL queries. There are several popular solutions in the Swift ecosystem. In this article, we will compare Core Data, Realm, GRDB, and SwiftData, provide code examples, and help you choose the right tool for your project.
1. Core Data
Core Data is Apple's built-in framework that provides not only ORM but also a full object management stack (object graph, lazy loading, undo/redo). It works with SQLite, XML, or binary storage. The main idea is working through NSManagedObjectContext.
Code Example (Core Data)
import CoreData
// Creating a contextlet container = NSPersistentContainer(name: "Model")container.loadPersistentStores { _, error in if let error = error { print(error) }}
// Saving an objectlet context = container.viewContextlet user = User(context: context)user.name = "Ivan"user.age = 30
try? context.save()
// Querylet request: NSFetchRequest<User> = User.fetchRequest()let users = try? context.fetch(request)Pros: full integration with Xcode, automatic migration management, iCloud support.
Cons: steep learning curve, need to create data model in the editor, lots of boilerplate code.
2. Realm
Realm is a cross-platform ORM running on its own engine (not SQLite). It is faster than Core Data in most operations and has a simpler API. Supports Swift, Objective-C, Kotlin, Java.
Code Example (Realm)
import RealmSwift
// Defining a modelclass User: Object { @Persisted var name: String = "" @Persisted var age: Int = 0}
// Savinglet realm = try! Realm()let user = User(value: ["name": "Maria", "age": 25])try! realm.write { realm.add(user)}
// Querylet users = realm.objects(User.self).filter("age > 18")Pros: high performance, convenient API, built-in support for Live Objects (automatic UI updates).
Cons: proprietary license (open source since 2020 but with restrictions), large binary size, migration difficulties.
3. GRDB
GRDB is a lightweight library for working with SQLite in Swift. It provides both low-level access to SQL and high-level ORM with Record types. This is an excellent choice for those who want to control SQL queries but don't want to write them manually.
Code Example (GRDB)
import GRDB
// Defining a structurestruct User: Codable, FetchableRecord, PersistableRecord { var id: Int64? var name: String var age: Int}
// Connecting to DBlet dbQueue = try DatabaseQueue(path: "/path/to/database.sqlite")
// Savingtry dbQueue.write { db in var user = User(name: "Alexey", age: 28) try user.insert(db)}
// Querylet users = try dbQueue.read { db in try User.filter(Column("age") >= 18).fetchAll(db)}Pros: lightweight, full control over SQL, excellent documentation, support for Combine and Swift Concurrency.
Cons: requires manual migration management, not as "magical" as Realm.
4. SwiftData (New from Apple)
SwiftData is a modern ORM introduced at WWDC 2023. It is built on top of Core Data but uses Swift macros (@Model, @Attribute, @Relationship). Allows describing models directly in code.
Code Example (SwiftData)
import SwiftDataimport SwiftUI
@Modelclass User { var name: String var age: Int init(name: String, age: Also in library
Dependency Injection Container for Java: Spring IoC, Google Guice, and Dagger
Working with Kafka in Kotlin: Libraries and Examples
Rig for Rust: Complete Guide with Examples
RxSwift for Swift: Complete Guide with Examples
Working with Images in PHP: Resize, Crop, and Optimization with GD and Imagick