Home > database >  Fire local notification when dead line is come
Fire local notification when dead line is come

Time:12-02

In my to-do app, I'm trying to set local notification at the time when dead line date for task have been came, but i can't figure out whats wrong with calendar trigger, interval trigger working ok. In function body i put default Date()

 func setupNotifications(id: String, contentTitle: String, contentBody: String, date: Date) {
        center.getNotificationSettings { (settings) in
            if (settings.authorizationStatus == .authorized) {
                let content = UNMutableNotificationContent()
                content.title = contentTitle
                content.body = contentBody
                content.sound = .default
                
                
                let dateComponents = Calendar.current.dateComponents([.year, .month, .day, .hour], from: Date().addingTimeInterval(5))
                let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: false)
                let trigger2 = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false)
                let request = UNNotificationRequest(identifier: id, content: content, trigger: trigger)
                let request2 = UNNotificationRequest(identifier: id, content: content, trigger: trigger2)
                self.center.add(request)
                }
            }

CodePudding user response:

You said:

let dateComponents = Calendar.current.dateComponents(
    [.year, .month, .day, .hour], from: Date().addingTimeInterval(5)
)

A time interval is reckoned in seconds. But your dateComponents doesn't have any seconds; you've told it to consider only the year, the month, the day, and the hour. And that time is in the past.

You can see this simply by converting your date components back to a date:

let d = Date()
print(d) // 2022-12-01 14:24:02  0000
let dateComponents = Calendar.current.dateComponents(
    [.year, .month, .day, .hour],
    from: d.addingTimeInterval(5)
)
let d2 = Calendar.current.date(from: dateComponents)
print(d2) // 2022-12-01 14:00:00  0000

So at the very least you would need to include .seconds in your list of components. That, as you can see, changes everything:

import UIKit

let d = Date()
print(d) // 2022-12-01 14:25:22  0000
let dateComponents = Calendar.current.dateComponents(
    [.year, .month, .day, .hour, .second],
    from: d.addingTimeInterval(5)
)
let d2 = Calendar.current.date(from: dateComponents)
print(d2) // 2022-12-01 14:00:27  0000

CodePudding user response:

found solution here https://github.com/YoussifHany51/ToDoList/blob/main/ToDoList/Models/localNotification.swift adopted to my project

   func setupNotifications(id: String, deadline:Date?) {
    if deadline != nil {
        let calendar = Calendar.current
        let hour = calendar.component(.hour, from: deadline ?? Date())
        let minute = calendar.component(.minute, from: deadline ?? Date())
        let second = calendar.component(.second, from: deadline ?? Date())
        let day = calendar.component(.day, from: deadline ?? Date())
        let month = calendar.component(.month, from: deadline ?? Date())
        let content = UNMutableNotificationContent()
        content.title = "To Do"
        content.subtitle = "Today is deadline for: \(id)"
        content.sound = .default
        var operationDate = DateComponents()
        operationDate.hour = hour
        operationDate.minute = minute
        operationDate.second = second
        operationDate.month = month
        operationDate.day = day
        //Trigger
        let trigger = UNCalendarNotificationTrigger(dateMatching: operationDate, repeats: false)
        //Request
        let requst = UNNotificationRequest(
            identifier: id, content: content,trigger: trigger
        )
        UNUserNotificationCenter.current().add(requst)
    }
}
  • Related