Alle Artikel
30. September 2026

SwiftData vs Core Data: choosing a persistence layer in 2026

SwiftData fits most new iOS 17+ apps. Core Data still wins for older OS support, SQL-layer aggregate queries, and existing CloudKit setups.

For a new app targeting iOS 17 or later, pick SwiftData. If you need to support an older OS, lean on SQL-layer aggregate queries, or extend an existing Core Data and CloudKit setup, Core Data is still the better call, often running alongside SwiftData rather than instead of it. Here's what SwiftData actually changes, how the two frameworks coexist, and the specific tradeoffs that should drive your pick.

What SwiftData is and why the comparison matters

SwiftData is Apple's Swift-native persistence framework. It's built on Core Data's underlying store architecture, not a replacement built from scratch. You declare models with the @Model macro, own the store configuration through ModelContainer, track in-memory changes with ModelContext, fetch and observe results in SwiftUI views with @Query, and filter with the type-safe Predicate syntax instead of NSPredicate strings. The framework cuts a real amount of boilerplate compared to a hand-rolled Core Data stack, especially for a small to mid-size app's model layer.

The comparison starts, and often ends, with a platform floor. SwiftData requires iOS 17, macOS 14, tvOS 17, or watchOS 10 at minimum. Support an older OS and SwiftData simply isn't on the table yet; Core Data remains the only supported path. Teams shipping SwiftUI apps with confidence tend to make this call at the very start of a project, since retrofitting a persistence layer after a year of shipped features costs far more than picking correctly on day one.

The day-to-day developer experience is where the difference really shows up. A Core Data model needs an .xcdatamodeld file, generated NSManagedObject subclasses, and a persistent container set up by hand before the first fetch even runs. A SwiftData model is just a plain Swift class with an @Model macro on it. For a small app, that difference can mean shipping the first working screen in an afternoon instead of a day. For a large app with hundreds of entities and years of migrations already on file, that simplicity matters a lot less than the operational history a Core Data stack already has behind it.

How SwiftData and Core Data work together in practice

Apple's own guidance for adopting SwiftData in a Core Data app treats this as an incremental migration, not a rewrite. SwiftData can point at the same SQLite store a Core Data stack already uses, so a team can move models over one at a time while the rest of the app keeps working against the existing store. Apple introduced this pattern at WWDC 2023's migration session, and every later piece of guidance, including the 2026 coexistence documentation, builds on that same foundation.

WWDC 2026 added two notable pieces to SwiftData. First: ResultsObserver, the non-SwiftUI equivalent of the @Query property wrapper. It fetches from a SwiftData store and observes it for changes using Swift's Observation framework, with the same filtering, sorting, and sectioning primitives @Query already supports, but it works from a view model or any context that isn't tied to a SwiftUI view's lifecycle. That matters for anything running outside a view tree, like a WidgetKit or Live Activity update handler that needs to read the store without waiting on a SwiftUI render pass. Second: .codable model attributes, which delegate serialization to the type itself and store the encoded representation directly, cutting schema-inference overhead for complex nested types. The tradeoff is that a .codable attribute's contents are opaque to SwiftData's storage layer, so you can't use one inside a Predicate for filtering or as a sort key.

Tradeoffs and edge cases

Two concrete feature gaps still favor Core Data as of 2026. History tracking is the first: SwiftData does it automatically, while Core Data requires manually setting NSPersistentHistoryTrackingKey. So SwiftData actually wins there for apps that need change tracking out of the box. Aggregate queries run the other way. Core Data's NSExpression computes sums, averages, counts, and min or max values directly at the SQL layer without pulling records into memory, and SwiftData has no direct equivalent. The same aggregate math currently means fetching the relevant rows into memory first. Many teams land on a hybrid pattern: adopt SwiftData for the model layer generally, and keep a narrow Core Data escape hatch against that same underlying store specifically for NSExpression-based aggregate fetches, so you're not maintaining two separate databases.

Coexistence gets more complicated once CloudKit sync enters the picture. An Apple DTS engineer, responding to a developer's proposal to run fully separate Core Data and SwiftData stores with separate CloudKit containers, confirmed the split is feasible in principle, but flagged that most real apps have data relationships crossing both stores, which means writing bridging code to move data across that boundary. For CloudKit-synced apps specifically, that same guidance points toward consolidating on a single Core Data-backed private database rather than maintaining two containers, since CloudKit sharing already runs through a private database no matter which framework wrote the record. Teams mid-way through a Swift 6 strict concurrency migration should weigh this carefully before stacking a second, unrelated migration on top of the first. Sequencing the two projects usually costs less than running them in parallel.

Testing and previews deserve a specific mention too. A ModelContainer configured with an in-memory store takes a few lines of code, and SwiftUI previews can boot against that in-memory container without touching a real database file. That's a smoother loop than standing up an in-memory NSPersistentContainer for the same purpose. It's a small win on its own, but on a team running dozens of previews and unit tests a day, it adds up to real time back.

Frequently asked questions

Can SwiftData and Core Data run in the same app?

Yes. Apple documents this as a supported path: SwiftData sits on Core Data's store format, so a team can adopt SwiftData for most models while dropping into Core Data against the same store for capabilities SwiftData doesn't cover, such as NSExpression aggregate queries.

What is the minimum iOS version for SwiftData?

SwiftData requires iOS 17, macOS 14, tvOS 17, or watchOS 10 or later. Apps supporting older OS versions must stay on Core Data or maintain a Core Data fallback path.

Does SwiftData support the same aggregate queries as Core Data?

Not directly. Core Data's NSExpression computes sums, averages, counts, and min or max at the SQL layer without loading records into memory. SwiftData has no direct equivalent as of 2026, so aggregate math requires fetching data into memory first, or dropping into Core Data against the shared store for that specific query.

What is new in SwiftData for 2026?

WWDC 2026 added ResultsObserver, the non-SwiftUI equivalent of the @Query property wrapper for view models and other non-view code, and .codable model attributes that delegate serialization to the type itself, though those attributes can't be used in predicates or sort keys.

Conclusion

The decision comes down to a short checklist, not a general preference. New app, iOS 17 or later as the deployment floor, no heavy reliance on SQL-layer aggregates: SwiftData by default. Existing Core Data app, older OS support to maintain, or an established CloudKit setup you don't want to re-architect: stay on Core Data, or migrate incrementally using Apple's documented coexistence path. It's the same build versus extend judgment call we make on most iOS engagements at Kallos Labs, and the answer is almost always specific to the app in front of you, not a rule that applies everywhere.