Returning to Core Data
However, the release of iOS 18 cast a shadow over this beautiful vision. A year after its first appearance, SwiftData underwent a major underlying refactoring. Although this adjustment was aimed at shifting from a strong coupling with Core Data to supporting more flexible multi-persistence solutions—a direction undoubtedly correct—it seems that the significant changes led to considerable impact on the new version’s stability.
Disappointingly, a large amount of SwiftData code that ran well on iOS 17 encountered various problems in the new version. For a data persistence framework that shoulders heavy responsibilities, these issues are undoubtedly fatal. What’s more worrying is that the complexity of these problems means they may not be thoroughly resolved in the short term. It is foreseeable that throughout the iOS 18 cycle, developers choosing to use SwiftData will have to continuously grapple with these challenges.
[…]
SwiftData’s performance on iOS 18 put me in a dilemma. For an application centered on data management, stability and reliability are non-negotiable. After repeated deliberation, I had to make a tough decision: abandon the thousands of lines of SwiftData code I had completed and return to Core Data.
[…]
When rebuilding the Core Data project, I decided to integrate the modern thinking I learned from SwiftData, using a more innovative approach to harness this time-tested framework.
Personally, I think the sweet spot is using mature frameworks like Core Data and Cocoa from Swift. Apple hasn’t done as much as I’d hoped to make this ergonomic, but there’s a lot you can do yourself. I actually go further than the example here and make all managed object initializers take the required attributes plus the context
as arguments.
Previously:
- NSManagedObjectID and PersistentIdentifier
- SwiftData and Core Data at WWDC24
- SwiftData Issues in macOS 14 and iOS 17
- Dynamic Swift Predicates in macOS 14 and iOS 17
- Elegant Concurrency Operations in Core Data
- SwiftData Fetching Pending Changes
- @Model for CoreData
- SwiftData
- Making NSFetchRequest.fetchBatchSize Work With Swift
- Marking Unused Required Swift Initializers As Unavailable
- Effective Core Data With Swift
- When Swift Makes You Use “throws” Instead of “rethrows”
- Modern Core Data With Swift
- Core Data Type Safety With Swift
Update (2024-10-17): See also: Hacker News.
Update (2024-10-18): Peter Steinberger:
So a year in, SwiftData is now worse than it was in the initial release? Honestly, don’t trust Apple there, use something open source that is properly maintained and has tests, like GRDB.
Update (2024-11-08): See also this thread from Steve Troughton-Smith:
What’s the consensus on SwiftData? Are any big apps using it? Does it have blockers or major issues to worry about?
SwiftData performance was so bad on iOS 17 that I switched my app to CoreData to make it usable. I submitted two test projects to Apple code-level support. They acknowledged the problem and advised me to “try it in iOS 18 beta.”
I did, and while there was much less lag, memory usage was still double that of CoreData.
Here’s my Apple Dev Forum thread with more details and links to the test projects.
2 Comments RSS · Twitter · Mastodon
Another example of why it is sometimes best to stay at least 3 years behind what Apple is introducing.
This should be adequate time to see how a new technology has matured over multiple releases, if Apple is committed to ongoing improvement and fixes, and if it is worth investing your own development effort into utilising the technology.
Otherwise, as always, you need to be ready to play the role of the frustrated beta tester.
This is not always feasible from a business perspective but can be a good rule of thumbs.
Apple Vision Pro support is a good example of this at the moment.
I have used CoreData many a time, but never SwiftData.
At this point, I'm not sure what they're really doing or why. NoSQL is the hype, they should have been ripping off GraphQL and making a first-party subsystem, not trying to invent/re-implement active record for the third time. For everything else/smaller, a first-party key-value store that persists out to would suffice.