I know there are plenty of similar questions and answers, and I reviewed them all, but still cannot find the solution. Despite of removing a scheduled notification from UNUserNotificationCenter
it still gets triggered.
I create local notification as follows:
let aDF = DateFormatter()
aDF.dateFormat = "yyyy-MM-dd HH:mm:ss"
var identifierST = ""
if update == true {
identifierST = myCoreDataEntity.notificationUID!
} else {
identifierST = aDF.string(from: Date())
}
let notif = UNMutableNotificationContent()
notif.title = "some string"
notif.body = "some string"
var dateComp: DateComponents
switch myCoreDataEntity.schedule {
case 1: //daily
dateComp = Calendar.current.dateComponents([.hour, .minute], from: myCoreDataEntity.date)
case 2: //weekly
dateComp = Calendar.current.dateComponents([.weekday, .hour, .minute], from: myCoreDataEntity.date)
case 3: //monthly
dateComp = Calendar.current.dateComponents([.day, .hour, .minute], from: myCoreDataEntity.date)
case 4: //quartely - this is actually not quarterly, dont know how to set quarterly, setting monthly
dateComp = Calendar.current.dateComponents([.day, .hour, .minute], from: myCoreDataEntity.date)
case 5: //halfyearly - this is actually not halfyearly, dont know how to set halfyearly, setting monthly
dateComp = Calendar.current.dateComponents([.day, .hour, .minute], from: myCoreDataEntity.date)
case 6: //yearly
dateComp = Calendar.current.dateComponents([.month, .day, .hour, .minute], from: myCoreDataEntity.date)
default: //monthly
dateComp = Calendar.current.dateComponents([.day, .hour, .minute], from: myCoreDataEntity.date)
}
dateComp.hour = 10
dateComp.minute = 0
let notificationTrigger = UNCalendarNotificationTrigger(dateMatching: dateComp, repeats: true)
let request = UNNotificationRequest.init(identifier: timeStampST, content: notif, trigger: notificationTrigger)
UNUserNotificationCenter.current().add(request) { (error) in
if (error != nil) {
print (error) //notify user that reminder was not saved
} else {
myCoreDataEntity.notificationUID = identifierST
}
}
notificationUID
is a String Attribute on a CoreData Entity where I store created notification identifier, so I could retrieve it later.
The above works correctly, notification is scheduled and delivered on defined date and time, so no problem here.
Whenever I need to remove a particular notification, I retrieve saved notification identifier (notificationUID
) and pass it to the following function:
func removeExisting(identifierST: String) {
UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: [identifierST])
}
When trying to find the issue, I've retrieved all pending notifications and compared their identifiers
with the identifierST
I am passing to removePendingNotificationRequests
and they match
UNUserNotificationCenter.current().getPendingNotificationRequests(completionHandler: { requests in
for request in requests {
print("==============================================")
print(request.identifier)
print(request.content.title)
print(request.content.subtitle)
print(request.content.body)
}
})
But those cancelled notifications are still being triggered, am I missing something obvious here?
Edit 1
To provide a bit more details on app logic and scenarios:
App creates some events recurring daily, weekly, monthly, etc
For each event a notification is created
Notification is sent on the date of event
The user can see upcoming events and can chose to skip one cycle => this is were the problem is -> when user choses to skip, I run the
func removeExisting(identifierST: String)
to remove it, but when the date of that skipped event comes, the notification is still being sent.
Edit 2
Re: the point on possible typo or logic mistake while removing the notification - the reason I am sure there is no mistake there, is because it works when I am not skipping or editing the event, but I am deleting it, i.e. let's say event date is tomorrow and notification is scheduled to be delivered tomorrow at 10:00. Today user decides that he does not want this even at all and deletes it, so I run func removeExisting(identifierST: String)
and it works -> no notification of that event is generated tomorrow.
But, if the user decides not to delete completely, but just skip 1 day tomorrow, and continue with it the day after tomorrow (in cases when schedule is daily) this is where I get the problem. I've tried to address this scenario in 3 approaches:
Approach 1 - Delete existing notification and create a new one with new identifier and new trigger date - the day after tomorrow
Approach 2 - Create notification with the same identifier (assuming that this will not create a new one but will modify the existing one) but new trigger date - the day after tomorrow
Approach 3 - Delete existing notification and create a new one with the same identifier and new trigger date - the day after tomorrow
None of this works.