When we started building QuietClip, one of the first architectural decisions was how to persist clipboard history. A clipboard manager accumulates data constantly — every copy adds a row — and needs to query it fast (the search panel has to feel instant). We needed a real database, not UserDefaults or flat files.
The choice came down to Core Data and SwiftData. We went with SwiftData. Here’s why — and where we think Core Data is still the better option.
Why we needed persistence
Clipboard managers have specific persistence requirements:
- High write frequency — new items arrive every few seconds during active use
- Fast reads with filtering — the user types a search query and results must appear instantly
- Mixed data types — text strings, image data (as file references), metadata
- Bounded growth — the database must enforce a maximum item count
- Reliability — losing clipboard history defeats the entire purpose
Both Core Data and SwiftData, backed by SQLite, handle all of this. The question was which one made the codebase simpler.
SwiftData advantages
The difference in model definition is striking. Here’s a simplified clipboard item in Core Data versus SwiftData:
Core Data requires an .xcdatamodeld file in Xcode’s visual editor, plus a generated NSManagedObject subclass. Changing a property means updating the model editor, regenerating code, and potentially writing a migration mapping.
SwiftData is just Swift:
@Model
final class ClipItem {
var content: String
var imageURL: String?
var sourceApp: String?
var copiedAt: Date
var isPinned: Bool
init(content: String, copiedAt: Date = .now) {
self.content = content
self.copiedAt = copiedAt
self.isPinned = false
}
}
That’s the entire model definition. The schema, the storage, the SwiftUI integration — it all flows from the @Model macro.
With SwiftData, the model IS the schema. There’s no separate definition to keep in sync, no code generation step, no visual editor. You write Swift, and it works.
Where Core Data still wins
SwiftData isn’t universally better. Core Data has real advantages in certain scenarios:
Migration control. Core Data’s heavyweight migration with mapping models gives you fine-grained control over how data transforms between schema versions. SwiftData’s lightweight migration handles adding and removing properties automatically, but complex transformations (renaming a property, splitting a field into two) can be harder.
Mature escape hatches. Core Data lets you drop down to raw SQL via NSPersistentStoreCoordinator, use batch operations (NSBatchDeleteRequest, NSBatchInsertRequest), and access the SQLite store directly. SwiftData’s surface area is smaller — intentionally — but that means fewer options when you hit an edge case.
Deployment target. Core Data runs on every Apple OS version. SwiftData requires macOS 14+, iOS 17+. If you need to support older systems, Core Data is your only option.
Migration complexity
For QuietClip’s simple data model — a flat table of clipboard items with text, image references, and metadata — SwiftData’s automatic lightweight migration handles every change we’ve needed. Adding a new property? SwiftData migrates the store automatically. But if we needed to restructure the schema significantly, Core Data’s mapping models would give us more control.
Our data model
QuietClip’s data model is deliberately simple. Each clipboard entry stores:
- The text content (for text items) or a file path (for images)
- The source application’s bundle identifier
- A timestamp
- A pinned flag
- The pasteboard type metadata
This flat structure is ideal for SwiftData. No relationships, no complex graphs, no need for Core Data’s more advanced features like fetched properties or derived attributes.
Querying is handled entirely with @Query in SwiftUI:
@Query(sort: \ClipItem.copiedAt, order: .reverse)
private var items: [ClipItem]
For search, #Predicate replaces NSPredicate with type-safe, compile-time-checked filtering:
let searchPredicate = #Predicate<ClipItem> { item in
item.content.localizedStandardContains(searchText)
}
No stringly-typed key paths. No runtime crashes from typos in predicate format strings.
The decision
For a new macOS app targeting macOS 14+ with a simple data model and a SwiftUI interface, SwiftData was the clear choice. It eliminated hundreds of lines of boilerplate, integrated naturally with our SwiftUI views, and made the codebase genuinely easier to understand.
If your app targets macOS 14+, has a straightforward data model, and uses SwiftUI — choose SwiftData. You’ll write less code, maintain less infrastructure, and ship faster. Core Data is still the right choice for complex schemas, legacy OS support, or apps that need granular migration control.
The best persistence layer is the one that disappears into the background. With SwiftData, we spend our time on clipboard features, not database plumbing. That’s exactly what we wanted.
Built on SwiftData. Built to last.
QuietClip uses SwiftData for fast, reliable clipboard history. Up to 1,000 items, searchable instantly, stored locally. Free to start, $8.99 once for Pro.