soundChaser
soundChaser

Reputation: 115

Swift updating data in core data entity

I am trying to set up a function to update data in my core data entity. I can bring up a specific context and change the data, but when I click save it creates a new context instead of overwriting the old. My code is as follows:

import UIKit import CoreData

class RoomDetailTableViewController: UITableViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {

@IBOutlet weak var roomImageView: UIImageView!
@IBOutlet weak var roomNameTextField: UITextField!


@IBOutlet weak var rmLengthFt: UITextField!
@IBOutlet weak var rmLengthInches: UITextField!
@IBOutlet weak var rmWidthFt: UITextField!
@IBOutlet weak var rmWidthInches: UITextField!

let appDelegateObj : AppDelegate = UIApplication.shared.delegate as! AppDelegate


var managedObjectContext: NSManagedObjectContext? {
    return (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
}

 var roomArray = [Rooms]()
var arrayElement: Int = 0

override func viewDidLoad() {
    super.viewDidLoad()
    retrieveRooms()
    setSaveBarButton()
    if arrayElement != 2112 { //Kludgy******

    updateRoom()
    }

}


func setSaveBarButton(){

    let saveBarButton = UIBarButtonItem(barButtonSystemItem: .save, target: self, action: #selector(RoomDetailTableViewController.saveRoom))
    navigationItem.rightBarButtonItem = saveBarButton



}

func updateRoom(){
    let room = self.roomArray[arrayElement]


    self.roomNameTextField.text = room.roomName
    self.roomImageView.image = UIImage(data: room.roomImage! as Data)

}


@IBAction func pickRoomImage(_ sender: UITapGestureRecognizer) {


    let pickerController = UIImagePickerController()
    pickerController.delegate = self
    pickerController.allowsEditing = true

    let alertController = UIAlertController(title: "Add a Picture", message: "Choose From", preferredStyle: .actionSheet)

    let cameraAction = UIAlertAction(title: "Camera", style: .default) { (action) in
        pickerController.sourceType = .camera
        self.present(pickerController, animated: true, completion: nil)

    }
    let photosLibraryAction = UIAlertAction(title: "Photo Library", style: .default) { (action) in
        pickerController.sourceType = .photoLibrary
        self.present(pickerController, animated: true, completion: nil)

    }

    let savedPhotosAction = UIAlertAction(title: "Saved Photos Album", style: .default) { (action) in
        pickerController.sourceType = .savedPhotosAlbum
        self.present(pickerController, animated: true, completion: nil)

    }

    let cancelAction = UIAlertAction(title: "Cancel", style: .destructive, handler: nil)

    alertController.addAction(cameraAction)
    alertController.addAction(photosLibraryAction)
    alertController.addAction(savedPhotosAction)
    alertController.addAction(cancelAction)


    present(alertController, animated: true, completion: nil)

}


func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    self.dismiss(animated: true, completion: nil)

    if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
        self.roomImageView.image = image

    }
}

func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
    picker.dismiss(animated: true, completion: nil)
}

func saveRoom(){

    if  roomNameTextField.text!.isEmpty || roomImageView.image == nil {

        let alertController = UIAlertController(title: "Room Name", message: "Pleae provide data", preferredStyle: .alert)

        alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
        self.present(alertController, animated: true, completion: nil)


    } else {

        //Let's save
        if let moc = managedObjectContext {
            let room = Rooms(context: moc)
            room.roomName = roomNameTextField.text!
            room.rmLengthFt = rmLengthFt.text!
            room.rmLengthInches = rmLengthInches.text!
            room.rmWidthFt = rmWidthFt.text!
            room.rmWidthInches = rmWidthInches.text!

            if let data = UIImageJPEGRepresentation(self.roomImageView.image!, 1.0) {
                room.roomImage = data as NSData
            }

            saveToCoreData() {
                self.navigationController!.popToRootViewController(animated: true)
            }


        }
    }

}


func saveToCoreData(completion: @escaping ()->Void){
    managedObjectContext!.perform {

        var error: NSError?
        do {
            try self.managedObjectContext?.save()
            completion()
        } catch let error1 as NSError {
            error = error1
        }

        //Check for any errors

        if let err = error {

            let a = UIAlertController(title: "Error", message: err.localizedFailureReason, preferredStyle: .alert)
            self.present(a, animated: true)
        } else {


            print("Room saved to CoreData")

        }

    }

}

func retrieveRooms(){
    fetchRoomsFromCoreData { (rooms) in
        if let rooms = rooms{
            self.roomArray = rooms
            self.tableView.reloadData()
        }
    }
}

func fetchRoomsFromCoreData(completion: ([Rooms]?)->Void){
    var results = [Rooms]()
    let request: NSFetchRequest<Rooms> = Rooms.fetchRequest()
    do {
        results = try  managedObjectContext!.fetch(request)
        completion(results)
    }catch {
        print("Could not fetch Rooms from CoreData:\(error.localizedDescription)")
    }
}

}

I know my nomenclature is probably inaccurate as I am just learning to work with core data.

Any help would be appreciated.

Upvotes: 1

Views: 163

Answers (1)

Jon Rose
Jon Rose

Reputation: 8563

I believe you mean that you are creating a new enitity when you want you to modify the existing entity. Instead of

let room = Rooms(context: moc)

which is creating a new entity, you want to access the same entity that you used to fill in the data. Something like let room = self.roomArray[arrayElement]. It is hard to comment further as I don't understand your code or what evils have happens to you to cause the number 2112 to be cursed. (if arrayElement != 2112 WTF!)

Upvotes: 1

Related Questions