last update
May 23, 2026
license
MITv1.0.0
format
SKILL.md
- Install
// Downloads SKILL.md into ~/.claude/skills/ios-coredata-architect/
$ curl -fsSL --create-dirs -o ~/.claude/skills/ios-coredata-architect/SKILL.md https://claudeskil.com/skills/ios-coredata-architect/SKILL.md - Invoke
// Inside Claude Code, type the skill name as a slash command
> /ios-coredata-architect help me ship this - Or copy this from the README
// extracted from a Usage / Example section
$ > Design a SwiftData model for Notebook -> Note (one-to-many), CloudKit-synced, with full-text-ish search on Note.title. @Model final class Notebook { var name: String = "" // CloudKit: no .unique, inverse required, cascade delete
- name:
- Core Data & SwiftData Architect
- slug:
- ios-coredata-architect
- version:
- v1.0.0
- license:
- MIT
- author:
- @chiragthummar16
- categories:
- tags:
- #coredata#swiftdata#persistence#swift#cloudkit
- description:
Core Data schemas, NSPersistentCloudKitContainer, SwiftData migrations — Apple persistence done right.
// What you can do with it
- Builds SwiftData models with @Model, @Attribute(.unique), @Relationship(deleteRule:inverse:), and @Index, plus the matching Core Data entity/attribute/relationship setup and Spotlight/derived attribut
- Sets up ModelContainer / ModelConfiguration and the Core Data equivalent (NSPersistentContainer, NSManagedObjectContext, background contexts via performBackgroundTask).
- Configures NSPersistentCloudKitContainer correctly: optional attributes with defaults, no unique constraints (CloudKit forbids them), NSPersistentHistoryTrackingKey, and remote-change notifications.
- Plans migrations — lightweight inference, VersionedSchema + SchemaMigrationPlan (custom/lightweight stages) for SwiftData, and mapping models / NSMigrationManager when inference can't bridge the chang
README.md
Core Data & SwiftData Architect
A focused assistant for Apple's persistence stack. It designs Core Data and SwiftData models that hold up in production — sane relationships, the right indexes, safe migrations, and CloudKit sync that actually round-trips — and it knows the sharp edges of moving an existing Core Data app onto SwiftData. Aimed at iOS/macOS developers who are past "hello world" and need the schema decisions to be correct before they ship.
When to use it
- You're starting a new app and want a SwiftData
@Modelgraph (or.xcdatamodeld) designed correctly the first time. - A lightweight migration is silently failing and you need to know whether you've crossed into a mapping-model situation.
- You're adopting
NSPersistentCloudKitContainerand hitting "CloudKit integration requires…" errors at launch. - You want to migrate a Core Data codebase to SwiftData without losing the existing on-disk store.
- You need a fetch to stop being slow and suspect a missing index or an N+1 relationship fault.
What it does
- Builds SwiftData models with
@Model,@Attribute(.unique),@Relationship(deleteRule:inverse:), and@Index, plus the matching Core Data entity/attribute/relationship setup and Spotlight/derived attributes where useful. - Sets up
ModelContainer/ModelConfigurationand the Core Data equivalent (NSPersistentContainer,NSManagedObjectContext, background contexts viaperformBackgroundTask). - Configures
NSPersistentCloudKitContainercorrectly: optional attributes with defaults, no unique constraints (CloudKit forbids them),NSPersistentHistoryTrackingKey, and remote-change notifications. - Plans migrations — lightweight inference,
VersionedSchema+SchemaMigrationPlan(custom/lightweight stages) for SwiftData, and mapping models /NSMigrationManagerwhen inference can't bridge the change.
Example
curl -fsSL --create-dirs -o ~/.claude/skills/ios-coredata-architect/SKILL.md https://claudeskil.com/skills/ios-coredata-architect/SKILL.md
> Design a SwiftData model for Notebook -> Note (one-to-many),
CloudKit-synced, with full-text-ish search on Note.title.
@Model final class Notebook {
var name: String = ""
// CloudKit: no .unique, inverse required, cascade delete
@Relationship(deleteRule: .cascade, inverse: \Note.notebook)
var notes: [Note] = []
}
@Model final class Note {
#Index<Note>([\.title])
var title: String = ""
var notebook: Notebook?
}
Tips & gotchas
- For CloudKit, every attribute must be optional or have a default, and
@Attribute(.unique)is unavailable — model uniqueness in app logic instead. - Lightweight migration silently bails when you rename without a renaming identifier; set
@Attribute(originalName:)(SwiftData) or hash-modifier renaming IDs (Core Data). - Enable
NSPersistentHistoryTrackingKeybefore going multi-process or CloudKit, not after — retrofitting history tracking onto a live store is painful. - SwiftData and Core Data can share one store; keep the
NSManagedObjectModeland@Modelgraph byte-compatible during a phased migration.
FAQ
Can I migrate to SwiftData without resetting users' data? Yes. Point ModelConfiguration at the existing store URL and keep entity/attribute names identical; SwiftData reads the Core Data store in place.
Why does CloudKit sync drop some records? Usually a non-optional attribute with no default or a unique constraint — both are rejected by the CloudKit schema. The skill audits the model for these.
Lightweight vs. mapping model — how do I know? If you only add/remove attributes or optional relationships, inference handles it. Renames, type changes, or splitting entities need a SchemaMigrationPlan stage or an NSMappingModel.
$ cat reviews/