iOS SwiftData Persistence
mobile
Swift
architecture
zen
Modern data persistence in iOS using SwiftData with models, queries, and relationships.
By alex_dev
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