Swift 删除计划的本地通知

Swift 删除计划的本地通知,swift,ios13,unusernotificationcenter,Swift,Ios13,Unusernotificationcenter,我知道有很多类似的问题和答案,我把它们都复习了一遍,但仍然找不到解决办法。尽管从UNUserNotificationCenter删除了计划通知,但仍会触发该通知 我创建本地通知如下: let aDF = DateFormatter() aDF.dateFormat = "yyyy-MM-dd HH:mm:ss" var identifierST = "" if update == true { identifierST = myCoreDataEntity.notific

我知道有很多类似的问题和答案,我把它们都复习了一遍,但仍然找不到解决办法。尽管从
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])
}
在尝试查找问题时,我检索了所有挂起的通知,并将它们的
标识符
与我传递给
removePendingNotificationRequests的
标识符ST
进行了比较,它们匹配

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

要提供有关应用程序逻辑和场景的更多详细信息,请执行以下操作:

  • 应用程序创建一些每天、每周、每月重复发生的事件,等等

  • 为每个事件创建一个通知

  • 在事件发生之日发送通知

  • 用户可以看到即将发生的事件,并可以选择跳过一个周期=>这就是问题所在->当用户选择跳过时,我运行
    func removeExisting(identifierST:String)
    将其删除,但当跳过事件的日期到来时,仍会发送通知

编辑2

Re:删除通知时可能出现的打字错误或逻辑错误——我确信没有错误的原因是,当我没有跳过或编辑事件,但我正在删除它时,它会起作用,也就是说,事件日期是明天,通知计划在明天10:00发送。今天,用户决定他根本不想要这个,并将其删除,所以我运行
func removeExisting(identifierST:String)
,它可以工作->明天不会生成该事件的通知

但是,如果用户决定不完全删除,而只是明天跳过一天,然后在后天继续删除(在日程安排是每天的情况下),这就是我遇到的问题。我尝试用3种方法解决这个问题:

方法1删除现有通知,并在后天创建一个新通知,其中包含新标识符和新触发日期

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

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


所有这些都不起作用。

你的意思是,你调用getPendingNotificationRequests而不再看到你删除的请求?那么,您确定要添加的代码在此之后不会被意外调用吗?(因此可以再次添加它?)


UNUserNotificationCenter.current().add()
的一个功能是,如果已计划了具有所需ID的通知,则它不会同时计划另一个通知,但也不会给出错误。你可以认为它覆盖了现有的一个。因此,如果您的代码以某种方式一次又一次地调度相同的通知,您可能不会注意到。直到您尝试删除通知,然后它们被重新安排。

我现在又看了一段与WWDC相关的视频,并稍微改变了逻辑

原始方法

当用户跳过一个周期时,我将删除计划通知并创建一个新通知,其中包含新标识符和新触发日期

新方法


当用户跳过一个周期时,我不会删除任何内容,而是使用相同的标识符创建一个具有新触发日期的“新”通知。我从视频中了解到,使用相同的标识符实际上并不是创建新的通知,而是更新现有的通知。我将能够在24小时内确认这是否有效。

首先,让我解释一下为什么您所做的不起作用

假设您有许多不同的日期,例如: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显示

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

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

解决方案可以是为每个特定日期设置非重复通知(同一时间最多可以有64个通知)或者像在我的例子中,为每个工作日设置七个重复通知,然后一次删除一个你不想要的通知,并在另一天再次添加,但不是在同一天,因为它将被触发