Convert Date to DateComponents in function to schedule local notification in Swift 3

tylerSF picture tylerSF · Feb 4, 2017 · Viewed 10.6k times · Source

I'm attempting to setup a function that takes in an integer and schedules a local notification n days in the future. I'm getting an error that I can't convert type Date to DateComponents. I haven't been able to figure out how to convert it. I found a few other similar questions here and here, but I haven't been able to adapt those answers to work on Swift 3.

How can I convert Date to DateComponents? Is there a better way to schedule the notification?

Thanks in advance for the help :)

The line with the error, "Cannot convert value of type 'Date?' to expected argument type 'DateComponents'":

let trigger = UNCalendarNotificationTrigger(dateMatching: fireDateOfNotification, repeats: false)

Full function:

func scheduleNotification(day:Int) {    
    let date = Date()
    let calendar = Calendar.current
    var components = calendar.dateComponents([.day, .month, .year], from: date as Date)
    let tempDate = calendar.date(from: components)
    var comps = DateComponents()

    //set future day variable
    comps.day = day

    //set date to fire alert
    let fireDateOfNotification = calendar.date(byAdding: comps as DateComponents, to: tempDate!)

    let trigger = UNCalendarNotificationTrigger(dateMatching: fireDateOfNotification, repeats: false) //THIS LINE CAUSES ERROR

    let content = UNMutableNotificationContent()
    content.title = "New Alert Title"
    content.body = "Body of alert"
    content.sound = UNNotificationSound.default()

    let request = UNNotificationRequest(identifier: "alertNotification", content: content, trigger: trigger)

    UNUserNotificationCenter.current().add(request) {(error) in
        if let error = error {
            print("Uh oh! We had an error: \(error)")
        }
    }
 }

Answer

Code Different picture Code Different · Feb 4, 2017

I think the error is as clear as it can be. UNCalendarNotificationTrigger is meant to be flexible, so that you can specify "fire a trigger on next Friday". All you need to is convert the next trigger day into DateComponents:

let n = 7
let nextTriggerDate = Calendar.current.date(byAdding: .day, value: n, to: Date())!
let comps = Calendar.current.dateComponents([.year, .month, .day], from: nextTriggerDate)

let trigger = UNCalendarNotificationTrigger(dateMatching: comps, repeats: false)
print(trigger.nextTriggerDate())