swiftui-data
Implement data persistence with SwiftData, Core Data, CloudKit sync, and local storage. Use when storing app data, creating database models, syncing with iCloud, or managing user preferences with AppStorage.
When & Why to Use This Skill
This Claude skill provides comprehensive implementation patterns for data persistence in SwiftUI applications. It streamlines the integration of modern SwiftData (iOS 17+), legacy Core Data, and CloudKit synchronization, enabling developers to build robust, data-driven iOS apps. By offering optimized code snippets for data modeling, CRUD operations, and user preference management, it ensures best practices in local storage and cloud-based data consistency.
Use Cases
- case 1: Implementing local data persistence and complex relationship modeling in modern iOS apps using SwiftData.
- case 2: Enabling seamless cross-device data synchronization via CloudKit for users within the Apple ecosystem.
- case 3: Managing lightweight user settings and UI state persistence using @AppStorage and @SceneStorage for a better user experience.
- case 4: Architecting data-heavy applications that require efficient querying, filtering, and sorting of local database records.
| name | swiftui-data |
|---|---|
| description | Implement data persistence with SwiftData, Core Data, CloudKit sync, and local storage. Use when storing app data, creating database models, syncing with iCloud, or managing user preferences with AppStorage. |
SwiftUI Data Persistence
SwiftData (iOS 17+) - Recommended
import SwiftData
@Model
final class Task {
var title: String
var isCompleted: Bool
var createdAt: Date
var priority: Priority
@Relationship(deleteRule: .cascade)
var subtasks: [Subtask]?
init(title: String, priority: Priority = .medium) {
self.title = title
self.isCompleted = false
self.createdAt = .now
self.priority = priority
}
}
enum Priority: String, Codable, CaseIterable {
case low, medium, high
}
// App configuration
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
.modelContainer(for: Task.self)
}
}
SwiftData Queries
struct TaskListView: View {
@Query(
filter: #Predicate<Task> { !$0.isCompleted },
sort: \Task.createdAt,
order: .reverse
)
private var tasks: [Task]
@Environment(\.modelContext) private var context
var body: some View {
List(tasks) { task in
TaskRow(task: task)
.swipeActions {
Button("Delete", role: .destructive) {
context.delete(task)
}
}
}
}
func addTask(_ title: String) {
let task = Task(title: title)
context.insert(task)
}
}
CloudKit Sync with SwiftData
// Enable in App configuration
@main
struct MyApp: App {
var container: ModelContainer
init() {
let schema = Schema([Task.self, Subtask.self])
let config = ModelConfiguration(
schema: schema,
cloudKitDatabase: .private("iCloud.com.myapp")
)
container = try! ModelContainer(
for: schema,
configurations: [config]
)
}
var body: some Scene {
WindowGroup {
ContentView()
}
.modelContainer(container)
}
}
AppStorage & SceneStorage
struct SettingsView: View {
// Persists to UserDefaults
@AppStorage("username") private var username = ""
@AppStorage("isDarkMode") private var isDarkMode = false
@AppStorage("fontSize") private var fontSize = 14.0
// Persists per-scene (window state)
@SceneStorage("selectedTab") private var selectedTab = 0
var body: some View {
Form {
TextField("Username", text: $username)
Toggle("Dark Mode", isOn: $isDarkMode)
Slider(value: $fontSize, in: 10...24)
}
}
}
When to Use What
| Solution | Use Case |
|---|---|
@AppStorage |
Simple preferences, settings |
@SceneStorage |
Window/scene-specific UI state |
| SwiftData | Complex models, relationships, CloudKit |
| Core Data | iOS < 17, advanced migrations |
| Keychain | Sensitive data (tokens, passwords) |
| FileManager | Documents, large files, exports |