{"id":45397,"date":"2024-10-16T14:05:21","date_gmt":"2024-10-16T18:05:21","guid":{"rendered":"https:\/\/mjtsai.com\/blog\/?p=45397"},"modified":"2025-03-17T11:29:09","modified_gmt":"2025-03-17T15:29:09","slug":"returning-to-core-data","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2024\/10\/16\/returning-to-core-data\/","title":{"rendered":"Returning to Core Data"},"content":{"rendered":"<p><a href=\"https:\/\/fatbobman.com\/en\/posts\/reinventing-core-data-development-with-swiftdata-principles\/\">Fatbobman<\/a>:<\/p>\n<blockquote cite=\"https:\/\/fatbobman.com\/en\/posts\/reinventing-core-data-development-with-swiftdata-principles\/\">\n<p>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&mdash;a direction undoubtedly correct&mdash;it seems that the significant changes led to considerable impact on the new version&rsquo;s stability.<\/p>\n<p>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&rsquo;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.<\/p>\n<p>[&#8230;]<\/p>\n<p>SwiftData&rsquo;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.<\/p>\n<p>[&#8230;]<\/p>\n<p>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.<\/p>\n<\/blockquote>\n<p>Personally, I think the sweet spot is using mature frameworks like Core Data and Cocoa from Swift. Apple hasn&rsquo;t done as much as I&rsquo;d hoped to make this ergonomic, but there&rsquo;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 <em>plus<\/em> the <code>context<\/code>  as arguments.<\/p>\n\n<p>Previously:<\/p>\n<ul>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2024\/09\/27\/nsmanagedobjectid-and-persistentidentifier\/\">NSManagedObjectID and PersistentIdentifier<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2024\/07\/26\/swiftdata-and-core-data-at-wwdc24\/\">SwiftData and Core Data at WWDC24<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2024\/06\/04\/swiftdata-issues-in-macos-14-and-ios-17\/\">SwiftData Issues in macOS 14 and iOS 17<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2024\/05\/28\/dynamic-swift-predicates-in-macos-14-and-ios-17\/\">Dynamic Swift Predicates in macOS 14 and iOS 17<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2024\/04\/23\/elegant-concurrency-operations-in-core-data\/\">Elegant Concurrency Operations in Core Data<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2024\/01\/09\/swiftdata-fetching-pending-changes\/\">SwiftData Fetching Pending Changes<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2023\/10\/02\/model-for-coredata\/\">@Model for CoreData<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2023\/06\/12\/swiftdata\/\">SwiftData<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2021\/03\/31\/making-nsfetchrequest-fetchbatchsize-work-with-swift\/\">Making NSFetchRequest.fetchBatchSize Work With Swift<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2020\/05\/22\/marking-unused-required-swift-initializers-as-unavailable\/\">Marking Unused Required Swift Initializers As Unavailable<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2018\/11\/29\/effective-core-data-with-swift\/\">Effective Core Data With Swift<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2018\/02\/20\/when-swift-makes-you-use-throws-instead-of-rethrows\/\">When Swift Makes You Use &ldquo;throws&rdquo; Instead of &ldquo;rethrows&rdquo;<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2016\/06\/24\/modern-core-data-with-swift\/\">Modern Core Data With Swift<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2016\/04\/21\/core-data-type-safety-with-swift\/\">Core Data Type Safety With Swift<\/a><\/li>\n<\/ul>\n\n<p id=\"returning-to-core-data-update-2024-10-17\">Update (2024-10-17): See also: <a href=\"https:\/\/news.ycombinator.com\/item?id=41858099\">Hacker News<\/a>.<\/p>\n\n<p id=\"returning-to-core-data-update-2024-10-18\">Update (2024-10-18): <a href=\"https:\/\/x.com\/steipete\/status\/1847047648949518700\">Peter Steinberger<\/a>:<\/p>\n<blockquote cite=\"https:\/\/x.com\/steipete\/status\/1847047648949518700\">\n<p>So a year in, SwiftData is now <em>worse<\/em> than it was in the initial release? \nHonestly, don&rsquo;t trust Apple there, use something open source that is properly maintained and has tests, like GRDB.<\/p>\n<\/blockquote>\n\n<p id=\"returning-to-core-data-update-2024-11-08\">Update (2024-11-08): See also this thread from <a href=\"https:\/\/mastodon.social\/@stroughtonsmith\/113443217616497845\">Steve Troughton-Smith<\/a>:<\/p>\n<blockquote cite=\"https:\/\/mastodon.social\/@stroughtonsmith\/113443217616497845\"><p>What&rsquo;s the consensus on SwiftData? Are any big apps using it? Does it have blockers or major issues to worry about?<\/p><\/blockquote>\n\n<p><a href=\"https:\/\/mastodon.social\/@uhl\/113447991315155352\">Uhl Albert<\/a>:<\/p>\n<blockquote cite=\"https:\/\/mastodon.social\/@uhl\/113447991315155352\"><p>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 &ldquo;try it in iOS 18 beta.&rdquo;<\/p><p>I did, and while there was much less lag, memory usage was still double that of CoreData.<\/p><p>Here&rsquo;s my <a href=\"https:\/\/developer.apple.com\/forums\/thread\/762330\">Apple Dev Forum thread<\/a> with more details and links to the test projects.<\/p><\/blockquote>\n\n<p id=\"returning-to-core-data-update-2025-01-13\">Update (2025-01-13): <a href=\"https:\/\/techhub.social\/@JTostitos\/113796298978103393\">Jonathan Tostitos<\/a>:<\/p>\n<blockquote cite=\"https:\/\/techhub.social\/@JTostitos\/113796298978103393\"><p>Has anyone else used #SwiftData based DocumentGroup in #SwiftUI?<\/p><p>It is pretty convenient compared to rolling your own storage solution. I&rsquo;m able to create a custom file extension and I can keep all SwiftData properties non-optional which cannot be done with CloudKit.<\/p><p>However, I have had it happen a couple times where the file will refuse to open on #iPadOS after having it opened on #macOS, which is a cause for concern because I cannot afford data loss. Especially since it doesn&rsquo;t appear to be possible to create backups of the file, or prevent it from being opened on more than one device, etc.<\/p><\/blockquote>\n\n<p id=\"returning-to-core-data-update-2025-02-11\">Update (2025-02-11): <a href=\"https:\/\/x.com\/vatsal_manot\/status\/1886907605114913031\">Vatsal Manot<\/a>:<\/p>\n<blockquote cite=\"https:\/\/x.com\/vatsal_manot\/status\/1886907605114913031\"><p>Random crashes. A lot fixed in iOS 18, but 0 workarounds for older versions.<\/p><p>Yet again, another fantastic set of APIs botched by poor QA and lack of proactive bug disclosure. Faith in its stability has been eroded for most developers that I know.<\/p><\/blockquote>\n\n<p id=\"returning-to-core-data-update-2025-02-26\">Update (2025-02-26): <a href=\"https:\/\/pado.name\/blog\/2025\/02\/swiftdata-query\/\">Geoff Pado<\/a>:<\/p>\n<blockquote cite=\"https:\/\/pado.name\/blog\/2025\/02\/swiftdata-query\/\"><p>Over the year-and-change since its release, I&rsquo;ve watched several developer friends abandon SwiftData in frustration, finding it buggy and unreliable. However, I&rsquo;ve found it to be a key part of my app&rsquo;s architecture, and I can&rsquo;t imagine going back. Is it that I&rsquo;m a 10x developer, and everyone else just needs to git gud? &#x1F914; No, of course not. But I think my experience, compared to others&rsquo;, comes down to one key difference: I completely avoided using <code>@Query<\/code>, and <strong>everyone else should, too<\/strong>.<\/p><\/blockquote>\n\n<p id=\"returning-to-core-data-update-2025-03-17\">Update (2025-03-17): <a href=\"https:\/\/fatbobman.com\/en\/posts\/key-considerations-before-using-swiftdata\/\">Fatbobman<\/a>:<\/p>\n<blockquote cite=\"https:\/\/fatbobman.com\/en\/posts\/key-considerations-before-using-swiftdata\/\"><p>Compared to Core Data, SwiftData currently lacks some functionalities, primarily in the following aspects[&#8230;] Additionally, given SwiftData&rsquo;s design goals, many of the fine-grained controls over data objects and contexts available in Core Data may never be supported in SwiftData.<\/p><p>[&#8230;]<\/p><p>Besides uncontrollable factors such as system bugs, the following recommendations can help improve the stability of your SwiftData projects[&#8230;]<\/p><p>[&#8230;]<\/p><p>Therefore, it is recommended to use the <code>@ModelActor<\/code> macro to implement <a href=\"\/en\/posts\/concurret-programming-in-swiftdata\/\">concurrent operations<\/a>.<\/p><p>[&#8230;]<\/p><p>Since SwiftData creates objects first and then explicitly inserts them into a context, do not assign relationship properties in the model&rsquo;s initializer.<\/p><p>[&#8230;]<\/p><p>The seemingly &ldquo;easy-to-learn and easy-to-use&rdquo; nature of SwiftData can easily mislead beginners into hastily adopting it in production environments. However, such rushed decisions often lead to unforeseen consequences: only when compatibility issues or stability crises emerge do developers realize their understanding of the framework is far from adequate.<\/p><\/blockquote>\n\n<p><a href=\"https:\/\/mastodon.social\/@fatbobman\/114149425229092565\">Jan Ekholm<\/a>:<\/p>\n<blockquote cite=\"https:\/\/mastodon.social\/@fatbobman\/114149425229092565\"><p>Can it be used for real projects? I have not heard of anyone that hasn&rsquo;t run into showstoppers and\/or missing features after a while.<\/p><\/blockquote>\n\n<p><a href=\"https:\/\/mastodon.social\/@davedelong\/114158385111319207\">Dave DeLong<\/a>:<\/p>\n<blockquote cite=\"https:\/\/mastodon.social\/@davedelong\/114158385111319207\"><p>I&rsquo;d rather just use Core Data directly if that&rsquo;s really the best option.<\/p><\/blockquote>","protected":false},"excerpt":{"rendered":"<p>Fatbobman: 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&mdash;a direction undoubtedly correct&mdash;it seems that the significant changes led [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"apple_news_api_created_at":"2024-10-16T18:05:24Z","apple_news_api_id":"815e5729-98ff-476e-9fb4-a3b4e1e591a6","apple_news_api_modified_at":"2025-03-17T15:29:11Z","apple_news_api_revision":"AAAAAAAAAAAAAAAAAAAABw==","apple_news_api_share_url":"https:\/\/apple.news\/AgV5XKZj_R26ftKO04eWRpg","apple_news_coverimage":0,"apple_news_coverimage_caption":"","apple_news_is_hidden":false,"apple_news_is_paid":false,"apple_news_is_preview":false,"apple_news_is_sponsored":false,"apple_news_maturity_rating":"","apple_news_metadata":"\"\"","apple_news_pullquote":"","apple_news_pullquote_position":"","apple_news_slug":"","apple_news_sections":"\"\"","apple_news_suppress_video_url":false,"apple_news_use_image_component":false,"footnotes":""},"categories":[4],"tags":[109,31,2586,30,2598,71,2200,901,2404],"class_list":["post-45397","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-coredata","tag-ios","tag-ios-18","tag-mac","tag-macos-15-sequoia","tag-programming","tag-swift-concurrency","tag-swift-programming-language","tag-swiftdata"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/45397","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/comments?post=45397"}],"version-history":[{"count":9,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/45397\/revisions"}],"predecessor-version":[{"id":47097,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/45397\/revisions\/47097"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=45397"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=45397"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=45397"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}