I have a SwiftUI app with 3 Core Data entities, Car
, CarService
and ServiceRecord
where Car
has many carServices
and each CarService
has many serviceRecords
. Everything is working fine but I'm not sure what's the most common MVVM practice.
As you can see in the following example I'm using CoreDataViewModel
to fetch data from Core Data
and then I pass it around all SwiftUI views, at the moment I don't have a ViewModel for the view's logic (the logic is currently inside of each view) but that's something I would like to incorporate, but I'm not sure what would be the best way to do that. I'm thinking about the two following option...
-
Create a view model for each view (
CarViewModel
,ServicesViewModel
andRecordsViewModel
) to handle ONLY the view's logic and leave the existingCoreDataViewModel
as is. -
Create a view model for each view,
CarViewModel
,ServicesViewModel
andRecordsViewModel
to handle the logic for each view and move the CoreData quests to each of the view models respectably and basically deleteCoreDataViewModel
altogether since now the core data related will live inside each view model.
Which of the two options above makes more sense for an MVVM app?
In general, can someone please share how you usually structure your code when using MVVM + CoreData + SwiftUI
?
CoreDataManager
class CoreDataManager{
static let instance = CoreDataManager()
lazy var context: NSManagedObjectContext = {
return container.viewContext
}()
lazy var container: NSPersistentContainer = {
return setupContainer()
}()
func setupContainer()->NSPersistentContainer{
// code to setup container...
return container
}
func save(){
do{
try context.save()
}catch let error{
print("Error saving Core Data. \(error.localizedDescription)")
}
}
}
CoreDataViewModel
class CoreDataViewModel: ObservableObject{
let manager: CoreDataManager
@Published var cars: [Car] = []
@Published var carServices: [CarService] = []
@Published var serviceRecords: [ServiceRecord] = []
init(coreDataManager: CoreDataManager = .instance){
self.manager = coreDataManager
// getCars() etc.
}
// CREATIONS
func addCar(name:String){}
func addService(name:String, cost: Double){}
func createRecord(name:String, cost: Double){}
// DELETES
func deleteCar(){}
func deleteCarService(){}
func deleteServiceRecord(){}
// UPDATES
func updateCar(){}
func updateService(){}
// GETS
func getCars(){}
func getServices(){}
func getRecords(){}
func save(){
self.manager.save()
}
}
SwiftUI Views
CarsView
struct CarsView: View {
@StateObject var coreDataViewModel = CoreDataViewModel()
var body: some View {
NavigationView{
VStack{
List {
ForEach(coreDataViewModel.cars) { car in
}
}
}
}
}
}
ServicesView
struct ServicesView: View {
@ObservedObject var coreDataViewModel:CoreDataViewModel
var body: some View {
NavigationView{
VStack{
List {
ForEach(coreDataViewModel.carServices) { service in
}
}
}
}
}
}
RecordsView
struct RecordsView: View {
@ObservedObject var coreDataViewModel: CoreDataViewModel
var body: some View {
NavigationView{
VStack{
List {
ForEach(coreDataViewModel.serviceRecords) { record in
}
}
}
}
}
}
Thanks!