Use when choosing Core Data vs SwiftData, setting up the Core Data stack, modeling relationships, or implementing concurrency patterns - prevents thread-confinement errors and migration crashes
View on GitHubSelect agents to install to:
npx add-skill https://github.com/CharlesWiltgen/Axiom/blob/main/.claude-plugin/plugins/axiom/skills/axiom-core-data/SKILL.md -a claude-code --skill axiom-core-dataInstallation paths:
.claude/skills/axiom-core-data/# Core Data
## Overview
**Core principle**: Core Data is a mature object graph and persistence framework. Use it when needing features SwiftData doesn't support, or when targeting older iOS versions.
**When to use Core Data vs SwiftData**:
- **SwiftData** (iOS 17+) — New apps, simpler API, Swift-native
- **Core Data** — iOS 16 and earlier, advanced features, existing codebases
## Quick Decision Tree
```
Which persistence framework?
├─ Targeting iOS 17+ only?
│ ├─ Simple data model? → SwiftData (recommended)
│ ├─ Need public CloudKit database? → Core Data (SwiftData is private-only)
│ ├─ Need custom migration logic? → Core Data (more control)
│ └─ Existing Core Data app? → Keep Core Data or migrate gradually
│
├─ Targeting iOS 16 or earlier?
│ └─ Core Data (SwiftData unavailable)
│
└─ Need both? → Use Core Data with SwiftData wrapper (advanced)
```
## Red Flags
If ANY of these appear, STOP:
- ❌ "Access managed objects on any thread" — Thread-confinement violation
- ❌ "Skip migration testing on real device" — Simulator hides schema issues
- ❌ "Use a singleton context everywhere" — Leads to concurrency crashes
- ❌ "Force lightweight migration always" — Complex changes need mapping models
- ❌ "Fetch in view body" — Use @FetchRequest or observe in view model
## Core Data Stack Setup
### Modern Stack (iOS 10+)
```swift
import CoreData
class CoreDataStack {
static let shared = CoreDataStack()
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "Model")
// Configure for CloudKit if needed
// container.persistentStoreDescriptions.first?.cloudKitContainerOptions =
// NSPersistentCloudKitContainerOptions(containerIdentifier: "iCloud.com.app")
container.loadPersistentStores { description, error in
if let error = error {
// Handle appropriately for production
fatalError("Failed to load store: \(error)")
}