iOS SwiftData Persistence

mobile
Swift
architecture
zen
Remix

Modern data persistence in iOS using SwiftData with models, queries, and relationships.

12/8/2025

Prompt

iOS SwiftData Persistence

Implement data persistence for [iOS App] using SwiftData with models, queries, and relationships.

Requirements

1. Data Models

Define SwiftData models for:

  • [Model 1] - [Purpose] (e.g., User)
  • [Model 2] - [Purpose] (e.g., Post)
  • [Model 3] - [Purpose] (e.g., Comment)

2. Model Properties

For each model include:

  • Unique identifiers
  • Required vs optional properties
  • Relationships to other models
  • Computed properties if needed
  • Proper data types

3. Relationships

Implement:

  • One-to-many relationships
  • Many-to-many relationships (if needed)
  • Cascading deletes
  • Relationship constraints

4. Queries

Create queries for:

  • Fetching all records
  • Filtering by properties
  • Sorting
  • Searching
  • Complex predicates

5. Model Container Setup

Configure:

  • SwiftData model container
  • Schema versioning strategy
  • Model context injection
  • Preview data for SwiftUI previews

Implementation Pattern

import SwiftData
import Foundation

// Define models with @Model macro
@Model
class [ModelName] {
    @Attribute(.unique) var id: UUID
    var [property1]: String
    var [property2]: Date
    var [optionalProperty]: String?
    
    // Relationships
    @Relationship(deleteRule: .cascade) var [relatedItems]: [[RelatedModel]]?
    @Relationship(inverse: \\[RelatedModel].[inverseProperty]) var [parent]: [ParentModel]?
    
    init([property1]: String, [property2]: Date) {
        self.id = UUID()
        self.[property1] = [property1]
        self.[property2] = [property2]
    }
}

// App entry with model container
@main
struct [AppName]: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .modelContainer(for: [[ModelName].self, [OtherModel].self])
    }
}

// SwiftUI View with queries
struct [ViewName]: View {
    @Environment(\\.modelContext) private var modelContext
    @Query(sort: \\[ModelName].[sortProperty]) private var items: [[ModelName]]
    
    // Filtered query
    @Query(filter: #Predicate<[ModelName]> { item in
        item.[property].contains([searchTerm])
    }, sort: \\[ModelName].[property]) private var filteredItems: [[ModelName]]
    
    var body: some View {
        List {
            ForEach(items) { item in
                Text(item.[property])
            }
            .onDelete(perform: deleteItems)
        }
        .toolbar {
            Button(action: addItem) {
                Label(\"Add\", systemImage: \"plus\")
            }
        }
    }
    
    private func addItem() {
        let newItem = [ModelName]([property1]: \"Value\", [property2]: Date())
        modelContext.insert(newItem)
    }
    
    private func deleteItems(at offsets: IndexSet) {
        for index in offsets {
            modelContext.delete(items[index])
        }
    }
}

// Preview with sample data
#Preview {
    [ViewName]()
        .modelContainer(for: [ModelName].self, inMemory: true)
}

Complex Queries

// Query with predicate
@Query(filter: #Predicate<[ModelName]> { item in
    item.[property] > [value] && item.[status] == [status]
})
private var filtered Items: [[ModelName]]

// Sort descriptors
@Query(sort: [
    SortDescriptor(\\[ModelName].[property1]),
    SortDescriptor(\\[ModelName].[property2], order: .reverse)
])
private var sortedItems: [[ModelName]]

Best Practices

  • Use @Attribute(.unique) for unique properties
  • Define clear relationship deletion rules
  • Use @Query for automatic UI updates
  • Leverage SwiftData's automatic change tracking
  • Create preview containers with sample data
  • Handle migrations for schema changes
  • Use descriptive property names
  • Implement proper error handling

Tags

ios
swiftdata
persistence
coredata

Tested Models

gpt-4
claude-3-opus

Comments (0)

Sign in to leave a comment

Sign In