Reputation: 115
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
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