Reputation: 719
I was trying to set up local notifications to fire on the last day of each month regardless of whether it's the 28th, 29th, 30th, or 31st.
With the previous framework UILocalNotification
I could specify the fireDate
and repeatInterval
and it worked. But now that I'm updating the framework to UNNotofication
, I tried to use UNCalendarNotificationTrigger
and set the DateComponents
' day to 0
. However it didn't fire. Anything I was doing wrong? Thanks!
The code is as below. nextTriggerDate
is nil.
var components = DateComponents()
components.hour = 8
components.minute = 0
components.day = 0
let trigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: true)
print(trigger.nextTriggerDate())
Upvotes: 1
Views: 431
Reputation: 132
You can use the following code, next last day month is calculated after notification is shown.
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge])
{ (granted, error) in
// Enable or disable features based on authorization
}
let current = UNUserNotificationCenter.current()
current.delegate = self
setNotificationRequest()
}
func setNotificationRequest(offset: Int = 0) {
let content = UNMutableNotificationContent()
content.title = "Alarm"
content.body = "Alarm for End of Month"
content.sound = UNNotificationSound.default
var dateCompo = DateComponents()
dateCompo.day = lastDay(offset: offset)
let trigger = UNCalendarNotificationTrigger.init(dateMatching: dateCompo, repeats: true)
let request = UNNotificationRequest(identifier: "alarm-id", content: content, trigger: trigger)
UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
UNUserNotificationCenter.current().add(request)
}
func lastDay(offset: Int) -> Int {
let cal = Calendar.current
let m = cal.component(.month, from: Date()) + 1
let y = cal.component(.year, from: Date())
var comps = DateComponents(calendar: cal, year: y, month: m)
comps.setValue(m + 1, for: .month)
comps.setValue(0, for: .day)
let date = cal.date(from: comps)!
return cal.component(.day, from: date)
} }
extension ViewController: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
// offset is set to 1 as we want to get last of next month now.
setNotificationRequest(offset: 1)
completionHandler([.badge, .sound])
} }
I have tested it, working fine for me.
Upvotes: 3