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个通知)或者像在我的例子中,为每个工作日设置七个重复通知,然后一次删除一个你不想要的通知,并在另一天再次添加,但不是在同一天,因为它将被触发