Repeat interval for UNNotification

前端 未结 2 555
遥遥无期
遥遥无期 2020-12-12 02:32

There is an option to set the repeat interval for UILocalNotification. Since Apple has deprecated UILocalNotification and recommend to use UNNotification instead, I couldn\'

相关标签:
2条回答
  • 2020-12-12 02:38

    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'

    0 讨论(0)
  • 2020-12-12 03:00

    you should use UNTimeIntervalNotificationTrigger Check the doc https://developer.apple.com/documentation/usernotifications/untimeintervalnotificationtrigger

    0 讨论(0)
提交回复
热议问题