SwiftUI + Core Data - updating an object (Detail -> DetailEdit)

569 Views Asked by At

Goal: update a core data object with SwiftUI: DetailView -> EditDetail -> DetailView (updated).

Problem: code bellow works, but creates a new object, instead of updating existing one.

import SwiftUI

struct DetailView: View {
    
    var order = Order()
    
    @State var showOrderEdit = false


    var body: some View {
        
        Form{
        
        Text(order.tableNumber)
        Text(order.pizzaType)
            
        }
        .navigationTitle(order.pizzaType)
        
        .toolbar {

            ToolbarItem(placement: .primaryAction) {
                
                
                //edit button
                Button(action: {
                    showOrderEdit = true
                }, label: {
                    Text("Edit")
                })
                .sheet(isPresented: $showOrderEdit) {
                    OrderEdit(order: order)
                }
            }
        }

    }
}

import SwiftUI

struct DetailEdit: View {
    
    @State var tableNumber = ""
    
    @Environment(\.managedObjectContext) private var viewContext
    @Environment (\.presentationMode) var presentationMode

    var order = Order()

    var body: some View {
        
        NavigationView {

        
        Form {
        
            TextField("table number", text: $tableNumber)
            
            
            //update button
            Button(action: {
                updateOrder(order: order)
            }) {
                Text("Update")
                    .foregroundColor(.blue)
            }
        
        }
        
        //passing data item detail -> item edit
        .onAppear {
            self.tableNumber = self.order.tableNumber
        }
        
        .navigationTitle("Edit Order")

    }
}
    
    func updateOrder(order: Order) {
        let newtableNumber = tableNumber
        viewContext.performAndWait {
            order.tableNumber = newtableNumber
            try? viewContext.save()
        }
    }
    
  
1

There are 1 best solutions below

1
On BEST ANSWER

You create new Order object in each view, so it is stored as new one into database. Instead you need to inject CoreData object from parent view (which shows DetailView) as observed object,

struct DetailView: View {
    
    @ObservedObject var order: Order   // << here !!
    
// .. other code

and

struct DetailEdit: View {
    
    @State var tableNumber = ""
    
    @Environment(\.managedObjectContext) private var viewContext
    @Environment (\.presentationMode) var presentationMode

    @ObservedObject var order: Order          // << here !!

// ... other code

in such approach you will work with same instance of Order in both views and they will be updated because observe that instance for modifications.