I have a parent class, that has children (Child Class), that have Puppets (Puppet Class). The data is displayed in a list of parents that navigates to a list of children, that navigates to a list of puppets.
Within the views, the user is able to add parents, children and puppets or remove them.
I want to store the data locally so that every change is save. I think storing the Parent class is enough, because of parents.children.puppets
.
Thus I need to conform to Codable anyhow and decode and encode my data anyhow.
The AppState should load local data or [] instead of the current dummy data. On every parent (or child or puppet) change, I want to store the parents locally in the most efficient way. Same for receiving the data.
class Parent: ObservableObject, Hashable {
static func == (lhs: Parent, rhs: Parent) -> Bool {
lhs.id == rhs.id
}
func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
let id = UUID()
let name: String
@Published var children: [Child]
init(name: String, children: [Child]? = nil) {
self.name = name
self.children = children ?? []
}
func remove(child: Child) {
self.children.remove(child)
}
func add(child: Child) {
self.children.append(child)
}
}
class Child: ObservableObject, Identifiable, Hashable {
static func == (lhs: Child, rhs: Child) -> Bool {
return lhs.id == rhs.id
}
func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
let id = UUID()
let name: String
@Published var puppets: [Puppet]
init(name: String, puppets:[Puppet]? = nil) {
self.name = name
self.puppets = puppets ?? []
}
func remove(puppet: Puppet) {
self.puppets.remove(puppet)
}
func add(puppet: Puppet) {
self.puppets.append(puppet)
}
}
struct Puppet: Identifiable, Hashable {
let id = UUID()
let name: String
}
class AppState: ObservableObject {
@Published var parents: [Parent]
init() {
self.parents = [
Parent(name: "Foo", children: [Child(name: "bar", puppets: [Puppet(name: "Tom")])]),
Parent(name: "FooBar", children: [Child(name: "foo", puppets: nil)])
]
}
}
extension Array where Element: Identifiable {
mutating func remove(_ object: Element) {
if let index = self.firstIndex(where: { $0.id == object.id}) {
self.remove(at: index)
}
}
}