问题
In my application I allow users to schedule repeating Local Notifications. The issue that I have though (any many others based on looking around) is that nextTriggerDate() always bases its return value on the current time rather than the time at which the notification was scheduled. I've seen suggestions to store a "date" value in the userInfo of the notification but seeing as how the notifications repeat, it doesn't seem like it would be able to keep this date value accurate each time the notification fires. Is there any way to get the actual fire date of a repeating local notification?
func getNotifications(completion: @escaping (Bool)->()){
notificationArray.removeAll()
center.getPendingNotificationRequests { (notifications) in
print("Count: \(notifications.count)")
if notifications.count <= 0{
completion(true)
return
}
for item in notifications {
var nextTrigger = Date()
if let trigger = item.trigger as? UNTimeIntervalNotificationTrigger{
nextTrigger = trigger.nextTriggerDate()!
}else if let trigger = item.trigger as? UNCalendarNotificationTrigger{
nextTrigger = trigger.nextTriggerDate()!
}
}
}
completion(true)
}
回答1:
Confirmed. I ran this code:
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 120, repeats: true)
print("scheduling at", Date())
DispatchQueue.main.asyncAfter(deadline: .now()+15) {
print("checking at", Date())
UNUserNotificationCenter.current().getPendingNotificationRequests {
arr in let arr = arr
if let req = arr[0].trigger as? UNTimeIntervalNotificationTrigger {
let fd = req.nextTriggerDate()
print("trigger date", fd as Any)
}
}
}
// ... proceed to configure and schedule the notification
I also configured my user notification center delegate to receive the notification in the foreground and print the time.
Here's what I saw in the console:
scheduling at 2018-08-01 03:40:36 +0000
checking at 2018-08-01 03:40:51 +0000
trigger date Optional(2018-08-01 03:42:51 +0000)
received notification while active 2018-08-01 03:42:36 +0000
So the trigger date was reported as 2 minutes from when I checked, but the notification actually fired 2 minutes from when I scheduled it.
I'd describe that as a bug!
The one disagreement I'd have with your original question is that I get exactly the same result for a non-repeating UNTimeIntervalNotificationTrigger:
scheduling at 2018-08-01 03:45:50 +0000
checking at 2018-08-01 03:46:06 +0000
trigger date Optional(2018-08-01 03:48:06 +0000)
received notification while active 2018-08-01 03:47:50 +0000
A UNTimeIntervalNotificationTrigger also has a timeInterval
property, but even that does us no good unless we know when the notification was originally scheduled — and a UNNotificationRequest provides no way to find that out.
(Just to be certain, I postponed my checking until the repeating notification had fired a couple of times, but the result was the same: nextTriggerDate
is clearly adding the timeInterval
to now rather than reporting the time at which the notification will next fire.)
回答2:
try using this funcation
func postNotification(yourMessage : String, date : Date){
var count = UIApplication.shared.applicationIconBadgeNumber
count = count + 1
var timeComponents = Calendar.current.dateComponents([.year,.month,.day], from: date)
timeComponents.hour = 06
timeComponents.year = timeComponents.year ?? 0
timeComponents.day = timeComponents.day ?? 0
timeComponents.month = timeComponents.month ?? 0
timeComponents.minute = 00
let content = UNMutableNotificationContent()
content.sound = UNNotificationSound.default()
content.title = "Project Name"
content.body = yourMessage
content.badge = count as NSNumber
let trigger = UNCalendarNotificationTrigger(dateMatching: timeComponents, repeats: false)
let request = UNNotificationRequest(identifier: "To identify push", content: content, trigger: trigger)
// Schedule the request.
let center = UNUserNotificationCenter.current()
center.add(request) { (error : Error?) in
if let theError = error {
print(theError.localizedDescription)
}
}
}
来源:https://stackoverflow.com/questions/51618620/nexttriggerdate-doesnt-return-the-expected-value-is-there-another-way-to-o