9

UILocalNotification has been depreciated so I would like to update my code to the UserNotification framework:

let alertDays = 3.0
let alertSeconds = alertDays * 24.0 * 60.0 * 60.0

let localNotification:UILocalNotification = UILocalNotification()

localNotification.alertAction = "Reminder"
localNotification.alertTitle = "Reminder Title"
localNotification.alertBody = "Reminder Message"
localNotification.fireDate = Foundation.Date(timeIntervalSinceNow: alertSeconds)
localNotification.repeatInterval = .day            
UIApplication.shared().scheduleLocalNotification(localNotification)

How can I set a similar daily or hourly repeat with the UserNotification framework after waiting for the initial notification?

let alertDays = 3.0
let alertSeconds = alertDays * 24.0 * 60.0 * 60.0

let content: UNMutableNotificationContent = UNMutableNotificationContent()

content.title = "Reminder Title"
content.subtitle = "Reminder Subtitle"
content.body = "Reminder Message"

let calendar = Calendar.current

let alarmTime = Foundation.Date(timeIntervalSinceNow: alertSeconds)
let alarmTimeComponents = calendar.components([.day, .hour, .minute], from: alarmTime)

let trigger = UNCalendarNotificationTrigger(dateMatching: alarmTimeComponents, repeats: true)

let request = UNNotificationRequest(identifier: workoutAlarmIdentifier,
                                        content: content,
                                        trigger: trigger)

UNUserNotificationCenter.current().add(request)
    {
        (error) in // ...
    }
Greg Robertson
  • 2,317
  • 1
  • 16
  • 30
  • Related? [How do I set an NSCalendarUnitMinute repeatInterval on iOS 10 UserNotifications?](http://stackoverflow.com/q/37804287/2415822) – JAL Jul 21 '16 at 16:16
  • Related but seems there is no .repeatInterval from the depreciated UILocalNotifications that is supported in UserNotifications. Looking for how this will be handled in the new framework so I can move my code from the depreciated one. – Greg Robertson Jul 21 '16 at 17:21
  • Suggest you raise a radar – Wain Jul 22 '16 at 07:53
  • Greg Robertson, did you manage to use the accepted answer with local UNNotifications? From what I can see it would only work with remote notifications... – CMash Sep 28 '16 at 20:59
  • 1
    This answer might help: https://stackoverflow.com/questions/54076050/repeat-interval-for-unnotification/54076269#54076269 – Brooketa Jan 16 '19 at 13:24

2 Answers2

2

It seems like this is not supported, but to make a workaround you could use:

let alertDays = 3.0
let daySeconds = 86400
let alertSeconds = alertDays * daySeconds

let content: UNMutableNotificationContent = UNMutableNotificationContent()

content.title = "Reminder Title"
content.subtitle = "Reminder Subtitle"
content.body = "Reminder Message"

let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: (alertSeconds), repeats: false)

let request = UNNotificationRequest(identifier: workoutAlarmIdentifier,
                                    content: content,
                                    trigger: trigger)

UNUserNotificationCenter.current().add(request)
{
    (error) in // ...
}

in combination with didReceive(_:withContentHandler:) you can use:

let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: (daySeconds), repeats: false)

I know this isn't optimal but it should work without using deprecated classes/methods. You use repeats: false since you are intercepting the notification just before the user receives it and creating a new notification. Additionally you can use it in combination with UNNotificationAction and UNNotificationCategory if you handle multiple notifications.

Gillsoft AB
  • 4,185
  • 2
  • 19
  • 35
  • 2
    Wait a minute... The question was asking about local notifications, not remote notifications, which is what the notification service extensions are for. You can't use them on locally scheduled `UNNotification`s, right? – CMash Sep 27 '16 at 21:08
  • In fact it looks like you need "mutable-content" set in a remote notification to get it to be handled by the service extension so not all notifications would go through it. – CMash Sep 27 '16 at 21:16
-1

This 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
        }
    })
}
highFly
  • 95
  • 1
  • 5