I've spent the last few months working on a macOS project that incorporates Core Data. I will release the app to the appstore soon but the primary motivation for writing it was to learn SwiftUI.
In that time I've seen a lot of different ways to utilise Core Data and I wasn't really happy with any of them from a design perspective. My first approach was to use the @FetchRequest property wrapper in my contentView but that quickly turned into putting absolutely everything into contentView. The app worked properly and I could have (and probably should have) just released it then but I really wasn't happy with it from a design perspective. At this point I decided to refactor the program to MVVM.
However Core Data and MVVM comes with quite a few questions that need answering themselves. I thought about using the DataController example model that is demonstrated on the Ultimate Portfolio App tutorial but I wasn't quite 100% happy with this. Using this approach is clearly good because it abstracts away Core Data from your view and it also makes it easier to change your data stores down the road, but I wanted somthing that made full use of the idiomatic features of Core Data which includes @FetchRequest, but I wasn't quite sure how to do it.
Additionally MVVM seems to mean different things to different people. It seems that many people take the Model component to mean exclusively the data or the database, and they suggest putting the business logic into the View Model. For me the Model represents a model for the application, of which the data is only a portion. This means I've got a heavy Model and skinny Views and ViewModels.
In the end I was able to come up with a solution that worked and also fit my desire to integrate Core Data idiomatically. My view code ended up incorporating one @ObervedObject which was my ViewModel, and two @FetchRequests. User actions filter down to the Model which changes it's state which then filters back to the View via either the @ObservedObject or the @FetchRequests.
I'm not sure if I'd use the same approach on future projects (unless I were sure they not require cross platform) but I'm glad I did it for this one.
Anyway my post doesn't really have a point other than to share my experience and to hear other people's on how they've dealt with this.
i feel your pain!
i think the Core Data connection with SwiftUI Views is a little bit of a kludge, frankly -- i think
the situation is further complicated by the fact that Core Data provides (class) objects and SwiftUI really wants to work with structs. you have access to the object itself -- you never tell a VM to do something to it (an "intent"), and you hope that the
my journey continues to this day. i once tried a simple CD project named ShoppingList in SwiftUI where i went out of my way to use more MVVM and avoid
then i updated this project to ShoppingList14 and removed all the ViewModel code and went back to
i consulted within the last year on two apps now on the app store on the CD implementation, and for one of those, we used a hybrid management of CD and in-memory objects through a view model. in a current project that is "almost ready for the app store," i have more of a
my current belief: if you only create and modify CD objects, you can probably stick with
but if you allow for deletion of CD objects and some views maintain
so my definitive answer to your unasked question: i think the jury's still out on how best to use SwiftUI and CD. i was hoping for some news at WWDC2021. maybe next year ...
hope that helps,
Edit after the fact: you might also consider reading this article by Dave DeLong, which seems to be working on the edges of what i think we're both talking about. i was intrigued; although i have not pursued it myself.
Thanks for your thoughtful reply DMG, and also for your links.
I've found that I've had to do a few things that sort of feel like hacks when combining the use of a view model with @FetchRequest, and you're right the problems did relate to deletion.
For example I populate a Picker with a @FetchRequest and I use the instance of the entity for the selection rather than using the index of the selection. This seems to work fine until I need to delete the selected entity (which I perform in my model rather than in the view) because if I set the selection to nil it will break the Picker.
I also use this "create and delete" approach when initialising the selector in case the @FetchRequest is empty.
SPONSORED AppSweep by Guardsquare helps developers automate the mobile app security testing process with fast, free scans. By using AppSweep’s actionable recommendations, developers can improve the security posture of their apps in accordance with security standards like OWASP.
This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.
All interactions here are governed by our code of conduct.
Link copied to your pasteboard.