I am relatively new to iOS programming and I am having a hard time making peace between how CoreData works and what I know about software architecture.
So I am trying to setup a project around the MVVM pattern with Combine framework and SwfitUI.
My first problem is the @FetchRequest
property wrapper. In every SwiftUI sample and tutorial I've seen, the view talks directly to the database. It is not just that I don't like this because I'm so religious about separation of concerns, it is making it hard for me to implement my use case. The local database is a cache for me, the actual source of truth is in the cloud, and the cache needs to keep up with the changes on the cloud. The observable pattern fits in nicely with this scenario; you serve what you have in the cache, and at the same time, you run your business logic to see if you need to fetch a fresh copy of your data, and if it is the case, you load your data and make another serve to the view layer. That will be hard to implement with @FetchRequest
to say the least.
The other problem is when you need to load just some of the columns out of your database table, with CoreData that means that not only you'll be arranging a rather complex database fetch operation inside your view, you'll get a dictionary result at the end, which means a whole lot of string literals for keys and type castings for values in your view code.
I would normally just inject a repository into my view-model and, if required, I would return a light version of my entity from the repository with only the required columns on it.
And finally, I find it problematic that all entities are NSManagedObject
instances. Besides similar violations of the MVVM pattern, this goes directly in the face of reactive functional programming (which Apple is trying to embrace with the Combine framework) where you're supposed to have a flow of immutable data.
Searching for a solution, I've found workarounds that basically work with NSFetchedResultsControllerDelegate
to turn a simple FetchRequest
into a Publisher
, like this one and this one.
Using that approach and mapping CoreData entities to immutable entities in each repository, I was able to address all the above concerns. As it stands now, I have, for instance, a CDUser
type which will be mapped to a User
type before it leaves the UserRepository
.
At this point, I am starting to doubt whether it is worth all the effort and the overhead that CoreData brings with it, just to keep using CoreData. Why not just ditch CoreData altogether and use something like Realm instead? That looks like a bold move though, considering how integral CoreData is to iOS programming. So I wanted to know the opinion of more experienced iOS programmers.
I know CoreData is a big frameworks and I am standing to lose some of its features here (like storage in iCloud which I don't need and batch loading which I could live without), but apart from those, would you call it a terribly bad idea to ditch CoreData for the reasons that I presented above.