Update And Delete Operations Using Core Data Framework

In my last articles, we created a simple application in which we inserted the details into the database and displayed them on a UITableView. In this article, we will implement the next 2 operations; i.e. Update and Delete, finally completing all the CRUD operations.
 
If you want to have a look at my previous two articles, then you can refer  to the following links,
  • Open the project in which we had implemented the Add and Display Operations in XCode. 
  • Our application takes Name, Age and Phone Number as inputs from the user and saves the record into our database. 
Update And Delete Operations Using Core Data Framework
  • Also, it displays the database records in a table.
Update And Delete Operations Using Core Data Framework
  • So let's perform the Delete operation first.
  • In the ViewController, we had added some tableView functions. Similiarly we will add one more tableView function.
  • Type 'commit' in your ViewController and XCode will display a list of tableView functions. Select the tableView function containing 'commit editingStyle'. By default, it must be highlighted at the top of the list displayed by XCode.

    Update And Delete Operations Using Core Data Framework

  • This function is used to add a sliding functionality to the tableview cells which gives an impressive look and feel to our application.
  • It contains sliding functionality for Insert/Edit and Delete operations. Here, we are using this sliding functionality only for Delete operation.
  • Paste the below code in this function.
    1. func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {  
    2.     guard  
    3.     let appDelegate = UIApplication.shared.delegate as ? AppDelegate  
    4.     else {  
    5.         return  
    6.     }  
    7.     let managedContext = appDelegate.persistentContainer.viewContext  
    8.     let person = details[indexPath.row]  
    9.     if editingStyle == .delete {  
    10.         managedContext.delete(person as NSManagedObject)  
    11.         details.remove(at: indexPath.row)  
    12.         do {  
    13.             try managedContext.save()  
    14.         } catch  
    15.         let error as NSError {  
    16.             print("Could not save. \(error),\(error.userInfo)")  
    17.         }  
    18.         self.tableView.deleteRows(at: [indexPath], with: .fade)  
    19.     }  
    20. }  
  • Now run the application and check if it works. Slide the tableview cell from right to left that you want to delete.
  • Here, I am deleting the second record. On sliding, the record gets deleted.
Update And Delete Operations Using Core Data Framework
  • Stop and re-run the application and check if the record that you had deleted is now visible on the table or not. If not, then we have successfully achieved the Delete operation.
  •  So now, our application is successfully implemented with the Create, Read and Delete operations. So let's move to the final operation; i.e. Update.
  • In my application, I am going to use a UIAlertController for the Update operation.
  • When I select a particular row from my tableview, an alert box must popup which will ask the user to enter the details and will update them.
  • For this, we will add another tableView function as we had added for the Delete operation.
  • Type 'didSelectRowAt' and the XCode will display the tableView function containing didSelectRowAt. Select this function.
