There is an option to set the repeat interval for UILocalNotification. Since Apple has deprecated UILocalNotification and recommend to use UNNotification instead, I couldn't find a way to set a notification with custom repeat interval with UNNotification.
var comp = DateComponents()
comp.year = 2019
comp.month = 1
comp.day = 9
comp.hour = 14
comp.minute = 14
comp.second = 0
let calendar = Calendar.current
let notification: UILocalNotification = UILocalNotification()
notification.category = "Daily Quote"
notification.alertBody = "Body"
notification.alertTitle = "Title"
notification.fireDate = calendar.date(from: comp)
notification.repeatInterval = NSCalendar.Unit.day
UIApplication.shared.scheduleLocalNotification(notification)
So can I set a similar notification that repeats hourly or daily after waiting for the initial notification using the new UNNotification?
To mimic the UILocalNotification's API fireDate
and repeatInterval
you can create two triggers, one non-repeating which would be used for fireDate
to kickoff and other repeating for repeatInterval
.
Here's an example:
import UserNotifications
/// Schedules notificaiton to fire at specific date, and then it repeats by specified repeat component
/// (week, day, hour, etc.) and repeat interval. For example to repeat every 20minutes repeatComponent
/// would be .minute and repeatInterval would be 20.
/// - Parameters:
/// - fireDate: Date for initial notification delivery
/// - repeatComponent: Component by which repeating would be performed (week, day, hour, etc.)
/// - repeatInterval: Interval by which repeating by specified component would be performed. Defaults value is 1.
func scheduleNotification(fireDate: Date, repeatComponent: Calendar.Component, repeatInterval: Int = 1) {
let content = UNMutableNotificationContent()
content.title = "Daily Quote"
content.body = "Inspirational quote."
content.categoryIdentifier = "quote.category"
UNUserNotificationCenter.current().requestAuthorization(
options: [.alert,.sound])
{
(granted, error) in
if let error = error {
print("granted, but Error in notification permission:\(error.localizedDescription)")
}
let fireTrigger = UNTimeIntervalNotificationTrigger(timeInterval: fireDate.timeIntervalSinceNow, repeats: false)
let fireDateRequest = UNNotificationRequest(identifier: "quote.starter", content: content, trigger: fireTrigger)
UNUserNotificationCenter.current().add(fireDateRequest) {(error) in
if let error = error {
print("Error adding firing notification: \(error.localizedDescription)")
} else {
if let firstRepeatingDate = Calendar.current.date(byAdding: repeatComponent, value: repeatInterval, to: fireDate) {
let repeatingTrigger = UNTimeIntervalNotificationTrigger(timeInterval: firstRepeatingDate.timeIntervalSinceNow, repeats: true)
let repeatingRequest = UNNotificationRequest(identifier: "quote.repeater", content: content, trigger: repeatingTrigger)
UNUserNotificationCenter.current().add(repeatingRequest) { (error) in
if let error = error {
print("Error adding repeating notification: \(error.localizedDescription)")
} else {
print("Successfully scheduled")
// Successfully scheduled
}
}
}
}
}
UNUserNotificationCenter.current().delegate = self
}
}
Delegate (for debug):
extension ViewController: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
print("\(notification.request.identifier): \(Date())")
UNUserNotificationCenter.current().getPendingNotificationRequests { (requests) in
for request in requests {
if let timeIntervalTrigger = request.trigger as? UNTimeIntervalNotificationTrigger {
print(Date(timeIntervalSinceNow: timeIntervalTrigger.timeInterval))
}
}
}
}
}
Usage for your requirement:
let interval = 7 // One week from now
if let fireDate = Calendar.current.date(byAdding: .day, value: interval, to: Date()) {
_ = scheduleNotification(fireDate: fireDate, repeatComponent: .day)
}
NOTE
Specifying repeating interval less than 60sec would result with exception:
'NSInternalInconsistencyException', reason: 'time interval must be at least 60 if repeating'
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