0

I'm trying to schedule a series of notifications when the user first opens the app so I have the following code, but the problem is they get scheduled for 18:30 instead of 19:30. The strange thing is that if I schedule just one notification without the while loop, index 0 of the array works as 19:30, but the others don't. Any ideas what I'm doing wrong?

Also, if this is a really stupid way of doing this, please tell me. I do need the days to be specific (so 1, 3, 5, 7, 14... days from the current day). Thank you.

let triggerDates = [
    // Notifications for the first week
    Calendar.current.date(byAdding: .day, value: 1, to: Date())!,
    Calendar.current.date(byAdding: .day, value: 3, to: Date())!,
    Calendar.current.date(byAdding: .day, value: 5, to: Date())!,
    Calendar.current.date(byAdding: .day, value: 7, to: Date())!,
    
    // Notifications for the month
    Calendar.current.date(byAdding: .day, value: 14, to: Date())!,
    Calendar.current.date(byAdding: .day, value: 21, to: Date())!,
    
    // Notifications afterward
    Calendar.current.date(byAdding: .day, value: 42, to: Date())!,
    Calendar.current.date(byAdding: .day, value: 84, to: Date())!]


var notificationToSchedule = 7

while notificationToSchedule >= 0 {
    var dateComponents = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute], from: triggerDates[notificationToSchedule])
    
    dateComponents.hour = 19
    dateComponents.minute = 30
    let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: false)
    let request = UNNotificationRequest(identifier: "notification\(notificationToSchedule)", content: content, trigger: trigger)
    center.add(request)
    print(trigger.nextTriggerDate() ?? "nil")
    
    notificationToSchedule -= 1
}

This is what the console outputs with this code:

2019-06-21 18:30:00 +0000

2019-05-10 18:30:00 +0000

2019-04-19 18:30:00 +0000

2019-04-12 18:30:00 +0000

2019-04-05 18:30:00 +0000

2019-04-03 18:30:00 +0000

2019-04-01 18:30:00 +0000

2019-03-30 19:30:00 +0000

Community
  • 1
  • 1
CristianMoisei
  • 2,071
  • 2
  • 22
  • 28
  • 1
    This is because of daylight saving time. It changes on the 31/03/2019 so all the printed dates are taking this into account. If you were to try it with earlier dates then you would see 19:30 as you expect. – Upholder Of Truth Mar 29 '19 at 23:09
  • Edit -- actually, I see the other problem. Can you post your suggestion as an answer and I'll add my correction in a bit. – CristianMoisei Mar 29 '19 at 23:13
  • I don't think you need a correction. If you set a breakpoint and look at the contents of the triggerDates array you will see it looks correct and it's only the act of printing them to the console that is causing the problem. – Upholder Of Truth Mar 29 '19 at 23:24
  • @UpholderOfTruth what do you mean? So notificationToSchedule is used both as the index of the array and for the while loop, so the the while loop needs to run 8 times, but the array only has an index from 0 to 7, so I had to set the while loop to >= instead of >, and that all works. I tried testing the notifications by changing the device's date though and the first one fires this way, but not the next ones. Is it still something to do with DST that I'm missing, am I just scheduling them incorrectly? This is the last bit of this app I need to solve and it's been giving me so many headaches. – CristianMoisei Mar 29 '19 at 23:31
  • Sorry my bad yes that does indeed need correcting. What did you change the date too? – Upholder Of Truth Mar 29 '19 at 23:34
  • First 2019-03-30 19:29, which worked, then 2019-04-01 18:29, which didn't. I also tried letting the date be 2019-04-01 when running the app to avoid the DST problem and then the console confirmed scheduling all of them at 18:30, but again, no luck. I also tried the Swift function from this conversation to print all the scheduled notifications and it says there are only two. It also doesn't tell me their dates. : https://stackoverflow.com/questions/17531332/find-list-of-local-notification-the-app-has-already-set – CristianMoisei Mar 29 '19 at 23:38
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/190946/discussion-between-upholder-of-truth-and-cristianmoisei). – Upholder Of Truth Mar 29 '19 at 23:40

1 Answers1

2

This is related to daylight saving and because it is changing on the 31/03/2019. Also if you put a breakpoint and check the contents of the triggerDates array you will see what the dates actually look like and it is only the printing to the console that is causing your issue.

If you add 1 days in BST on the 30/03/2019 you are in fact only adding 23 hours in UTC because of daylight saving time. However if you convert it back it will be ok.

Upholder Of Truth
  • 4,643
  • 2
  • 13
  • 23