I wrote a small sample app "BudgetApp" using Core Data and MV/MVI pattern. You can find it here:
https://github.com/azamsharp/BudgetApp
I ended up creating the fetch request inside the Model (Core Data Model Classes) and that way I was able to reuse them.
Post
Replies
Boosts
Views
Activity
Search for the following articles. My website is azamsharp dot com or follow me on Twitter @azamsharp
SwiftUI Architecture - A Complete Guide to MV Pattern Approach
Embracing Core Data in SwiftUI
When most readers read the above code they say "Oh you change the name of view model to StoreModel or DataStore etc and thats it". NO! Look carefully. We are no longer creating view model per screen. We are creating a single thing that maintains an entire state of the application. I am calling that thing StoreModel (E-Commerce) but you can call it anything you want. You can call it DataStore etc. I explained it in detail in my article linked in my post.
This means in a client/server app, where server is the source of truth you will have a single place to handle the entire state of your app (For bigger apps you can create more based on bounded context and domain - read my article linked above).
MVVM approach -> CategoryListViewModel, CategoryDetailViewModel, ProductViewModel, AddCategoryViewModel, AddProductViewModel
MV approach -> StoreModel
Also, all view specific logic will go in the View.
You can find some information in this article.
https://azamsharp.com/2023/07/04/the-ultimate-swift-data-guide.html
and this:
https://youtu.be/OF7TLbMu1ZQ?si=WetrgS5rD_Qlod9M
and I have a series on building Reminders app:
https://www.youtube.com/watch?v=om9IloU7Lqc&list=PLDMXqpbtInQgFOoRkbRnMHEAyJs3qB8Dm
class Budget {
func save(context: ModelContext) throws {
let fetchDescriptor = FetchDescriptor<Budget>(predicate: #Predicate { $0.name == name })
let budgets: [Budget] = try context.fetch(fetchDescriptor)
if !budgets.isEmpty {
throw BudgetError.duplicateName
}
context.insert(self)
}
}
Apple's post emphasizes business logic, not presentation or transformation logic. This distinction is clear, as Apple applies the same principles in their code samples, like in FoodTruckApp, Fruta, ScrumDinger, and Backyard Birds. For business logic, it’s best to place it where it can be easily unit tested. Personally, I prefer to use Stores or services for managing business logic, depending on the context and requirements.