Update And Delete Operations Using Core Data Framework
  • This function allows you to select any particular row from the tableview and implement whatever you wish to do with them.
  • Paste the following code inside this function.
    1. func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {  
    2.     let person = details[indexPath.row]  
    3.     let alert = UIAlertController(title: "Update Details", message: "Update Name, Age & Phone No.", preferredStyle: .alert)  
    4.     // Enter button  
    5.     let updateAction = UIAlertAction(title: "Update", style: .default, handler: {  
    6.         (action) - > Void in  
    7.         // Get TextFields text  
    8.         guard  
    9.         let newUsernameTxt = alert.textFields?.first,  
    10.             let newUsername = newUsernameTxt.text  
    11.         else {  
    12.             return  
    13.         }  
    14.         guard  
    15.         let newAgeTxt = alert.textFields ? [1],  
    16.             let newAge = Int16(newAgeTxt.text!)  
    17.         else {  
    18.             return  
    19.         }  
    20.         guard  
    21.         let newPhoneTxt = alert.textFields ? [2],  
    22.             let newPhone = Int32(newPhoneTxt.text!)  
    23.         else {  
    24.             return  
    25.         }  
    26.         self.updateData(newName: newUsername, newAge: newAge, newPhone: newPhone, person: person as!Details)  
    27.         self.tableView.reloadData()  
    28.     })  
    29.     // Add 1 textField (for name)  
    30.     alert.addTextField {  
    31.         (textField: UITextField) in textField.placeholder = "Update Name"  
    32.     }  
    33.     // Add 2 textField (for age)  
    34.     alert.addTextField {  
    35.         (textField: UITextField) in textField.placeholder = "Update Age"  
    36.     }  
    37.     // Add 3 textField (for phone no)  
    38.     alert.addTextField {  
    39.         (textField: UITextField) in textField.placeholder = "Update Phone No"  
    40.     }  
    41.     let cancelAction = UIAlertAction(title: "Cancel", style: .default)  
    42.     alert.addAction(updateAction)  
    43.     alert.addAction(cancelAction)  
    44.     present(alert, animated: true, completion: nil)  
    45. }  
  • This code consists of the implementation of alert box with 3 text fields inside it. When you enter the details inside this alert box and press Update, the updateData function called inside this code will replace the selected row with the updated details that you have entered. For this, we need to add an updateData function too.
  • Create a function updateData() inside your ViewController and paste the following code.
    1. func updateData(newName: String, newAge: Int16, newPhone: Int32, person: Details) {  
    2.     guard  
    3.     let appDelegate = UIApplication.shared.delegate as ? AppDelegate  
    4.     else {  
    5.         return  
    6.     }  
    7.     let context = appDelegate.persistentContainer.viewContext  
    8.     do {  
    9.         person.setValue(newName, forKey: "name")  
    10.         person.setValue(newAge, forKey: "age")  
    11.         person.setValue(newPhone, forKey: "phone")  
    12.         do {  
    13.             try context.save()  
    14.             print("Details Updated!")  
    15.         } catch  
    16.         let error as NSError {  
    17.             print("Could not save \(error), \(error.userInfo)")  
    18.         } catch {}  
    19.     } catch {  
    20.         print("Error with request: \(error)")  
    21.     }  
    22. }  
  • Here is the whole ViewController.swift file containing all the codes.
    1. import UIKit  
    2. import CoreData  
    3. class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {  
    4.     var details: [NSManagedObject] = []  
    5.     @IBOutlet weak  
    6.     var tableView: UITableView!@IBOutlet weak  
    7.     var txtPhoneNo: UITextField!@IBOutlet weak  
    8.     var txtAge: UITextField!@IBOutlet weak  
    9.     var txtName: UITextField!@IBOutlet weak  
    10.     var lblPhoneNo: UILabel!@IBOutlet weak  
    11.     var lblAge: UILabel!@IBOutlet weak  
    12.     var lblName: UILabel!override func viewDidLoad() {  
    13.         super.viewDidLoad()  
    14.         tableView.register(UINib(nibName: "DetailsTableViewCell", bundle: nil), forCellReuseIdentifier: "details")  
    15.     }  
    16.     override func viewWillAppear(_ animated: Bool) {  
    17.         super.viewWillAppear(animated)  
    18.         //1  
    19.         guard  
    20.         let appDelegate = UIApplication.shared.delegate as ? AppDelegate  
    21.         else {  
    22.             return  
    23.         }  
    24.         let managedContext = appDelegate.persistentContainer.viewContext  
    25.         //2  
    26.         let fetchRequest = NSFetchRequest < NSManagedObject > (entityName: "Details")  
    27.         //3  
    28.         do {  
    29.             details =  
    30.                 try managedContext.fetch(fetchRequest)  
    31.         } catch  
    32.         let error as NSError {  
    33.             print("Could not fetch. \(error), \(error.userInfo)")  
    34.         }  
    35.     }  
    36.     @IBAction func btnAdd(_ sender: Any) {  
    37.         //1  
    38.         guard  
    39.         let appDelegate = UIApplication.shared.delegate as ? AppDelegate  
    40.         else {  
    41.             return  
    42.         }  
    43.         let managedContext = appDelegate.persistentContainer.viewContext  
    44.         //2  
    45.         let entity = NSEntityDescription.entity(forEntityName: "Details"in : managedContext) !  
    46.             //3  
    47.             let record = NSManagedObject(entity: entity, insertInto: managedContext)  
    48.         //4  
    49.         record.setValue(txtName.text, forKey: "name")  
    50.         record.setValue(Int16(txtAge.text!), forKey: "age")  
    51.         record.setValue(Int16(txtPhoneNo.text!), forKey: "phone")  
    52.         do {  
    53.             try managedContext.save()  
    54.             details.append(record)  
    55.             print("Record Added!")  
    56.             //To display an alert box  
    57.             let alertController = UIAlertController(title: "Message", message: "Record Added!", preferredStyle: .alert)  
    58.             let OKAction = UIAlertAction(title: "OK", style: .default) {  
    59.                 (action: UIAlertAction!) in  
    60.             }  
    61.             alertController.addAction(OKAction)  
    62.             self.present(alertController, animated: true, completion: nil)  
    63.         } catch  
    64.         let error as NSError {  
    65.             print("Could not save. \(error),\(error.userInfo)")  
    66.         }  
    67.         self.tableView.reloadData()  
    68.     }  
    69.     func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) - > Int {  
    70.         return details.count  
    71.     }  
    72.     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) - > UITableViewCell {  
    73.         let person = details[indexPath.row]  
    74.         let cell = tableView.dequeueReusableCell(withIdentifier: "details",  
    75.             for: indexPath) as!DetailsTableViewCell  
    76.         cell.tblLblName?.text = (person.value(forKey: "name") ? ? "-") as ? String  
    77.         cell.tblLblAge?.text = String(describing: person.value(forKey: "age") ? ? "-")  
    78.         cell.tblLblPhoneNo?.text = String(describing: person.value(forKey: "phone") ? ? "-")  
    79.         return cell  
    80.     }  
    81.     func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {  
    82.         guard  
    83.         let appDelegate = UIApplication.shared.delegate as ? AppDelegate  
    84.         else {  
    85.             return  
    86.         }  
    87.         let managedContext = appDelegate.persistentContainer.viewContext  
    88.         let person = details[indexPath.row]  
    89.         if editingStyle == .delete {  
    90.             managedContext.delete(person as NSManagedObject)  
    91.             details.remove(at: indexPath.row)  
    92.             do {  
    93.                 try managedContext.save()  
    94.             } catch  
    95.             let error as NSError {  
    96.                 print("Could not save. \(error),\(error.userInfo)")  
    97.             }  
    98.             self.tableView.deleteRows(at: [indexPath], with: .fade)  
    99.         }  
    100.     }  
    101.     func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {  
    102.         let person = details[indexPath.row]  
    103.         let alert = UIAlertController(title: "Update Details", message: "Update Name, Age & Phone No.", preferredStyle: .alert)  
    104.         // Enter button  
    105.         let updateAction = UIAlertAction(title: "Update", style: .default, handler: {  
    106.             (action) - > Void in  
    107.             // Get TextFields text  
    108.             guard  
    109.             let newUsernameTxt = alert.textFields?.first,  
    110.                 let newUsername = newUsernameTxt.text  
    111.             else {  
    112.                 return  
    113.             }  
    114.             guard  
    115.             let newAgeTxt = alert.textFields ? [1],  
    116.                 let newAge = Int16(newAgeTxt.text!)  
    117.             else {  
    118.                 return  
    119.             }  
    120.             guard  
    121.             let newPhoneTxt = alert.textFields ? [2],  
    122.                 let newPhone = Int32(newPhoneTxt.text!)  
    123.             else {  
    124.                 return  
    125.             }  
    126.             self.updateData(newName: newUsername, newAge: newAge, newPhone: newPhone, person: person as!Details)  
    127.             self.tableView.reloadData()  
    128.         })  
    129.         // Add 1 textField (for name)  
    130.         alert.addTextField {  
    131.             (textField: UITextField) in textField.placeholder = "Update Name"  
    132.         }  
    133.         // Add 2 textField (for age)  
    134.         alert.addTextField {  
    135.             (textField: UITextField) in textField.placeholder = "Update Age"  
    136.         }  
    137.         // Add 3 textField (for phone no)  
    138.         alert.addTextField {  
    139.             (textField: UITextField) in textField.placeholder = "Update Phone No"  
    140.         }  
    141.         let cancelAction = UIAlertAction(title: "Cancel", style: .default)  
    142.         alert.addAction(updateAction)  
    143.         alert.addAction(cancelAction)  
    144.         present(alert, animated: true, completion: nil)  
    145.     }  
    146.     func updateData(newName: String, newAge: Int16, newPhone: Int32, person: Details) {  
    147.         guard  
    148.         let appDelegate = UIApplication.shared.delegate as ? AppDelegate  
    149.         else {  
    150.             return  
    151.         }  
    152.         let context = appDelegate.persistentContainer.viewContext  
    153.         do {  
    154.             person.setValue(newName, forKey: "name")  
    155.             person.setValue(newAge, forKey: "age")  
    156.             person.setValue(newPhone, forKey: "phone")  
    157.             do {  
    158.                 try context.save()  
    159.                 print("Details Updated!")  
    160.             } catch  
    161.             let error as NSError {  
    162.                 print("Could not save \(error), \(error.userInfo)")  
    163.             } catch {}  
    164.         } catch {  
    165.             print("Error with request: \(error)")  
    166.         }  
    167.     }  
    168. }  
  • We are done! Let's run the application and check if it works. 
Update And Delete Operations Using Core Data Framework
  • As you can see, in the above image, I have selected my first row; i.e the details of 'Anna' .We can see an alert box titled 'Update Details' with 3 text fields inside it. I am updating all 3 fields with the new data.
Update And Delete Operations Using Core Data Framework 
  • After clicking on Update, the entire row is replaced by my new updated details.
  • Hence, we have successfully implemented the Update operation and with this, we have implemented all the CRUD operations using Core Data Framework!  
  • In my next article, we will implement an alternate method for Update operations. Instead of displaying an alert box to update details, we will update our details using ID.