删除计划的本地通知 [英] Removing scheduled local notification

查看:50
本文介绍了删除计划的本地通知的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道有很多类似的问题和答案,我都对其进行了审查,但仍然找不到解决方案.尽管已从 UNUserNotificationCenter 中删除了计划的通知,但仍会触发该通知.

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.

我创建本地通知如下:

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 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.

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

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

尝试查找问题时,我已检索所有待处理的通知,并将它们的 identifiers 与我传递给 removePendingNotificationRequests 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?

编辑1

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

To provide a bit more details on app logic and scenarios:

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

  • App creates some events recurring daily, weekly, monthly, etc

为每个事件创建一个通知

For each event a notification is created

通知在事件日期发送

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

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.

编辑2

回复:删除通知时可能出现错别字或逻辑错误的原因-我确信在那里没有错误的原因是,当我没有跳过或编辑事件,而是删除事件时,它就起作用了,即假设活动日期是明天,通知定于明天10:00发出.今天,用户决定甚至根本不希望它并删除了它,所以我运行 func removeExisting(identifierST:String),并且它的工作原理是->明天不会生成该事件的通知.

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.

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

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:

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

Approach 1 - Delete existing notification and create a new one with new identifier and new trigger date - the day after tomorrow

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

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

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

Approach 3 - Delete existing notification and create a new one with the same identifier and new trigger date - the day after tomorrow

这些都不起作用.

推荐答案

首先,让我解释一下为什么您的操作无法正常工作.

First, let me explain why what you're doing is not working.

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

Let's say you have many different dates, for example: April 27th, May 4th, May 11th, May 18th etc..

您将dateComp分配为

You're assigning dateComp as

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

因此,对于上述每个日期,您的dateComp都将如下所示:

so for each of those mentioned dates your dateComp will look like:

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放入触发器中,您是否知道我的处理方式?触发器与您的日期没有任何关系,除了这三个参数外,通过在一周后更改日期,您实际上使用的是完全相同的触发器.

and next you put that dateComp in your trigger, do you see where i'm going with this? Trigger doesn't have anything to do with your date except those three parameters, by changing date week later, you're actually using exactly the same trigger.

将请求添加到通知中心的那一刻,您的通知就设置为在下一个星期一的10:30上显示,而不是在星期一的10:30上显示.

The moment you add your request to notification center your notification is set up to show on NEXT AVAILABLE Monday at 10:30, NOT on your date Monday 10:30.

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

I had the same problem and posted similar question here. From all my research and what others said it is not possible to set up repeated notification from specific future date in current UNNotificationCenter, i will be more than happy if someone could prove me wrong about this.

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

You could set up whole dateComp from your date, for example [.month, .day, .hour, .minute] but then if you set repeat to true it will repeat only on the same [.month, .day, .hour, .minute] which will end up repeating yearly.

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

Solution can be either to set up non-repeating notification for each specific date (there is limit of 64 notifications you can have in the same time) or like in my case set up seven repeating notifications for each weekday and then just remove the one you don't want at a time and add it again some other day but NOT the same day yet because it will be triggered again.

您可以在这里查看我在我的应用中使用过的代码:

You can check out code i used in my app to do that here:

查看全文

登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