Search code examples
swiftcore-datausernotificationsdo-catch

The do statement


Let's say this is our function for delete objects from the model:

func delete(indexPath: IndexPath) {

    let managedObject = self.fetchedResultsController.object(at: indexPath)
    self.managedObjectContext.delete(managedObject)

    do {

        // Save changes
        try self.managedObjectContext.save()

        // Cancel the notification
        let center = UNUserNotificationCenter.current()
        center.removeDeliveredNotifications(withIdentifiers: [managedObject.uuid!])
        center.removePendingNotificationRequests(withIdentifiers: [managedObject.uuid!])

        // Reload tableView
        self.tableView.reloadData()

    } catch {

        let alertController = UIAlertController.init(title: "Error", message: "We are sorry! Unknown error occured...", preferredStyle: .alert)
        alertController.addAction(UIAlertAction.init(title: "Close", style: .default, handler: { (action) in
            // Completion handler
        }))
        self.present(alertController, animated: true, completion: {
            // Completion block
        })
    }
}

Question:

If an error thrown, execution transfers to the catch clauses. That's nice. But what happens with the statements ( rest of the code, Cancel the notification and Reload tableView ) ? Those statements are still executable or simple ignored?


Solution

  • If you want your code to still be called even if an error is thrown, you can either create a separate function for it, and call it from the end of both do and catch statement. Or you can put that code in a defer statement.

    Either something like

    func delete(indexPath: IndexPath) {
    
    let managedObject = self.fetchedResultsController.object(at: indexPath)
    self.managedObjectContext.delete(managedObject)
    
    do {
    
        // Save changes
        try self.managedObjectContext.save()
        reloadCode()
    
    } catch {
        reloadCode()
        let alertController = UIAlertController.init(title: "Error", message: "We are sorry! Unknown error occured...", preferredStyle: .alert)
        alertController.addAction(UIAlertAction.init(title: "Close", style: .default, handler: { (action) in
            // Completion handler
        }))
        self.present(alertController, animated: true, completion: {
            // Completion block
        })
    }
    }
    
    func reloadCode() {
            // Cancel the notification
            let center = UNUserNotificationCenter.current()
            center.removeDeliveredNotifications(withIdentifiers: [managedObject.uuid!])
            center.removePendingNotificationRequests(withIdentifiers: [managedObject.uuid!])
    
            // Reload tableView
            self.tableView.reloadData()
    
    }
    

    Or more neatly,

    func delete(indexPath: IndexPath) {
    
    let managedObject = self.fetchedResultsController.object(at: indexPath)
    self.managedObjectContext.delete(managedObject)
    
    
      defer {
     let center = UNUserNotificationCenter.current()
            center.removeDeliveredNotifications(withIdentifiers: [managedObject.uuid!])
            center.removePendingNotificationRequests(withIdentifiers: [managedObject.uuid!])
    
            // Reload tableView
            self.tableView.reloadData()
    }
    do {
    
        // Save changes
        try self.managedObjectContext.save()
    
        // Cancel the notification
    
    
    } catch {
    
        let alertController = UIAlertController.init(title: "Error", message: "We are sorry! Unknown error occured...", preferredStyle: .alert)
        alertController.addAction(UIAlertAction.init(title: "Close", style: .default, handler: { (action) in
            // Completion handler
        }))
        self.present(alertController, animated: true, completion: {
            // Completion block
        })
      }
    }