Friday, July 26, 2024

SwiftData and Core Data at WWDC24

What’s new in SwiftData:

SwiftData makes it easy to add persistence to your app with its expressive, declarative API. Learn about refinements to SwiftData, including compound uniqueness constraints, faster queries with #Index, queries in Xcode previews, and rich predicate expressions. Join us to explore how you can use all of these features to express richer models and improve performance in your app.

[…]

You can use the new #Unique macro to tell SwiftData which combinations of your model’s properties must always remain unique in the model data. When two model instances share the same unique values, SwiftData will perform an upsert on collision with an existing model!

It seems there is still no way to control the merge policy.

New in iOS 18 is the ability to use Foundation’s new #Expression macro to build complex predicates easily! Expressions allow for reference values that do not produce true or false but instead allow for arbitrary types.

Create a custom data store with SwiftData:

Combine the power of SwiftData’s expressive, declarative modeling API with your own persistence backend. Learn how to build a custom data store and explore how to progressively add persistence features in your app.

Track model changes with SwiftData history:

Reveal the history of your model’s changes with SwiftData! Use the history API to understand when data store changes occurred, and learn how to use this information to build features like remote server sync and out-of-process change handing in your app. We’ll also cover how you can build support for the history API into a custom data store.

See also: the SwiftData documentation and updates.

I was not impressed with the introduction of SwiftData last year, and this year was also a disappointment. It seems like they are working on the wrong things and not communicating their vision for the future of SwiftData and how it will work with (or supplant) Core Data. It’s not clear whether this is a strategy and execution problem or primarily a communication problem, but it is leaving me unsettled.

Last year, SwiftData was very buggy and incomplete. This year, they didn’t talk about fixing the basics but rather about advanced and somewhat niche features like custom stores and history tracking. Last year, there was no integration between SwiftData and Core Data identifiers and predicates. There still seems to be none. The only mention of Core Data was that if you’re using Core Data’s persistent history you can now migrate to SwiftData history. There were no Core Data sessions at WWDC 2024.

So it remains unclear whether it’s even planned for SwiftData to be able to do the things that Core Data can. Is this going to be like SwiftUI where five years later they are still reimplementing features the previous framework has had for decades? It’s also unclear whether Core Data even has a future. Last year was encouraging in that both frameworks got equivalent new features at the same time. This year, Core Data got nothing, even though there’s a long list of outstanding feature requests, limitations, and bugs. Is this year an aberration? Or is Core Data in maintenance mode while they focus on SwiftData? It really does not feel good to have multiple apps and 20 years of code built on a framework that Apple isn’t talking about.

The point of building on system frameworks is that they’re in theory better supported than random open source projects. But now the future is uncertain, and it’s closed-source so that no one else can make the fixes or improvements that Apple won’t. I can’t rewrite my Core Data code in SwiftData because it’s so limited. Even if there are major improvements next year, they will be locked to macOS 16 and later, so it will be a long time before I can deploy code that uses them. At least right now, it’s not worth rewriting my code for a third-party framework. Core Data isn’t announced dead yet, and many other apps use it, so hopefully it’s safe to assume that Apple won’t let it break too badly. But if I were starting a new app today I would seriously consider whether it makes sense to be on the Apple train. There are some interesting alternatives such as GRDB, Lighter, and Blackbird.

Donny Wals:

It feels like Apple wanted to do more with SwiftData but they ran out of time. Surely being able to write your own persistence layer wasn’t the one thing they really wanted to ship, right?

There’s so much that developers were hoping for this year but we didn’t get any of it.

Makes me wonder whether the plan was to replace Core Data entirely and go from there but they couldn’t get it done so they gave us this instead?

Gwendal Roué:

I mostly see people hitting walls with SwiftData (limited support for non-optional relationships and ordered relationships, predicates that won’t compile, no dynamic predicate, change reactivity that does not work, etc.) And I’m all but charmed by its mutable model classes anyway. Maybe it would be interesting to have a GRDB store, so that one can workaround SwiftData limitations with a robust database API. But then, why not use the robust API in the first place?

Donny Wals:

Sadly, none of these limitations are the result of Core Data not supporting them. They’re a result of SwiftData’s interface not exposing these features. So even if you ship a custom persistence layer you’re limited by what SwiftData supports. And that’s not much.

For now, SwiftData remains a framework that’s only useful for small, simple apps that don’t need much in terms of features.

Fatbobman:

The latest version of SwiftData was surprisingly impactful. Although it might seem that few features were added on the surface, the substantial underlying adjustments were revolutionary. Considering that SwiftData was only founded a year ago, such changes were particularly unexpected. Stability remains a challenge, as seen in the first test version, which may disappoint many developers who had high expectations for SwiftData. However, after in-depth analysis, I believe there is sound reasoning behind these significant adjustments. The new version of SwiftData has almost achieved decoupling from the Apple ecosystem, and once it adds an independent default storage implementation, it will have all the makings of a cross-platform open-source framework. While this is just my personal hope, given Apple’s increasingly open approach to the community, the potential for this transformation is significant. If realized, the current waiting and effort will undoubtedly be worthwhile.

