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)
}
}