Home > Software design >  Edit operation is not working in Core Data
Edit operation is not working in Core Data

Time:09-23

I'm working on core data crud operation.I've Person object and when user click on add ( ) button user can add the person name and person name will show in tableview. When user click on any tableView cell it shows the alert and current tap cell person show in alert text field and user can edit the name of person but my logic is not working fine and user is not editing.I've one more problem like when i run the app the pervious users record not showing but it will showing after I will enter the new user and fetch all the pervious users see the code and guide me thanks in advance.

ViewController Class:

@IBOutlet weak var tableView: UITableView!
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

var items : [Person] = [] {
    didSet{
        DispatchQueue.main.async {
            self.tableView.reloadData()
        }
    }
}
override func viewDidLoad() {
    super.viewDidLoad()
    self.tableView.delegate = self
    self.tableView.dataSource = self
    tableView.register(UINib(nibName: String(describing: StundentCell.self), bundle: .main), forCellReuseIdentifier: String(describing: StundentCell.self))
   
}
@IBAction func addPerson(_ sender: UIBarButtonItem) {
    showAlert()
}

private  func showAlert(_ title:String = "Add new Item", message: String = "what is your name"){
    let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
    alertController.addTextField()
    let subbmitBtn = UIAlertAction(title: "Add Person", style: .default) { (action) in
        let textField = alertController.textFields![0]
        let newPerson = Person(context:self.context)
        newPerson.name = textField.text
        newPerson.age = 20
        newPerson.gender = "Male"
        do {
            try self.context.save()
        }
        catch{
            
        }
        self.fetchPerople()
        }
    alertController.addAction(subbmitBtn)
    self.present(alertController, animated: true, completion: nil)
    
}

func fetchPerople(){
    do{
        self.items = try context.fetch(Person.fetchRequest())
    }
    catch{
        
    }
}
}

extension ViewController: UITableViewDelegate,UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return items.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    self.configurePersonCell(tableView, cellForRowAt: indexPath)
}


func configurePersonCell(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
    guard let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: StundentCell.self)) as? StundentCell else {return UITableViewCell()}
    cell.studentData = items[indexPath.row]
    cell.delete.tag = indexPath.row
    cell.delete.addTarget(self, action: #selector(deleteRecord(sender:)), for: .touchUpInside)
    return cell
 }

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    var person =  items[indexPath.row].name
    let alertController = UIAlertController(title: "Edit Person", message: "Edit name", preferredStyle: .alert)
    alertController.addTextField()
    let alertField = alertController.textFields![0]
    alertField.text = person
    
    let saveBtn = UIAlertAction(title: "Save", style: .default) { (action) in
        let getName = alertController.textFields![0]
        person = getName.text
        
        do{
            try self.context.save()
        }
        catch{
            
        }
        self.fetchPerople()
    }
    alertController.addAction(saveBtn)
    self.present(alertController, animated: true, completion: nil)
}

func gotoPersonDetails(personData:Person){
   
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 50
}
@objc func deleteRecord(sender: UIButton){
    if items.count > 0{
        let personRemove = self.items[sender.tag]
        self.context.delete(personRemove)
        
        do {
            try self.context.save()
        }
        catch{
            
        }
        self.fetchPerople()
        
    }
}


@IBOutlet weak var tableView: UITableView!
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

var items : [Person] = [] {
    didSet{
        DispatchQueue.main.async {
            self.tableView.reloadData()
        }
    }
}
override func viewDidLoad() {
    super.viewDidLoad()
    self.tableView.delegate = self
    self.tableView.dataSource = self
    tableView.register(UINib(nibName: String(describing: StundentCell.self), bundle: .main), forCellReuseIdentifier: String(describing: StundentCell.self))
   
}
@IBAction func addPerson(_ sender: UIBarButtonItem) {
    showAlert()
}

private  func showAlert(_ title:String = "Add new Item", message: String = "what is your name"){
    let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
    alertController.addTextField()
    let subbmitBtn = UIAlertAction(title: "Add Person", style: .default) { (action) in
        let textField = alertController.textFields![0]
        let newPerson = Person(context:self.context)
        newPerson.name = textField.text
        newPerson.age = 20
        newPerson.gender = "Male"
        do {
            try self.context.save()
        }
        catch{
            
        }
        self.fetchPerople()
        }
    alertController.addAction(subbmitBtn)
    self.present(alertController, animated: true, completion: nil)
    
}

func fetchPerople(){
    do{
        self.items = try context.fetch(Person.fetchRequest())
    }
    catch{
        
    }
   
}


}


extension ViewController: UITableViewDelegate,UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return items.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    self.configurePersonCell(tableView, cellForRowAt: indexPath)
}


func configurePersonCell(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
    guard let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: StundentCell.self)) as? StundentCell else {return UITableViewCell()}
    cell.studentData = items[indexPath.row]
    cell.delete.tag = indexPath.row
    cell.delete.addTarget(self, action: #selector(deleteRecord(sender:)), for: .touchUpInside)
    return cell
 }

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    
    var person =  items[indexPath.row].name
   

    let alertController = UIAlertController(title: "Edit Person", message: "Edit name", preferredStyle: .alert)
    alertController.addTextField()
    let alertField = alertController.textFields![0]
    alertField.text = person
    
    let saveBtn = UIAlertAction(title: "Save", style: .default) { (action) in
        //get the person name in alert text field
        let getName = alertController.textFields![0]
        //edit the name of the person object
        person = getName.text
        
        do{
            try self.context.save()
        }
        catch{
            
        }
        self.fetchPerople()
    }
    alertController.addAction(saveBtn)
    self.present(alertController, animated: true, completion: nil)
}

func gotoPersonDetails(personData:Person){
   
}


func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 50
}
@objc func deleteRecord(sender: UIButton){
    
    /* fro api calling or firebase for deleting the rows in tableview
    if items.count > 0 {
        items.remove(at:sender.tag)
    }
*/
    
    if items.count > 0{
        let personRemove = self.items[sender.tag]
        //remove the person
        self.context.delete(personRemove)
        
        //save the data
        do {
            try self.context.save()
        }
        catch{
            
        }
        //refetch the data
        self.fetchPerople()
        
    }
}

CodePudding user response:

You are modifying the name string but you don't update the record.

Get the whole person

let person = items[indexPath.row] // can be a constant because it's reference type

assign the name to the text field

alertField.text = person.name

and assign the edited name back

let nameField = alertController.textFields![0]
person.name = nameField.text

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let person = items[indexPath.row]
    let alertController = UIAlertController(title: "Edit Person", message: "Edit name", preferredStyle: .alert)
    alertController.addTextField()
    let alertField = alertController.textFields![0]
    alertField.text = person.name
    
    let saveBtn = UIAlertAction(title: "Save", style: .default) { (action) in
        let nameField = alertController.textFields![0]
        person.name = nameField.text
        
        do{
            try self.context.save()
        }
        catch{
            
        }
        self.fetchPerople()
    }
    alertController.addAction(saveBtn)
    self.present(alertController, animated: true, completion: nil)
}
  • Related