Loading skill
Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Generates SwiftData or CoreData persistence layer with optional iCloud sync. Use when user wants to add local storage, data persistence, or cloud sync.
.claude/skills/rshankras-persistence-setup/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-06 | ✗→✓ | ▲ Improved | 47% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 29% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 6% | 0% |
| case-14 | ✗→✓ | ▲ Improved | 43% | 0% |
| case-04 | ✓→✓ | = Same ✓ | 64% | 0% |
Generates a production-ready persistence layer using SwiftData (iOS 17+) or CoreData with optional iCloud (CloudKit) sync.
Before generating, ALWAYS check:
bash# Check deployment target cat Package.swift | grep -i "platform" # Or check project.pbxproj # Find existing persistence implementations rg -l "ModelContainer|NSPersistentContainer|@Model|@Entity" --type swift # Check for existing SwiftData models rg "@Model" --type swift | head -5 # Check for CoreData stack rg "NSManagedObjectContext|NSPersistentStore" --type swift | head -5 # Check existing entitlements for iCloud cat *.entitlements 2>/dev/null | grep -i "icloud"
Use SwiftData if:
Use CoreData if:
If existing persistence found:
Ask user via AskUserQuestion:
Always generate:
Sources/Persistence/
├── PersistenceController.swift # Container setup
├── Repository.swift # Repository protocol
└── SwiftDataRepository.swift # Concrete implementationIf example model requested:
Sources/Persistence/Models/
└── Item.swift # Sample @ModelIf iCloud enabled:
Sources/Persistence/CloudSync/
├── CloudKitConfiguration.swift # Container identifier
└── SyncStatus.swift # Sync monitoringRead templates from this skill:
templates/PersistenceController.swifttemplates/Repository.swifttemplates/SwiftDataRepository.swifttemplates/ExampleModel.swifttemplates/CloudKitConfiguration.swift (if iCloud)templates/SyncStatus.swift (if iCloud)Adapt templates to match:
Basic Integration:
swift@main struct MyApp: App { let container = PersistenceController.shared.container var body: some Scene { WindowGroup { ContentView() .modelContainer(container) } } }
With iCloud sync:
swift@main struct MyApp: App { let container = PersistenceController.shared.container var body: some Scene { WindowGroup { ContentView() .modelContainer(container) .environment(\.syncStatus, SyncStatus.shared) } } }
iCloud.com.yourcompany.yourappxml<key>com.apple.developer.icloud-container-identifiers</key> <array> <string>iCloud.com.yourcompany.yourapp</string> </array> <key>com.apple.developer.icloud-services</key> <array> <string>CloudKit</string> </array>
swiftprotocol Repository<T>: Sendable { associatedtype T: PersistentModel func fetch(predicate: Predicate<T>?, sortBy: [SortDescriptor<T>]) async throws -> [T] func insert(_ item: T) async throws func delete(_ item: T) async throws func save() async throws }
swift@Model final class Item { var title: String var timestamp: Date var isCompleted: Bool init(title: String, timestamp: Date = .now, isCompleted: Bool = false) { self.title = title self.timestamp = timestamp self.isCompleted = isCompleted } }
swiftlet container = try ModelContainer( for: Item.self, configurations: ModelConfiguration( cloudKitDatabase: .private("iCloud.com.yourcompany.yourapp") ) )
After generation, verify:
swift@Model final class Project { var name: String @Relationship(deleteRule: .cascade) var items: [Item] init(name: String, items: [Item] = []) { self.name = name self.items = items } } // Update container let container = try ModelContainer(for: Item.self, Project.self)
swiftlet descriptor = FetchDescriptor<Item>( predicate: #Predicate { $0.isCompleted == false }, sortBy: [SortDescriptor(\.timestamp, order: .reverse)] ) let items = try modelContext.fetch(descriptor)
swift// SwiftData handles lightweight migrations automatically // For complex migrations, use VersionedSchema enum ItemSchemaV1: VersionedSchema { static var versionIdentifier = Schema.Version(1, 0, 0) static var models: [any PersistentModel.Type] { [Item.self] } }
modelContainer modifier is on root viewsave() is called after modificationscloudKitDatabase: .automatic for shared containersnetworking-layer - For remote API data alongside local cachesettings-screen - Often uses @AppStorage (simpler persistence)Other measured skills in the registry, with their headline benchmark lift.