SwiftUI Editing the information in the Detail of a Master/Detail

Working on a sample app. The goal is to have a list pulled up from CoreData in a MasterView, and then click on one to go to a DetailView where you can edit the information and save. When you edit the "name" in the DetailView, it not only updates the DetailView to reflect the change, but it also reflects the change on the MasterView as well. I've tried numerous ways to accomplish this, but so far have not come up with an answer.

// Code generation is turned OFF in the xcdatamodeld file
public class EntityName: NSManagedObject, Identifiable {
    @NSManaged public var name: String
    @NSManaged public var active: Bool
}

extension EntityName {
    static func allEntityNameFetchRequest() -> NSFetchRequest<EntityName> {
        let request: NSFetchRequest<EntityName> = EntityName.fetchRequest() as! NSFetchRequest<EntityName>
        request.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]
        return request
    }
}

struct MasterView: View {
    
    @Environment(\.managedObjectContext) var managedObjectContext
    @FetchRequest(fetchRequest: EntityName.allEntityNameFetchRequest()) var allEntityNames: FetchedResults<EntityName>
    
    
    var body: some View {
        NavigationView {
            List {
                ForEach(self.allEntityNames) { entityName in
                    NavigationLink(destination: DetailView(entityName: entityName)) {
                        VStack(alignment: .leading) {
                            Text(entityName.name)
                                .font(.headline)
                            Text(String(entityName.active))
                                .font(.subheadline)
                        }
                    }
                }
            }
        }
        .onAppear() {
            // Just want to populate the Core Data to have a few to work with
            if self.allEntityNames.count == 0 {
                for _ in 1...3 {
                    let newEntry = EntityName(context: self.managedObjectContext)
                    newEntry.name = "New Entry"
                    
                    try! self.managedObjectContext.save()
                }
            }
        }
    }
}

struct DetailView: View {
    
    var entityName = EntityName()
    @State private var name = ""
    @State private var booley = false
    
    var body: some View {
        VStack {
            Text("Name: \(entityName.name)")
            Text("Active: \(String(entityName.active))")
            
            // What I'd like to do now:
            //TextField("", text: $entityName.name)
            //Toggle(isOn: $entityName.active)
        }
    }
}

Replies

If you want to bind your textfields directly to the entityName property you should make it an @ObservedObject like this:


struct DetailView: View {
  @ObservedObject var entityName: EntityName
  
  var body: some View {
    VStack {
      TextField("Name", text: $entityName.name)
      Toggle(isOn: $entityName.active) { Text("Active") }
    }
  }
}


I don't know whether the $binding will also commit your changes or if you have to do that manually though.