2017-05-08 51 views
1

我正在尝试设置一个函数来更新我的核心数据实体中的数据。我可以调出特定的上下文并更改数据,但是当我单击保存时,它会创建一个新的上下文,而不是覆盖旧的上下文。我的代码如下:Swift更新核心数据实体中的数据

进口的UIKit 进口CoreData

类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)") 
    } 
} 

}

我知道我的术语可能是不准确的,因为我只是学习使用核心数据。

任何帮助,将不胜感激。

回答

1

我相信你的意思是说,当你希望你修改现有的实体时,你正在创建一个新的实体。而不是

let room = Rooms(context: moc) 

这是创建一个新的实体,你想访问你用来填充数据的同一个实体。像let room = self.roomArray[arrayElement]。由于我不了解您的代码或您发生什么恶行导致号码2112受到诅咒,因此很难进一步评论。 (if arrayElement != 2112 WTF!)

+0

@Jon我知道它是一个kludge(只是临时的)让程序流动,而我围绕更新实体时我的头。我在2112背后的原因是,我不希望有人在房子附近的许多房间附近。此外,我是一名拉什粉丝,所以在我找到更好的方法时,它似乎是一个难以置信的数字。 – soundChaser