删除计划的本地通知

时间:2020-04-22 08:51:27

标签: swift ios13 unusernotificationcenter

我知道有很多类似的问题和答案,我都对其进行了审查,但仍然找不到解决方案。尽管从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])
}

尝试查找问题时,我已检索了所有待处理的通知,并将它们的identifiers与我传递给identifierST的{​​{1}}进行了比较,

removePendingNotificationRequests

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

编辑1

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

  • App创建一些每天,每周,每月等重复发生的事件

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

  • 通知在事件日期发送

  • 用户可以看到即将发生的事件,并可以选择跳过一个周期=>这是问题所在->当用户选择跳过时,我运行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) } }) 将其删除,但是当跳过事件的日期到来,通知仍在发送。

编辑2

回复:删除通知时可能出现错别字或逻辑错误的原因-我确定在那里没有错误的原因是,当我不跳过或编辑事件,而是删除事件时,它可以工作,即假设活动日期是明天,通知定于明天10:00发出。今天,用户决定甚至根本不需要它,然后将其删除,因此我运行func removeExisting(identifierST: String),它可以正常工作->明天不会生成该事件的通知。

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

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

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

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

这些都不起作用。

3 个答案:

答案 0 :(得分:1)

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

假设您有许多不同的日期,例如: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个通知),或者像我这样,在每个工作日设置七个重复通知,然后删除一次您不想要的那个,然后再改天再添加一次,但又不是同一天,因为它将再次被触发。

您可以在此处查看我在应用程序中使用过的代码:

How to set up daily local notification for tasks but don't show it when user completes the task before

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

我现在再次观看了相关的WWDC视频-https://developer.apple.com/videos/play/wwdc2016/707-并稍微改变了逻辑。

原始方法

当用户跳过一个周期时,我将删除计划的通知并创建一个具有新标识符和新触发日期的新通知。

新方法

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