I'm working on local notification scheduling module for iOS 10 which repeats local notification for example every Sunday or every Monday..etc. Lets say i scheduled a notification for this date which is 2016-12-27 10:53:22 +0000
and using UNCalendarNotificationTrigger
with repeat value equals true, the notification get triggered for ones in that date, and it doesn't repeat next week at the same time.
What could be the reason for that? and how is it possible to repeat every week for specific day in iOS 10.
Here is the code for creating local notification:
let content = UNMutableNotificationContent()
content.title = object.title
content.body = object.body
content.sound = UNNotificationSound.default()
let date = object.fireDate
let triggerDate = Calendar.current.dateComponents([.year,.month,.day,.hour,.minute,.second,], from: date as Date)
let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDate,
repeats: true)
// Swift
let identifier = object.id
let request = UNNotificationRequest(identifier: identifier,
content: content, trigger: trigger)
localNotification.add(request, withCompletionHandler: { (error) in
if error != nil {
// Something went wrong
print(error!)
}else {
print("Reminder \(object.id) has been added successfully at \(object.fireDate)")
}
})
Update:
I have also discovered after the notification get fired at that date and to check that there is no more pending notification exist or to check if it has been rescheduled again or not. actually with repeat equals true, it has not been scheduled again for next week.
UNUserNotificationCenter.current().getPendingNotificationRequests(completionHandler: { (notficiations) in
for localNotification in notficiations {
print(localNotification)
}
})
And the result was:
<UNNotificationRequest: 0x174223ca0; identifier: A1, content: <UNNotificationContent: 0x1742e2980; title: My Title, subtitle: (null), body: My Body, categoryIdentifier: , launchImageName: , peopleIdentifiers: (
), threadIdentifier: , attachments: (
), badge: (null), sound: <UNNotificationSound: 0x1740b1820>, hasDefaultAction: YES, shouldAddToNotificationsList: YES, shouldAlwaysAlertWhileAppIsForeground: NO, shouldLockDevice: NO, shouldPauseMedia: NO, isSnoozeable: NO, fromSnooze: NO, darwinNotificationName: (null), darwinSnoozedNotificationName: (null), trigger: <UNCalendarNotificationTrigger: 0x174223cc0; dateComponents: <NSDateComponents: 0x17415e140>
Calendar Year: 2016
Month: 12
Day: 27
Hour: 14
Minute: 46
Second: 15, repeats: YES>>
I don't know if its actually a bug in iOS or not.
Triggering date format is not proper to repeat notification in a day of a week. Your current trigger date components includes year,month,day, etc so this notification repeat in each year in that particular month and day.Change trigger date like mentioned below to repeat notification in a day of a week.
let triggerDate = Calendar.current.dateComponents([.weekday,.hour,.minute], from: date as Date)
Here is approach which should work:
func addNotificationForAlarm(alarm: MyAlarm) {
let myAlarmNotifContent = UNMutableNotificationContent()
myAlarmNotifContent.title = "Reminder"
myAlarmNotifContent.body = alarm.activity
myAlarmNotifContent.sound = UNNotificationSound.default()
if alarm.repeatDays.count == 1 {
} else {
for index in 1...alarm.repeatDays.count {
createNotif(date: alarm.date, weekDay: index, content: myAlarmNotifContent)
}
}
}
private func createNotif(date: Date, weekDay: Int, content: UNNotificationContent) {
var dateComponent = DateComponents()
dateComponent.weekday = weekDay
dateComponent.hour = Calendar.current.dateComponents([.hour], from: date).hashValue
dateComponent.minute = Calendar.current.dateComponents([.minute], from: date).hashValue
let myAlarmTrigger = UNCalendarNotificationTrigger(dateMatching: dateComponent, repeats: true)
setupNotificationSettings()
let identifier = "Your-Notification"
let request = UNNotificationRequest(identifier: identifier, content: content, trigger: myAlarmTrigger)
let center = UNUserNotificationCenter.current()
center.add(request, withCompletionHandler: { (error) in
if error != nil {
//TODO: Handle the error
}
})
}
Basically what I have found is that you can set a separate notification for each day you want the alarm to trigger. For example, you want every Monday and every Tuesday, so create a date component for each day and add it to the trigger. It is not perfect but is a solution that I think is better then calculating time intervals.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With