I'm new to SwiftUI architecture especially when using MVVM. Currently I've got the following situation that I try to solve using MVVM. I struggle to understand the boundaries of a view model and how to solve the data handling part for it.
Let's give an example: the properties of the following domain model should be changed throughout a sequence of different NavigationViews
, think of it as a wizard.
The struct representing this domain model looks like this:
class BusModel: Identifiable {
let id: UUID
var name: String
var drivers: [DriverModel]
}
class DriverModel: Identifiable {
let id: UUID
var firstName: String
var lastName: String
var toursToDrive: [TourToDriveModel]
}
class TourToDriveModel: Identifiable {
let id: UUID
var dayOfTheWeek: Int
var tour: TourModel
}
class TourModel: Identifiable {
let id: UUID
let label: String
}
As you see, the domain model has some sort of hierarchy: BusModel
contains a list of DriverModel
contains a list of ToursToDriveModel
contains a TourModel
The purpose of the first NavigationView
is to make changing the BusModel.name
field possible. After clicking the next button, the list of drivers getting displayed, represented using NavigationLinks
. There it should be possible to add a new driver or update the existing ones. So clicking on a list item navigates the user to the next view, presenting the data of those DriverModel
. There it should be possible to change the drivers firstName
and lastName
and should show it's toursToDrive
presented in a list as well. Changing a tourToDrive
follows the same navigation principle as described for the driver.
So my question is: after all every view changes some properties of the underlying BusModel
object and I don't know what a view model in this context would look like. Should the view model be related to all those single views or should every view has it's own dedicated view model?
Currently my view model spans the whole set of views, where every view changes to related properties of the view model. But I don't think that's correct because the view model holds every logic of every single view and if the relationship would be 1:1 of view and view model, those logics would be scoped to the distinct view they belong to.
So I guess, putting the domain model into an environment object which can be used within every distinct view model would be a better choice?
Another problem I have right now is, that the BusModel
fields are exposed as @Published
properties, so it looks something like this:
class AlterBusViewModel: ObservableObject {
@Published var name: String
@Published var drivers: [DriverModel]
}
But if DriverModel.firstname
gets updated, the view model doesn't propagate the changes to ancestor views as well, because it's some sort of nested property I guess? Even if the view model would be divided into view related view models, this problem persists from my point of view. How could this be solved as well?
Finally the domain model and data handling gets replaced by core data later on, but for now I would like to solve it by using a class
representing the domain model at runtime which should be updated subsequently.
If there are any questions, feel free to ask, I will provide more info as soon as possible!
Many thanks in advice.