[SOLVED] How do I schedule local notifications to fire once when the app opens without having repeats when the user reopens it? (Swift, XCode, IOS)

Issue

I’m new to programming in Swift and XCode and I’m having trouble debugging my code. The app is supposed to send notifications to the user once every day at the same time. I have the basics set up so far, but while testing, if I clear the app and reopen it, it schedules two notifications instead of just one. Is there some sort of magic trick I need to fix this?

Currently, the scheduleNotification function is being called under viewDidLoad so that it can schedule everything as soon as it boots up. I’ve tried calling the function under UNUserNotificationCenter.current().add(request). I figured it would make sense to call it under there because it only prompts the user once, so when the user grants notification permissions, it would activate the notifications immediately without risking repeats. But that didn’t schedule any notifications at all.

I did some more research and maybe I’m programming the notifications in the wrong file? This is all in the View Controller.

I talked to my dad who’s really into software and he suggested tracking the notifications with an ID and deleting them if I don’t want them to appear. But that sounds very complicated and I’m not in the mood for another headache haha

Any ideas?

(Also, ignore some of the calls that have to do with the calculator. That’s unrelated to my issue)

//
//  ViewController.swift
//

import UIKit

class ViewController: UIViewController {

    // Calculator Outlets
    @IBOutlet weak var calculatorWorkings: UILabel!
    @IBOutlet weak var calculatorResults: UILabel!
    var workings:String = ""
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        clearAll()
        
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound]) {_, _ in
            DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
                
                print("Request authorized")
                
                 // Repeatedly call function so program schedules notifications in advance
                 for i in 1...10 {
                    self.scheduleNotification(day: i)
                }
                
            }
        }
    }
        
    // Phrases
    let phrasesArray = ["0", "1", "2", "3", "4", "5", "6", "7", "8"]
    
    // Handle Notifications
    func scheduleNotification(day: Int) {
        
        var dateComponents = DateComponents()
        dateComponents.hour = 21
        dateComponents.minute = 09
        dateComponents.day = day
        
        let content = UNMutableNotificationContent()
            // App name is not included in notification bar
        content.title = "Jenna's Wisdom:"
        content.body = phrasesArray[(Int.random(in: 0..<9))]
        
        content.sound = .default
        content.interruptionLevel = .timeSensitive
        
        let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)
        
        // Request to send notifications
        let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
        
        UNUserNotificationCenter.current().add(request) { error in
            if let error = error {
                print(error)
            } else {
                print("Success")
                
            }
        }
        
    }
    
}

Solution

Assuming ViewController is the first and rootViewcontroller you can just remove all local notifications before adding new ones.

UNUserNotificationCenter.current().removeAllPendingNotificationRequests()

Answered By – tereks

Answer Checked By – Robin (BugsFixing Admin)

Leave a Reply

Your email address will not be published.