{"id":52383,"date":"2026-06-23T15:14:57","date_gmt":"2026-06-23T19:14:57","guid":{"rendered":"https:\/\/mjtsai.com\/blog\/?p=52383"},"modified":"2026-06-23T15:14:57","modified_gmt":"2026-06-23T19:14:57","slug":"swiftdata-in-appleos-27","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2026\/06\/23\/swiftdata-in-appleos-27\/","title":{"rendered":"SwiftData in appleOS 27"},"content":{"rendered":"<p><a href=\"https:\/\/developer.apple.com\/documentation\/updates\/swiftdata\">SwiftData updates<\/a>:<\/p>\n<blockquote cite=\"https:\/\/developer.apple.com\/documentation\/updates\/swiftdata\">\n<p>Section your query results by creating your query with a macro that takes a <code>sectionBy<\/code> parameter, as listed on the <a href=\"https:\/\/developer.apple.com\/documentation\/SwiftData\/AdditionalQueryMacros\">Additional query macros<\/a> page.<\/p>\n<p>Use types that conform to <a href=\"https:\/\/developer.apple.com\/documentation\/Swift\/Codable\"><code>Codable<\/code><\/a> in a model, including types you don&rsquo;t control directly, by using the  <a href=\"https:\/\/developer.apple.com\/documentation\/SwiftData\/Schema\/Attribute\/Option\/codable\"><code>codable<\/code><\/a> option for <a href=\"https:\/\/developer.apple.com\/documentation\/SwiftData\/Schema\/Attribute\"><code>Schema.Attribute<\/code><\/a>.<\/p>\n<p>Receive real-time updates to models that match specified fetch criteria by using the <a href=\"https:\/\/developer.apple.com\/documentation\/SwiftData\/ResultsObserver\"><code>ResultsObserver<\/code><\/a> type.<\/p>\n<p>Observe remote model changes with the <a href=\"https:\/\/developer.apple.com\/documentation\/SwiftData\/HistoryObserver\"><code>HistoryObserver<\/code><\/a> type.<\/p>\n<\/blockquote>\n\n<p><a href=\"https:\/\/developer.apple.com\/videos\/play\/wwdc2026\/274\/\">What&rsquo;s new in SwiftData<\/a>:<\/p>\n<blockquote cite=\"https:\/\/developer.apple.com\/videos\/play\/wwdc2026\/274\/\">\n<p>Discover the latest enhancements to SwiftData. We&rsquo;ll show you how to persist custom and third-party types using <code>Codable<\/code>, and group fetched data into sections in your SwiftUI app. We&rsquo;ll also explore how to observe data store changes anywhere else using <code>ResultsObserver<\/code> and <code>HistoryObserver<\/code>, giving you the flexibility to drive powerful state objects and react precisely to model updates.<\/p>\n<\/blockquote>\n\n<p><a href=\"https:\/\/mjtsai.com\/blog\/2025\/06\/19\/swiftdata-and-core-data-at-wwdc25\/\">Again<\/a>, there seems to be nothing new in Core Data this year, nor any communication about it. There&rsquo;s still no interoperability for object IDs. The SwiftData changes seem fine but don&rsquo;t really address the new framework&rsquo;s deficiencies relative to Core Data. It seems like there are still basic problems with threading. I just don&rsquo;t understand how Apple is deciding what to prioritize with this framework.<\/p>\n\n<p>With SwiftUI, the bones seem questionable, but at least we can see that Apple is full steam ahead, with substantial progress to address limitations and pain points. SwiftData seemed to have better bones and is much less ambitious. Getting it right seemed like just a matter of follow through. But, for some inexplicable reason, it seems to lack the resources and\/or urgency to reach its potential. And even though SwiftUI is clearly the chosen one, AppKit remains in development. Meanwhile, Core Data seems to be abandoned, even though SwiftData feels more like a side quest than a genuine attempt to supplant it.<\/p>\n\n<p>The implicit message, for those who have build the core of their app on top of Apple&rsquo;s old persistence framework, seems to be that Apple is not looking out for their needs. Core Data will surely get maintenance to the extent that Apple&rsquo;s own apps need it, but there&rsquo;s no evidence of a future or even a migration plan. The answer, I guess, is third-party frameworks, but that&rsquo;s not an easy migration, either, since none is even as close a match as SwiftData.<\/p>\n\n<p><a href=\"https:\/\/developer.apple.com\/videos\/play\/wwdc2026\/275\/\">Add persistence with SwiftData<\/a>:<\/p>\n<blockquote cite=\"https:\/\/developer.apple.com\/videos\/play\/wwdc2026\/275\/\">\n<p>Experience SwiftData in action as we add persistence to an existing app. We&rsquo;ll show you how to define your data models and seamlessly integrate persistent data with SwiftUI. You&rsquo;ll also learn foundational skills for managing your app&rsquo;s state using this expressive, declarative API.<\/p>\n<\/blockquote>\n\n<p><a href=\"https:\/\/developer.apple.com\/videos\/play\/wwdc2026\/8017\/\">SwiftData Group Lab<\/a>:<\/p>\n<blockquote cite=\"https:\/\/developer.apple.com\/videos\/play\/wwdc2026\/8017\/\">\n<p>Join us online for a deep dive into WWDC26 with Apple engineers and designers to ask questions, get advice, and follow the discussion about the week&rsquo;s biggest SwiftData announcements.<\/p>\n<\/blockquote>\n\n<p><a href=\"https:\/\/developer.apple.com\/documentation\/macos-release-notes\/macos-27-release-notes\">macOS Golden Gate 27 Beta Release Notes<\/a>:<\/p>\n<blockquote cite=\"https:\/\/developer.apple.com\/documentation\/macos-release-notes\/macos-27-release-notes\">\n<p>Fixed: You might experience a deadlock for <code>@Query<\/code> when saving a <code>ModelContext<\/code> on a background actor while scheduling new async tasks for a <code>ModelActor<\/code>.<\/p>\n<\/blockquote>\n\n<p><a href=\"https:\/\/x.com\/twostraws\/status\/2064060539228311593\">Paul Hudson<\/a>:<\/p>\n<blockquote cite=\"https:\/\/x.com\/twostraws\/status\/2064060539228311593\">\n<p>I am so pleased to say these words: IT IS A BIG YEAR FOR SWIFTDATA! &#x1F389;<\/p>\n<\/blockquote>\n\n<p><a href=\"https:\/\/azamsharp.com\/2026\/06\/12\/whats-new-in-swiftdata.html\">Mohammad Azam<\/a>:<\/p>\n<blockquote cite=\"https:\/\/azamsharp.com\/2026\/06\/12\/whats-new-in-swiftdata.html\">\n<p>SwiftData predicates can now work directly with enum values, resulting in cleaner models and simpler query code.<\/p>\n<p>[&#8230;]<\/p>\n<p>In iOS 27, Apple introduced support for compound predicates through the <code>Predicate(all:)<\/code> and <code>Predicate(any:)<\/code> initializers, making it easier to build queries dynamically based on user input.<\/p>\n<\/blockquote>\n\n<p>I&rsquo;m not sure why that took so long.<\/p>\n\n<blockquote cite=\"https:\/\/azamsharp.com\/2026\/06\/12\/whats-new-in-swiftdata.html\">\n<p>The framework is gradually moving beyond simple demos and becoming easier to use in larger, more sophisticated projects.<\/p>\n<p>[&#8230;]<\/p>\n<p>iOS 27 is the first release where many of the framework&rsquo;s early rough edges have started to disappear.<\/p>\n<\/blockquote>\n\n<p><a href=\"https:\/\/mastodon.social\/@mattiem\/116716178659490404\">Matt Massicotte<\/a>:<\/p>\n<blockquote cite=\"https:\/\/mastodon.social\/@mattiem\/116716178659490404\">\n<p>Results of my now-yearly check to see if SwiftData&rsquo;s <code>ModelActor<\/code> continues to sometimes run code on the main thread: yes it does<\/p>\n<\/blockquote>\n\n<p><a href=\"https:\/\/weekly.fatbobman.com\/p\/fatbobmans-swift-weekly-139\">Fatbobman<\/a>:<\/p>\n<blockquote cite=\"https:\/\/weekly.fatbobman.com\/p\/fatbobmans-swift-weekly-139\">\n<p>Compared with <code>@Query<\/code> gaining support for section fetches, and <code>ResultsObserver<\/code> enabling observation of query result changes outside views, I am more interested in <code>@Attribute(.codable)<\/code>. It provides a clearer storage intent and gives developers a way to avoid falling into the black box of composition.<\/p>\n<p>Of course, <code>@Attribute(.codable)<\/code> is not a silver bullet. It is more like a clearly defined escape hatch SwiftData provides for opaque <code>Codable<\/code> types: suitable for storing external types that you cannot model yourself, but still genuinely need to persist. The cost is that this content cannot participate in SwiftData&rsquo;s predicate, sort, or migration awareness. Precisely for this reason, its value lies not in being &ldquo;more powerful,&rdquo; but in being &ldquo;more explicit.&rdquo;<\/p>\n<p>However, SwiftData still does not provide cloud syncing for public \/ shared data, nor have I seen a clearer signal of performance improvements. These issues will continue to limit its adoption. For many developers, SwiftData this year feels more like it is filling key gaps rather than making a leap significant enough to fundamentally change confidence in it.<\/p>\n<\/blockquote>\n\n<p><a href=\"https:\/\/mastodon.social\/@helge\/116716973051333446\">Helge He&szlig;<\/a>:<\/p>\n<blockquote cite=\"https:\/\/mastodon.social\/@helge\/116716973051333446\">\n<p><code>Codable<\/code> types in SwiftData seem pretty lame given that SQLite absolutely does have JSON support and does support queries on it?<\/p>\n<p>But the funnier thing in the MKMapItem.Identifier example is that <code>MKMapItem.Identifier<\/code> is a <code>RawRepresentable==String<\/code>, so it could actually be stored as a <code>String<\/code> in the store.<\/p>\n<\/blockquote>\n\n<p>Previously:<\/p>\n<ul>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2026\/06\/17\/wwdc-2026-links\/\">WWDC 2026 Links<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2025\/12\/18\/batch-delete-in-swiftdata\/\">Batch Delete in SwiftData<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2025\/08\/26\/swiftdatas-modelactor-is-just-weird\/\">SwiftData&rsquo;s ModelActor Is Just Weird<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2025\/08\/12\/swiftdata-runtime\/\">SwiftData Runtime<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2025\/07\/23\/ways-swiftdatas-modelcontainer-can-error-on-creation\/\">Ways SwiftData&rsquo;s ModelContainer Can Error on Creation<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2025\/06\/19\/swiftdata-and-core-data-at-wwdc25\/\">SwiftData and Core Data at WWDC25<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2024\/10\/16\/returning-to-core-data\/\">Returning to Core Data<\/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<\/ul>","protected":false},"excerpt":{"rendered":"<p>SwiftData updates: Section your query results by creating your query with a macro that takes a sectionBy parameter, as listed on the Additional query macros page. Use types that conform to Codable in a model, including types you don&rsquo;t control directly, by using the codable option for Schema.Attribute. Receive real-time updates to models that match [&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":"2026-06-23T19:15:03Z","apple_news_api_id":"28f65f4c-a17b-4977-b001-92659a344f68","apple_news_api_modified_at":"2026-06-23T19:15:03Z","apple_news_api_revision":"AAAAAAAAAAD\/\/\/\/\/\/\/\/\/\/w==","apple_news_api_share_url":"https:\/\/apple.news\/AKPZfTKF7SXewAZJlmjRPaA","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,2887,30,2784,71,1774,2200,901,2404],"class_list":["post-52383","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-coredata","tag-ios","tag-ios-27","tag-mac","tag-macos-27","tag-programming","tag-swift-codable","tag-swift-concurrency","tag-swift-programming-language","tag-swiftdata"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/52383","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=52383"}],"version-history":[{"count":1,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/52383\/revisions"}],"predecessor-version":[{"id":52384,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/52383\/revisions\/52384"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=52383"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=52383"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=52383"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}