SwiftUI cannot update CoreData Entity Object

Viewed 40

I am facing a very weird bug, I have a edit function which will accept the object and new form data from the frontend, the function can be executed without errors but the issue is the data is not updated at all. I tried reopen the simulator and refetch also no use to this. May I ask how to solve this?

class RoomDataController: ObservableObject {
    @Published var rooms: [Room] = []

    let container = NSPersistentContainer(name: "RentalAppContainer")
    
    init() {
        container.loadPersistentStores { description, error in
                let current = FileManager.default.currentDirectoryPath
                print(current)

            if let error = error {
                print("Failed to load data in DataController \(error.localizedDescription)")
            }
        }
        fetchRooms()
    }

    func save(context: NSManagedObjectContext) {
        do {
            try context.save()
            print("Data created or updated successfully!")
        } catch {
            // Handle errors in our database
            let nsError = error as NSError
            fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
        }
    }

    func editRoom(room: Room, roomType: String, roomDescription: String, contactPeriod: String, roomPrice: Float, userID: UUID, isShort: Bool, isLong: Bool, images: String, email: String, phoneNum:String, context: NSManagedObjectContext) {
            
            room.roomType = roomType
            room.roomPrice = roomPrice
            room.roomDescription = roomDescription
            room.contactPeriod = contactPeriod
            room.contactEmail = email
            room.contactNum = phoneNum
            room.updated_at = Date()
            print("room to be edited: ", room)
            save(context: container.viewContext)
            fetchRooms()
        }
}

The Frontend View that call the edit function

struct EditRoomView: View {
    @EnvironmentObject var userAuth: UserAuth

    @State var type: String = ""
    @State var description: String = ""
    @State var price: String = ""
    @State var contactPeriod: String = ""
    @State var isShort: Bool = false
    @State var isLong: Bool = false
    @State var email: String = ""
    @State var phoneNum: String = ""

    @ObservedObject var room: Room
    private func editItem() {
        RoomDataController().editRoom(
            room: room,
            roomType: self.type,
            roomDescription: self.description,
            contactPeriod: self.contactPeriod,
            roomPrice: Float(self.price)!,
            userID: userAuth.user.id!,
            isShort: self.isShort,
            isLong: self.isLong,
            images: "room-1,room-2,room-3",
            email: email,
            phoneNum: phoneNum
        )
    }
    
    init(room: Room){
        self.room = room
        _type = State(initialValue: room.roomType!)
        _description = State(initialValue: room.roomDescription!)
        _price = State(initialValue: String( room.roomPrice))
        _contactPeriod = State(initialValue: room.contactPeriod!)
        _email = State(initialValue: room.contactEmail!)
        _phoneNum = State(initialValue: room.contactNum!)
        if room.contactPeriod == "Short"{
            _isShort = State(initialValue:true)
            _isLong = State(initialValue: false)
        } else {
            _isShort = State(initialValue: false)
            _isLong = State(initialValue:true)
        }
    }
    
    
    
    var body: some View {
        VStack{
            HStack {
                Spacer()
                VStack {
                    Menu {
                        Button {
//                            self.selectedTab = .AccountViewTab
                        } label: {
                            NavigationLink(destination: AccountView().environmentObject(userAuth), label: {Text("My Profile")})
                            Image(systemName: "arrow.down.right.circle")
                        }
                        Button {
                            userAuth.isLoggedin = false
                        } label: {
                            Text("Log Out")
                            Image(systemName: "arrow.up.and.down.circle")
                        }
                    } label: {
                        Text("Menu").foregroundColor(Color.black)
                    }
                }
                
                Spacer()
                VStack {
                    NavigationLink(destination: OwnerNavbarView().environmentObject(userAuth), label: {Text("Room Rent").foregroundColor(Color.black)})
                }
                .onTapGesture {
                }
                Spacer()
                VStack {
                    NavigationLink(destination: OwnerNavbarView(nextView: "PostRoomHistoryViewTab").environmentObject(userAuth), label: {Text("Post History").foregroundColor(Color.black)})
                }
                .onTapGesture {
                }
                Spacer()
                VStack {
                    NavigationLink(destination: OwnerNavbarView(nextView: "CustomerOrderViewTab").environmentObject(userAuth), label: {Text("Customer Orders").foregroundColor(Color.black)})
                }
                .onTapGesture {
                }
                Spacer()
            }
            .padding(.bottom)
            .background(Color.gray.edgesIgnoringSafeArea(.all))
            
            Text("Edit Room Details")
            Form {
                Section(header: Text("Room Type") ) {
                    TextField("", text: self.$type)
                }
                
                Section(header: Text("Room Description") ) {
                    TextField("", text: self.$description)
                }
                
                MultipleImagePickerView()
                
                Section(header: Text("Room Price") ) {
                    TextField("", text: self.$price)
                }
                Section(header: Text("Contact Period") ) {
                    
                    HStack{
                        Toggle( "Short", isOn: $isShort )
                        
                        Toggle("Long", isOn: $isLong )
                        
                    }
                }
                
                Section(header: Text("Contact Email Address * :") ) {
                    TextField("", text: self.$email)
                }
                Section(header: Text("Contact Mobile No * :") ) {
                    TextField("", text: self.$phoneNum)
                }
                
            }

            Button(action: {
                self.editItem()
            }) {
                HStack {
                    Text("Update")
                }
                .padding()
                .scaledToFit()
                .foregroundColor(Color.white)
                .background(Color.blue)
                .cornerRadius(5)
            }
        }
    }
}

Ok..Managed to solve this in this way, buy why?

do {
    fetchRequest.predicate = NSPredicate(format: "id == %@", room.id?.uuidString as! CVarArg)
    let result = try container.viewContext.fetch(fetchRequest)
    result[0].roomType = roomType
    result[0].roomPrice = roomPrice
    result[0].roomDescription = roomDescription
    result[0].contactPeriod = contactPeriod
    result[0].contactEmail = email
    result[0].contactNum = phoneNum
    result[0].updated_at = Date()
} catch {
    print ("fetch task failed", error)
}
if room.ownerID == userID.uuidString {
    save(context: container.viewContext)
    fetchRooms()
}
0 Answers
Related