Realm with SwiftUI: A Comprehensive Guide with Real-World Examples, CRUD Operations & Relationships
Realm is a powerful and efficient mobile database solution that works seamlessly with SwiftUI. It offers live objects, thread safety, automatic change tracking, and more — making it a great alternative to Core Data for local data persistence.
In this guide, we’ll walk through how to integrate Realm with SwiftUI, perform full CRUD operations, run complex queries, and handle relationships in a real-world-style example.
📦 Why Realm?
- Fast and lightweight
- Easy to use with SwiftUI
- Live data updates via ObservedResults
- Thread-safe
- Schema migrations made easy
🚀 Getting Started with Realm in SwiftUI
🔧 Step 1: Add Realm to Your Project
Use Swift Package Manager and add:
https://github.com/realm/realm-swift.git
Select the latest version.
🧱 Step 2: Define Your Realm Models
Let’s build a Task Management App with Projects and Tasks.
import RealmSwift
class Project: Object, ObjectKeyIdentifiable {
@Persisted(primaryKey: true) var id: ObjectId
@Persisted var title: String = ""
@Persisted var tasks = RealmSwift.List<Task>()
}
class Task: Object, ObjectKeyIdentifiable {
@Persisted(primaryKey: true) var id: ObjectId
@Persisted var name: String = ""
@Persisted var isCompleted: Bool = false
}
🧩 Setting Up the Realm Configuration
class RealmManager: ObservableObject {
private(set) var realm: Realm?
init() {
do {
realm = try Realm()
} catch {
print("Failed to open Realm: \(error.localizedDescription)")
}
}
}
🧑🎨 SwiftUI View with Realm Integration
📃 Display a List of Projects
import RealmSwift
struct ProjectListView: View {
@ObservedResults(Project.self) var projects
var body: some View {
NavigationView {
List {
ForEach(projects) { project in
NavigationLink(destination: TaskListView(project: project)) {
Text(project.title)
}
}
.onDelete(perform: $projects.remove)
}
.navigationTitle("Projects")
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button("Add") {
$projects.append(Project(value: ["title": "New Project"]))
}
}
}
}
}
}
🔄 CRUD Operations in Realm with SwiftUI
✅ Create a Task
func addTask(to project: Project, name: String) {
guard let realm = project.realm else { return }
try? realm.write {
let newTask = Task()
newTask.name = name
project.tasks.append(newTask)
}
}
✏️ Update a Task
func toggleCompletion(task: Task) {
guard let realm = task.realm else { return }
try? realm.write {
task.isCompleted.toggle()
}
}
❌ Delete a Task
func deleteTask(project: Project, indexSet: IndexSet) {
guard let realm = project.realm else { return }
try? realm.write {
project.tasks.remove(atOffsets: indexSet)
}
}
🔍 Complex Queries in Realm
// All completed tasks across all projects
let completedTasks = realm.objects(Task.self).where { $0.isCompleted == true }
// Projects with more than 3 tasks
let activeProjects = realm.objects(Project.self).where { $0.tasks.count > 3 }
🔗 Handling Relationships in Realm
In our example:
- A
Project
has manyTask
s (one-to-many). - Realm’s
List<T>
handles this relationship natively.
To access all tasks under a project:
let tasks = project.tasks
You can filter or sort them:
let sortedTasks = project.tasks.sorted(byKeyPath: "name")
🎨 TaskListView (Child Relationship Example)
struct TaskListView: View {
@ObservedRealmObject var project: Project
@State private var taskName = ""
var body: some View {
VStack {
List {
ForEach(project.tasks) { task in
HStack {
Text(task.name)
Spacer()
Button(action: {
toggleCompletion(task: task)
}) {
Image(systemName: task.isCompleted ? "checkmark.circle.fill" : "circle")
}
}
}
.onDelete(perform: delete)
}
HStack {
TextField("New Task", text: $taskName)
Button("Add") {
addTask(to: project, name: taskName)
taskName = ""
}
}
.padding()
}
.navigationTitle(project.title)
}
func delete(at offsets: IndexSet) {
deleteTask(project: project, indexSet: offsets)
}
}
🧪 Testing & Debugging Tips
- Use
Realm.Configuration.inMemoryIdentifier
for testing - Add breakpoints inside
try realm.write
blocks - Use Realm Studio to inspect your database visually
✨ Final Thoughts
Realm + SwiftUI is a powerful combo for building responsive, data-driven iOS apps. You get:
- Real-time UI updates
- Simple relationship management
- Easy schema migrations
Start small — then scale your models and views. With Realm’s speed and SwiftUI’s declarative syntax, your next app is in great shape!
Comments
Post a Comment