0

I am scheduling notifications with Unique Identifiers so I don't have to make a new String for each notification. This all works well for scheduling but the problem lies in trying to cancel them.

This is my code for scheduling notifications...

let notifIdentifier = TaskManager.notification2.userInfo.description as String!
let trigger = UNCalendarNotificationTrigger(dateMatching: components , repeats: true)
let request = UNNotificationRequest(identifier: notifIdentifier! , content: TaskManager.notification2, trigger: trigger)
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)

This is the code for cancelling notifications ...

// Deletion of Cells ...

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    
    let managedObject: NSManagedObject = frc.object(at: indexPath) as! NSManagedObject
    context.delete(managedObject)
    if tableView == TaskTableViews {
    let itemController = TaskManager()
    let nItem: List = frc.object(at: indexPath) as! List
    itemController.nItem = nItem
    UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: [itemController.notifIdentifier!] )

When I try to cancel them, they are very hit and miss. I have tested the code by changing the identifier to a regular String and everything works as it should so its definitely the unique identifier.

Any thoughts/ suggestions on creating a unique ID for every new task/notification?

shim
  • 9,289
  • 12
  • 69
  • 108
Tai
  • 25
  • 1
  • 6
  • What's the problem? What does "they are very hit and miss" even _mean?_ Explain what the issue is, please. What is a TaskManager, anyway? – matt Jan 29 '17 at 23:11
  • Only one notification can be cancelled at a time (not multiple). If you schedule a notification, close the app, then later reopen the app to delete the task, the notification isn't cancelled. Like I said this all works perfectly with a String but using a unique ID is my problem. Im looking for another way to create unique IDs for each task. – Tai Jan 29 '17 at 23:25
  • "all works perfectly with a String but using a unique ID is my problem" I can't figure out what that means either. The identifier _is_ a String, so I don't get what distinction you are drawing. And you have not shown how your identifiers are created and stored, so who knows what you're doing? The entire question, so far, is completely unclear (to me at least). – matt Jan 29 '17 at 23:42
  • OK to create a unique string, I am using TaskManager.notification2.userInfo.description as String! instead of making up a String such as "Whatever" for the UNNotifcationRequest – Tai Jan 29 '17 at 23:45
  • But you have not shown what a TaskManager is. Why should I believe that `TaskManager.notification2.userInfo.description as String!` generates the _same_ identifier both when you create the notification and later when you try to cancel it? – matt Jan 29 '17 at 23:50
  • 1
    The question was, "creating a unique identifier for notifications" not can you critique my code. Next time try answering the question instead of critiquing code. If you can't answer the question, move on. – Tai Jan 30 '17 at 18:56

1 Answers1

0

Scheduling notifications

@IBAction func scheduleNotification(_ sender: AnyObject) {

    let uuid = UUID().uuidString


    let content = UNMutableNotificationContent()
    content.title = NSString.localizedUserNotificationString(forKey: "Example", arguments: nil)
    content.sound = UNNotificationSound.default()
    //...

    var dateComponents = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute], from: self.datePicker.date)
    dateComponents.second = 0

    let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: false)

    let request = UNNotificationRequest(identifier: uuid, content: content, trigger: trigger)

    UNUserNotificationCenter.current().add(request) { (error) in

        if let errorPerforms = error {
         print(errorPerforms.localizedDescription)
        } else {
         print("Success")
        }
    }


    let managedObject = ManagedObject(context: self.managedObjectContext!)
    managedObject.setValue(uuid, forKey: "uuid")
    //...

    do {
     try self.managedObjectContext.save()
        self.dimiss()
    } catch {}
}

Delete notifications from the indexPath.

 // Override to support editing the table view.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {

    switch editingStyle {
    case .delete:

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

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

        do {
         try self.managedObjectContext.save()
            self.tableView.reloadData()
        } catch {}

    default:
        break
    }

}

This works well! When you're using the NSFetchedResultsControllerDelegate protocol methods. Hope it helps

Mannopson
  • 2,634
  • 1
  • 16
  • 32