Q:

Questions about schedule notifications pending approval in Swift

I've created a feature that sounds an alarm at a specific time and day of the week that you set.
func scheduleNotification() {
​
   let center = UNUserNotificationCenter.current()
​   let hour = 6
​   let minute = 40
​   let weekdays = [2,3,4] // mon, tue, wed
​   let content = UNMutableNotificationContent()
​
   content.title = "Fire!!"
   content.body = "test.!"
   content.badge = 1
   content.categoryIdentifier = "alarm"
   content.userInfo = ["customData": "fizzbuzz"]
   content.sound = UNNotificationSound.default
​
   for weekday in weekdays {
       var dateComponents = DateComponents()
       dateComponents.hour = hour
       dateComponents.minute = minute
       dateComponents.weekday = weekday

       let trigger = UNCalendarNotificationTrigger.init(dateMatching: dateComponents, repeats: true)

       let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
            center.add(request)
            center.getPendingNotificationRequests { (requests) in
                for request in requests {
                    print("trigger : \(request.trigger)")
                }
            }

            UNUserNotificationCenter.current().add(request) { (error) in

            }
      }
}

As you can see in the code above, the days you want to repeat are Monday, Tuesday, and Wednesday.
weekdays = [2,3,4]
After that, I wanted to create an alarm that sounds on Monday, Tuesday, and Wednesday using the for statement on the [2,3,4] array.
But the alarm didn't sound as I wanted.
I used the getPendingNotificationRequests method to print a list of scheduled alarms to the console.
trigger : Optional(<UNCalendarNotificationTrigger: 0x283242f20; dateComponents: <NSDateComponents: 0x2830567a0> {
    Hour: 6
    Minute: 40
    Weekday: 2, repeats: YES>)
trigger : Optional(<UNCalendarNotificationTrigger: 0x283241920; dateComponents: <NSDateComponents: 0x283056900> {
    Hour: 6
    Minute: 40
    Weekday: 2, repeats: YES>)
trigger : Optional(<UNCalendarNotificationTrigger: 0x2832416a0; dateComponents: <NSDateComponents: 0x2830556f0> {
    Hour: 6
    Minute: 40
    Weekday: 3, repeats: YES>)
trigger : Optional(<UNCalendarNotificationTrigger: 0x283242f20; dateComponents: <NSDateComponents: 0x283056900> {
    Hour: 6
    Minute: 40
    Weekday: 2, repeats: YES>)
trigger : Optional(<UNCalendarNotificationTrigger: 0x2832426e0; dateComponents: <NSDateComponents: 0x283054c40> {
    Hour: 6
    Minute: 40
    Weekday: 3, repeats: YES>)
trigger : Optional(<UNCalendarNotificationTrigger: 0x2832413c0; dateComponents: <NSDateComponents: 0x283056930> {
    Hour: 6
    Minute: 40
    Weekday: 4, repeats: YES>)

What I wanted was three triggers, and Weekday was stored one by one in the [2,3,4] array.
However, six triggers were created, and the order of Weekday was stored incorrectly.
I want to ask two questions.

If you look at the log of the above code, if you have a series of triggers with Weekday stored as 2, are they executed one by one? For example, does it sound once today if it's Monday and once next Monday?
Why is the alarm stored so wrong, and how can I solve that problem?

A:

The reason you are getting six triggers is because, in your for loop (for weekday in weekdays), you are adding each trigger twice. Each trigger gets added once at the line center.add(request), and again at the line UNUserNotificationCenter.current().add(request) { (error) in. You could resolve this by updating your for loop to look something like this:
for weekday in weekdays {
    var dateComponents = DateComponents()
    dateComponents.hour = hour
    dateComponents.minute = minute
    dateComponents.weekday = weekday

    let trigger = UNCalendarNotificationTrigger.init(dateMatching: dateComponents, repeats: true)

    let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)

    center.current().add(request) { (error) in
        if error != nil {
            print(error.localizedDescription)
        }
    }
}

You also probably only want to print out the triggers after the for loop has completed, not within the for loop. So I would add the following code after the for loop:
func scheduleNotification() {

    ...

    for weekday in weekdays {

        ...

    }

    //This following code was originally within your for loop, but should probably execute after the for loop instead
    //The console should look a lot cleaner after doing so
    center.getPendingNotificationRequests { (requests) in
        for request in requests {
            print("trigger : \(request.trigger)")
        }
    }
}

