首页 > 解决方案 > 删除计划的本地通知

问题描述

我知道有很多类似的问题和答案,我都查看了它们,但仍然找不到解决方案。尽管从中删除了预定的通知,UNUserNotificationCenter但它仍然会被触发。

我创建本地通知如下:

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是 CoreData 实体上的字符串属性,我在其中存储创建的通知标识符,因此我可以稍后检索它。

上述工作正常,通知在定义的日期和时间安排和交付,所以这里没有问题。

每当我需要删除特定通知时,我都会检索保存的通知标识符 ( notificationUID) 并将其传递给以下函数:

func removeExisting(identifierST: String) {
     UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: [identifierST])
}

在尝试查找问题时,我检索了所有待处理的通知,并将它们identifiersidentifierST我传递给的通知进行了比较removePendingNotificationRequests,它们匹配

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)
        }
})

但是那些被取消的通知仍然被触发,我在这里遗漏了一些明显的东西吗?

编辑 1

要提供有关应用程序逻辑和场景的更多详细信息:

编辑 2

回复:删除通知时可能出现拼写错误或逻辑错误的要点 - 我确定那里没有错误的原因是因为它在我不跳过或编辑事件时有效,但我正在删除它,即假设事件日期是明天,通知定于明天 10:00 送达。今天用户决定他根本不想要这个并删除它,所以我运行func removeExisting(identifierST: String)它并且它工作 - >明天不会生成该事件的通知。

但是,如果用户决定不完全删除,而是明天跳过 1 天,并在后天继续(如果计划是每天),这就是我遇到问题的地方。我尝试通过 3 种方法解决这种情况:

方法 1 - 删除现有通知并使用新标识符和新触发日期创建一个新通知 - 后天

方法 2 - 创建具有相同标识符的通知(假设这不会创建新的但会修改现有的)但新的触发日期 - 后天

方法 3 - 删除现有通知并创建一个具有相同标识符和新触发日期的新通知 - 后天

这些都不起作用。

标签: swiftios13unusernotificationcenter

解决方案


首先,让我解释一下为什么你正在做的事情不起作用。

假设您有许多不同的日期,例如:4 月 27 日、5 月 4 日、5 月 11 日、5 月 18 日等。

您将 dateComp 分配为

dateComp = Calendar.current.dateComponents([.weekday, .hour, .minute], from: myCoreDataEntity.date)

因此对于每个提到的日期,您的 dateComp 将如下所示:

dateComp = [Monday, 10, 30] // April 27th
dateComp = [Monday, 10, 30] // May 4th
dateComp = [Monday, 10, 30] // May 11th
dateComp = [Monday, 10, 30] // May 18th

接下来你把那个 dateComp 放在你的触发器中,你知道我要去哪里吗?除了这三个参数外,触发器与您的日期没有任何关系,通过在一周后更改日期,您实际上使用的是完全相同的触发器。

当您将请求添加到通知中心时,您的通知设置为在下一个可用的星期一 10:30 显示,而不是在您的日期星期一 10:30 显示。

我有同样的问题并在这里发布了类似的问题。根据我的所有研究和其他人所说,不可能在当前的 UNNotificationCenter 中设置从特定未来日期开始的重复通知,如果有人能证明我对此错误,我将非常高兴。

您可以从您的日期设置整个 dateComp,例如 [.month, .day, .hour, .minute] 但如果您将 repeat 设置为 true,它将仅在相同的 [.month, .day, .hour, .minute] 最终将每年重复一次。

解决方案可以是为每个特定日期设置非重复通知(您可以同时拥有 64 个通知的限制),或者在我的情况下为每个工作日设置七个重复通知,然后删除您的通知一次不想要并在另一天再次添加它,但不是同一天,因为它将再次被触发。

你可以在这里查看我在我的应用程序中使用的代码:

如何为任务设置每日本地通知,但在用户完成任务之前不显示


推荐阅读