Helge Heß:

What they apparently didn’t do is fix the actual issues it had, like missing Observation refreshes 🙃

dasdom:

Is SwiftData dead already?

SENTINELITE:

I picked up SwiftData last year for my app, & it’s been an excruciatingly painful experience. Cloud syncing doesn’t always work, duplicate entries, etc.

Things didn’t really improve this year, although some internal things did, because some bugs have been cleaned up.

But… I just feel lost. I need the foundation of the app to be working, so I can dive into other APIs (Widgets, shortcuts, etc), but it’s been an uphill battle.

Helge Heß:

Something disappointing in SwiftData is that it doesn’t make use of the static nature of the macro(s). The macro can’t see the full schema like Lighter does, but it could still statically generate a ton, e.g. a static snapshot struct for the backing data. Or predefined indices for quickly binding the snapshot to the SQLite API (or really any).

Instead we get custom backends. Is anyone going to use this, for anything? Maybe they’ll eventually release it as FOSS for server side?

Helge Heß:

IMO the ability to replace the backend is exactly the wrong direction to go 🤷‍♀️ (for an embedded persistence framework). Specific backends should have specific implementations of the SwiftData API, not yet another layer in between that does abstractions which likely won’t fly. Remember the LDAP EOAdapter…

SENTINELITE:

Adopting SwiftData’s new History stuff, causes my model(s) to crash, as you can’t query embedded structs. […] I’m THIS close to rewriting the back-end. Gah.

Jon Duenas:

Yeah, it’s just, credit where credit is due, adding CloudKit to SwiftData “just worked”. With bugs and crashes, sure. But barely any extra effort on the developer’s end to do the actual syncing.

I’m actually considering whether I should just move rolling my own backend with something like Firebase or Supabase and make local storage more of a cache than the source of truth.

Duncan Babbage:

Would love any leads on this: setting [Core Data’s] .fetchBatchSize causes entire collection to be immediately traversed [by SwiftUI].

With Core Data and AppKit there are several possible solutions. If you fetch whole objects, the batching “just works,” so long as you stick to one store and avoid converting the NSArray to a Swift Array. With multiple stores, or to save memory, it’s straightforward to just fetch the sorted IDs and bring the objects into memory as needed.

Previously:

Update (2024-07-29): Helge Heß:

SQLite.swift is really slow. If you want a popular good one, rather get GRDB. Neither provides what SwiftData has though, i.e. an EditingContext.

I do think the context is a useful feature—another reason I’ve liked Core Data.

When I need direct SQLite access, I’ve been using SQLite.swift because it seemed simpler and smaller than GRDB. It like it, but it is indeed very slow due to Swift and GCD overhead within the framework. I was able to 3x the query performance by making some minor changes to reduce overhead and by manually unpacking the result rows. Now nearly all the time is spent in SQLite itself.

Update (2024-07-31): Keith Harrison:

First the bad news, this [SwiftData Indexes are] an iOS 18 feature that does not back deploy to iOS 17.

[…]

Note the subtle difference between adding an index for the individual properties or a compound index (I can see myself getting this wrong)[…]

I don’t see how to index the entity column.

Update (2024-09-25): Fatbobman:

Compared to minor UI-level glitches, deeper crash issues have caught some developers off guard. Apps using SwiftData have seen a noticeable increase in crash frequency, undoubtedly disappointing many developers who had high hopes for the new framework. Even more surprising is that the fetchedProperties feature in Core Data on iOS 18 can also cause crashes—quite unexpected for a framework that’s known for its stability.

Update (2024-09-30): Chad Etzel:

well.. i’m trying to use SwiftData but the @Query wrapper spins the CPU 100%+ on the main thread… lots of other ppl reporting this .. seems very bad

7 Comments RSS · Twitter · Mastodon


More Swift hot garbage.

>So it remains unclear whether it’s even planned for SwiftData to be able to do the things that Core Data can. Is this going to be like SwiftUI where five years later they are still reimplementing features the previous framework has had for decades?

I think so, unless the managers responsible for making these decisions are shown the door (this is certainly possible, perhaps even likely).

>This year, Core Data got nothing, even though there’s a long list of outstanding feature requests, limitations, and bugs. Is this year an aberration? Or is Core Data in maintenance mode while they focus on SwiftData? It really does not feel good to have multiple apps and 20 years of code built on a framework that Apple isn’t talking about.

I feel exactly this way about AppKit and UIKit and I certainly don't have as much code as you.

The SwiftData story seems similar to SwiftUI. The pattern as it relates to all things Swift seems to be this:

1) They get you to migrate to their *wrapper* around the framework you were already using because this framework is EASY (supposedly).
2) They handicap your ability to workaround their bugs because the framework is closed source and everything is magic, but the magic often doesn't work.
3) They trickle in features the previous framework already provided, little by little, not over the course of months but YEARS.
4) A certain group of developers in the dev/blogger community praise Apple and clap like a bunch of seals.
5) The new framework is still not as good, a half decade later or so.

