salma209
salma209

Reputation: 189

Update data selected from UITableViewCell in Core Data using Swift 3

I will let user edit the data by tapping on table cell. User will select the table cell, whichever data they want to modify, a newVC "UpdateDataViewController" will appear with previously selected data. user can modify the data and hit the save button to save the edited data in database table.

here is my code:

//Code to pass the data in selected row
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "update" {
        var path = self.tableView.indexPathForSelectedRow
        let nav = segue.destination as! UINavigationController
        let updateViewController = nav.topViewController as! UpdateDataViewController

        updateViewController.index = path?.row
       updateViewController.editPeopleList = peopleList[(path?.row)!].name
      //  let updatePersonModel = PersonModel()
       // updateViewController.editPeopleList = [updatePersonModel.name!]

    }
}

UpdateDataViewController.swift

// code to select the row and enable to edit touching any place of text field

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    if indexPath.section == 0 && indexPath.row == 0  {
        updateDataTextField.becomeFirstResponder()
    }
    tableView.deselectRow(at: indexPath, animated: true)
}

the variables required:

  var index:Int?
var editPeopleList:String!

var updatePeopleList: String?

  override func viewDidLoad() {
    super.viewDidLoad()

    updateDataTextField.text = editPeopleList
}

 // after editing data is replaced here: 
 override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    // Get the new view controller using segue.destinationViewController.
    // Pass the selected object to the new view controller.

    if segue.identifier == "updateData" {
        updatePeopleList = updateDataTextField.text
    }
}

the code for updating in core-data using unwind segue:

 //code for unwind segue

@IBAction func updateDataToViewController(segue: UIStoryboardSegue) {

    let updatePeopleData = segue.source as! UpdateDataViewController

    let index = updatePeopleData.index

 //   let dataToUpdate = peopleList[index!].name
   let personData = updatePeopleData.updatePeopleList


    let updatePersonName = PersonModel()
    updatePersonName.name = personData

    let path = self.tableView.indexPathForSelectedRow
    let selectedPersonData = peopleList[(path?.row)!]

    PersonServices.sharedInstance.updatePerson(updatePersonName: updatePersonName, selectedPersonData: selectedPersonData  )
   // updatePersonModel.name = name


   //peopleList[index!] = updatePeopleData.
    tableView.reloadData()
}

here is my update function for updating data in core-data:

 func updatePerson(updatePersonName: PersonModel , selectedPersonData: PersonModel) {

    let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: PersonEntity)

    let updatepredicates = NSPredicate(format: "name == %@" , selectedPersonData.name!  )

   print("data to update: \(updatepredicates)")
    print("updated data: \(String(describing: updatePersonName.name))")

   fetchRequest.predicate = updatepredicates
    print("after edit: \(fetchRequest)")
      var updatePersonModels = [PersonModel]();

 do {
        if  let person = try 
      self.managedObjectContext.fetch(fetchRequest).first as? Person {

let newPersondata = NSEntityDescription.insertNewObject(forEntityName: PersonEntity, into: managedObjectContext)
            newPersondata.setValue("updatePersonName.name", forKey: person.name!)

            do {
               try self.managedObjectContext.save()
              updatePersonModels.append(PersonModel(person: person))
            } catch let error as NSError {
                print("could not save. \(error), \(error.userInfo)")
            }

}
    } catch let error as NSError {
        print("Could not save \(error), \(error.userInfo)")
    }
}

but my app is crashing at

newPersondata.setValue("updatePersonName.name", forKey: person.name!)  

in updatePerson function.

The error is:

Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ setValue:forUndefinedKey:]: the entity Person is not key value coding-compliant for the key "Umar".'

Upvotes: 2

Views: 1504

Answers (1)

salma209
salma209

Reputation: 189

At last I have done it, Ahumdulillah.

At first i have changed my "updatePerson" function as belows:

func updatePerson(updatePersonName: PersonModel , selectedPersonData: PersonModel) {

    let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: PersonEntity)

    let updatepredicates = NSPredicate(format: "name == %@" , selectedPersonData.name!  )

   fetchRequest.predicate = updatepredicates

      var updatePersonModels = [PersonModel](); 
 do {
        if  let person = try self.managedObjectContext.fetch(fetchRequest).first as? Person {

           person.name = updatePersonName.name
            print("person name is: \(person.name)")


            do {
               try self.managedObjectContext.save()

              updatePersonModels.append(PersonModel(person: person))
            } catch let error as NSError {
                print("could not save. \(error), \(error.userInfo)")
            }

}
    } catch let error as NSError {
        print("Could not save \(error), \(error.userInfo)")
    }
}

Then ,in the "updateDataToViewController" unwind segue function : i have just put the edited data in the selected index.

 @IBAction func updateDataToViewController(segue: UIStoryboardSegue) {

    let updatePeopleData = segue.source as! UpdateDataViewController

    let index = updatePeopleData.index

   let dataToUpdate = peopleList[index!].name
   let personData = updatePeopleData.updatePeopleList


    let updatePersonName = PersonModel()
    updatePersonName.name = personData



    let selectedPersonData = peopleList[index!]

    PersonServices.sharedInstance.updatePerson(updatePersonName: updatePersonName, selectedPersonData: selectedPersonData  )

  peopleList[(path?.row)!] = updatePersonName
    tableView.reloadData()
}

thats it.....

Upvotes: 2

Related Questions