How can I update/save a Property Change for Child Item from a Hierarchical List View of Items

How can I update/save a Property Change for Child Item from a Hierarchical List View of Items

See the following app screens:

Content View Screen:

Content View with hierarchical list children rows disclosed: 

Parent Row Detail View:

Child Row Detail View: 

Referencing the above views, here are the steps I do and the resulting problem I’m trying to solve:

  1. Launch the app.

  2. From the Functions (Content View) presented at launch, see that there is one item listed in a list view (1.0 Move Vessel)

  3. Click the yellow (my app accent color) disclosure arrow at the right of the list item.

  4. Two subordinate child list rows appear under the parent list item, 1.1 Move Position and 1.2 Hold Position.

  5. When I tap the parent item (1.0 Move Vessel) in the hierarchy list, I'm successfully able to navigate to a detail view for that tapped item. 

  6. Edit the description of the 1.0 Move Vessel item (defaults to test) of the tapped item properties in the detail view using a TextEditor view. 

  7. Click yellow Save button at top left of detail view. The app navigates back to the parent Functions (Content View).

  8. Click on the parent 1.0 Move Vessel row again.

  9. See that description was successfully saved and now displayed from the change made in Step 5 and 6.

  10. Repeat steps 5 through 8 again for 1.1 Move Position list row.

  11. See that the edit/change made to the description was not saved and the default test1 description is displayed instead (not what is wanted).

  12. Repeat steps 5 through 8 again for 1.2 Hold Position list row.

  13. See that the edit/change made to the description was not saved and the default test2 description is displayed instead (not what is wanted).

I think I may have a problem in my save code logic and I'm trying to investigate.

Here are the swift files for the Detail View, the View Model, and the Model (I’ve not included the content view code because that code is working ok with the detail view. Again, I think the problem is in my save button and function call code for updating the view model. NOTE: sorry that I can’t seem to figure out how to get all the code for a file contiguous in the code view. I seem to have some closing braces that don’t appear in the code view. I think you can still follow the code.

FunctionDetailView.swift


struct FunctionDetailView: View {
@State var vesselFunction: VesselFunction
@State var vesselFunctionDescription: String
@Environment(\.presentationMode) var presentationMode
@EnvironmentObject var functionViewModel : FunctionViewModel


var body: some View {
    
    NavigationView {
        
        Form {
            Text("Enter description below")
            TextEditor(text: $vesselFunctionDescription)
                .frame(height: 200)
                .toolbar {
                    Button {
                        //print(vesselFunction)
                        
                        vesselFunction.funcDescription = vesselFunctionDescription
                        
                        //print(vesselFunction)
                        
                        functionViewModel.updateVesselFunction(vesselFunction: vesselFunction)
                        
                        //print(vesselFunction)
                        
                        presentationMode.wrappedValue.dismiss()
                    } label: {
                        Text("Save")
                    }
                    
                }
        }
        .padding()
        .navigationTitle(vesselFunction.name)
        .navigationBarTitleDisplayMode(.inline)
    }
}
}

struct FunctionDetailView_Previews: PreviewProvider {
static var previews: some View {
    
    FunctionDetailView(vesselFunction: VesselFunction(id: UUID(), name: "x.x Verb Noun", funcDescription: "Description", children: nil), vesselFunctionDescription: "placeholder")
        .environmentObject(FunctionViewModel())
        .preferredColorScheme(.dark)
}
}

FunctionViewModel.swift

@MainActor class FunctionViewModel: ObservableObject {

@Published private(set) var decomp : [VesselFunction] = [
    VesselFunction(id: UUID(), name: "1.0 Move Vessel", funcDescription: "test", children: [
        VesselFunction(id: UUID(), name: "1.1 Move Position", funcDescription: "test1", children: nil),
        VesselFunction(id: UUID(), name: "1.2 Hold Position", funcDescription: "test2", children: nil)
    ])
]

func updateVesselFunction(vesselFunction: VesselFunction) {
    //
//    if let index = decomp.firstIndex(where: { //(existingVesselFunction) -> Bool in
//        return existingVesselFunction.id == vesselFunction.id
//    }) {
        //run this code
//    }
    
    // cleaner version of above
    if let index = decomp.firstIndex(where: { $0.id == vesselFunction.id }) {
        decomp[index] = vesselFunction.updateCompletion()
    } 
    // else {
    //    for item in decomp {
   //         if item.children != nil {
     //           if let index = item.children?.firstIndex(where: { $0.id == vesselFunction.id }) {
          //          item.children![index] = vesselFunction.updateCompletion()
  //              }
    //        }
   //     }
//    }
}
}

FunctionModel.swift


struct VesselFunction: Identifiable {
let id : UUID
let name : String
var funcDescription : String
var children : [VesselFunction]?

init(id: UUID, name: String, funcDescription: String, children: [VesselFunction]?) {
    self.id = id
    self.name = name
    self.funcDescription = funcDescription
    self.children = children
}

func updateCompletion() -> VesselFunction {
    return VesselFunction(id: id, name: name, funcDescription: funcDescription, children: children)
}
}

As you can see from the else and for-in loop code commented out at the bottom of the FunctionViewModel code, I was trying to see if I needed to do something like this code to access the children VesselFunction array entries of the decomp published property. With the if let index code that is not commented out, the save function works but only for the top-level decomp array VesselFunction elements, not the nested children arrays elements.

Any help would be appreciated so all decomp array elements, both parent and nested children, can be updated when the TextEditor field is changed and the Save button is pressed in the FunctionDetailView. NOTE: I am only showing a 1 level deep nested array of children for the decomp property. I actually want to have multiple (at least 3) level of children arrays, so if you have any ideas how to make an updateVesselFunction function work for multiple children array elements, I would appreciate it.

How can I update/save a Property Change for Child Item from a Hierarchical List View of Items
 
 
Q