But just wait...it'll get there! In 30 years when we're all old and gray it'll be just as good as AppKit! Except by then there will be new kids with a new language and UI framework and they'll repeat this dumb shit all over again.


@ObjC4Lie There are certainly similarities, but the SwiftData situation seems worse to me. SwiftUI is more ambitious (whole new paradigm) and has the potential to be a big improvement if they execute well. Multi-platform support is also a big carrot. SwiftUI certainly has its issues, but they seem be making solid progress on important issues. Perhaps most importantly, they put at lot of effort into the interop so that you can adopt it incrementally, and you can use AppKit as an escape hatch for pieces that are missing. AppKit is still getting attention each year. I suppose there is a risk that the SwiftUI architecture is fundamentally wrong for certain things, but they can address that by leaving AppKit and UIKit around as the lower layer.

In contrast, SwiftData seems like a different skin for the same old idea. Like SwiftUI, it was limited out of the gate but also really buggy. And there is little interop.

The other obvious comparison is Cocoa and Carbon. I see that as more of SwiftUI-type story but done well (except for reneging on 64-bit). Cocoa was a big improvement, and it was much more capable and more mature out of the gate than SwiftUI. It had interop with Carbon. And Carbon continued to get improvements for a long time.


I am glad Michael are collecting all of these snippets and evidence of Swift problems as I have been sceptical of it since the beginning. Or from the Day I heard Chris Lattner said using Swift to replace Assembly to Javascript. Ten years since the first introduction of Swift, Five years of Swift UI and now Swift Data. All of these resources that went into it. They could have continue to mold and fix Objective-C along with fixing old frameworks. Instead we are pretty much reimplementating the same thing with different language.

The old Apple was very conservative in technology's choices and iteration. The new Apple had too much money and doesn't seems to know what to do with it.


Also adding had Scott Forstall is still in Apple we may not have have Swift and a lot of these Software directions problems.


@Ksec

> the Day I heard Chris Lattner said using Swift to replace Assembly to Javascript

I thought the same thing, however his quote went.

The idea that Swift was designed as an "end-language" for *every* domain (from systems, to servers, to embedded, to scripting, and oh hey, it works for apps, too!) is a catastrophic design fail. Lack of focus and thinking it would take over the world led to it becoming C+++.

ObjC is an App language. A first-tier App language should have been the focus. Not an academic type system. Not a personal quest to make everything a value-type or protocol. Not a checklist for feature parity with hotter languages designed for different things.

Swift is the F-35 of languages, built for "everything" (for all branches and all roles). Tons of hype and marketing, an occasionally nice demo, but the whole of the package is usually beat by purpose-built languages and tools. Like the F-35, Swift is the most-expensive tech transition in history and a maintenance disaster.

Whatever is designed to succeed Swift needs an extreme focus on Apps. Whoever runs it should ban C++ enjoyers and academics from having input (or perhaps do the opposite, where appropriate).

> had Scott Forstall is still in Apple we may not have have Swift and a lot of these Software directions problems

Swift began under Serlet, but it's interesting to think if an exec would have been able to foresee its overall harm and either kill it after a couple years or hard re-focus it. Lack of focus and this "take over the world" mantra is leading to over-complicated products and tools designed for no one (Vision Pro and CarPlay 2 come to mind).


> ObjC is an App language. A first-tier App language should have been the focus. Not an academic type system. Not a personal quest to make everything a value-type or protocol. Not a checklist for feature parity with hotter languages designed for different things.

@Hammer 100% agree. I think the dev community has put too much faith in Apple and never provided enough pushback as they go forward with the Swiftification and Josh Schaff-ing of their platforms.

Two things I think were happening at the same time:
1) Devs throw their hands up in the air and say things like "going against Apple's recommended guidelines is a losing proposition. Of course we moved to Swift). Technically speaking this isn't true as Objective-C is very stable and Swift continues to introduce many breaking changes.

2) There is group of devs who hate square brackets because most other languages don't use them and Swift feels more "familiar." But this is dumb. Objective-C is actually a very easy and powerful language for app dev. Much easier than Swift. This group of developers who harp on syntax is so large it's kind of depressing. Lattner admitted in a recent interview that Apple was surprised by the quick adoption of Swift by the developer community which caused new features to be rushed which contributed to Swift's overall complexity. He described this as a "massive failure." Kudos to him for being self-aware and honest.

>Whatever is designed to succeed Swift needs an extreme focus on Apps. Whoever runs it should ban C++ enjoyers and academics from having input (or perhaps do the opposite, where appropriate).

These C++ types need to stick to writing compilers. Keep your fucking filthy hands off UI frameworks.


> Swift began under Serlet, but it's interesting to think if an exec would have been able to foresee its overall harm and either kill it after a couple years or hard re-focus it.

Well, Swift started in 2010 and Serlet left in 2011. If I recall correctly some of the latest podcast with Lattner, he was facing a lot of push back from "the leadership from the Next era who loved obj-c". I guess it was him amongst others.

Leave a Comment