Search code examples
iosswifttableviewreloaddataswift4.2

How to delete from tableview as well as sqlite3 using Swift


I'm new to swift and sqlite3 and I need help on how to delete from tableview and sql db.

I tried to use reloadData() but it doesn't work. I tried to delete using tableView.deleteRows(at: [indexPath], with: .fade) but Im getting an error as I have a sql delete statement running before that. With this code provided below, Im successfully able to remove the item from the database, but it doesn't refresh the tableview. The way I got around to fixing it temporarily is perform a segue to previous screen upon successful removal of an item and when returned to the tableviewcontroller it would be removed.

import UIKit

class TableViewController: UIViewController,UITableViewDataSource,UITableViewDelegate {

    let mainDelegate = UIApplication.shared.delegate as! AppDelegate
    @IBOutlet var tableView: UITableView!
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let tableCell = tableView.dequeueReusableCell(withIdentifier: "cell") as? SiteCell ?? SiteCell(style: .default, reuseIdentifier: "cell")
        let rowNum = indexPath.row
        tableCell.primaryLabel.text = mainDelegate.people[rowNum].name
        tableCell.secondaryLabel.text = mainDelegate.people[rowNum].email
        tableCell.myImageView.image = UIImage(named: mainDelegate.people[rowNum].avatar!)
        tableCell.accessoryType = .disclosureIndicator
        return tableCell
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return mainDelegate.people.count
    }
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 70
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        let rowNum = indexPath.row
        let details : String! =  "Address: \(mainDelegate.people[rowNum].address!) \nPhone Num: \(mainDelegate.people[rowNum].phonenum!) \nEmail: \(mainDelegate.people[rowNum].email!) \nAge: \(mainDelegate.people[rowNum].age!) \nGender: \(mainDelegate.people[rowNum].gender!) \nDate of birth: \(mainDelegate.people[rowNum].dob!)"
        let alertController = UIAlertController(title: mainDelegate.people[rowNum].name, message: details, preferredStyle: .alert
        )
        let cancelAction = UIAlertAction(title: "ok", style: .cancel, handler: nil)
        print("TESTING ROW: \(mainDelegate.people[rowNum].id!)")
        alertController.addAction(cancelAction)
        present(alertController, animated: true)
    }

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
    var rowNum: Int = indexPath.row
        if editingStyle == .delete {
            print("Testing delete \(mainDelegate.people[rowNum].id!)")
            print("\(indexPath.row)")

            mainDelegate.removeFromDatabase(id: mainDelegate.people[rowNum].id!)
            print("\(indexPath)")
//            tableView.deleteRows(at: [indexPath], with: .fade)

            DispatchQueue.main.async{
                self.tableView.reloadData()
            }
//            self.performSegue(withIdentifier: "DataToInfo", sender: self)

//          let mainDelegate = UIApplication.shared.delegate as! AppDelegate
//          mainDelegate.removeFromDatabase(person: mainDelegate.people[indexPath.row])
            }
    }
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        mainDelegate.readDataFromDatabase()
    }

removeFromDatabase method

func removeFromDatabase(id : Int){

        var db : OpaquePointer? = nil

        if sqlite3_open(self.databasePath, &db) == SQLITE_OK{

            print("Successfully opened connection to database at \(self.databasePath)")
            var deleteStatement : OpaquePointer? = nil
            let deleteStatementString : String = "delete from entries where id=\(id)"
            if sqlite3_prepare_v2(db, deleteStatementString, -1, &deleteStatement, nil) == SQLITE_OK{
                if sqlite3_step(deleteStatement) == SQLITE_DONE{
                    print("Deleted")
                }
                else{
                    print("Failed")
                }
            }else{
                print("Couldn't prepare")
            }
            sqlite3_finalize(deleteStatement)

            sqlite3_close(db)
        }
    }

Im trying to delete it from tableview as well as database. At one point I was trying to mainDelegate.people.remove(at: indexPath.row) tableView.deleteRows(at: [indexPath], with: .fade) then running the removeFromDatabase, but it was giving me an error.


Solution

  • You should update your datasource. Try to refactor your commitEditing like this:

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
    var rowNum: Int = indexPath.row
        if editingStyle == .delete {
            print("Testing delete \(mainDelegate.people[rowNum].id!)")
            print("\(indexPath.row)")
    
            mainDelegate.removeFromDatabase(id: mainDelegate.people[rowNum].id!)
            print("\(indexPath)")
    
    
            mainDelegate.readDataFromDatabase()
    
    
            tableView.deleteRows(at: [indexPath], with: .fade)
    
    
            }
    }