iosswiftusernotifications

How to set up daily local notification for tasks but don't show it when user completes the task before


I know similar questions appeared before but I think I need more clarification since i still don't know how to make it done. I'm a beginner programmer so please forgive me any mistakes.

I'm trying to have daily reminders for daily tasks from my app IF user didn't complete it yet, so how can i make it not show up when he had already done the task?

Solutions i found so far suggest to remove pending notification and setting up new one for future date in the same time.

I successfully set up daily notifications using this code:

    func sendDailyReminder() {
        let content = UNMutableNotificationContent()
        content.title = "Daily reminder"
        content.body = "You still have task to complete today."
        content.sound = UNNotificationSound.default
        var dateComponents = DateComponents()
        dateComponents.hour = 20
        dateComponents.minute = 00
        let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)
        let request = UNNotificationRequest(identifier: "dailyTrigger", content: content, trigger: trigger)

        center.add(request) { (error) in
            if let error = error {
                print("Notification Error: ", error)
            }
        }
    }

i can also successfully remove pending notification with removePendingNotificationRequest method but how can I set it up trigger for tomorrow using dateComponents here?

Or is there any other way to achieve that? Maybe using background fetch to check if its done just before sending notification?

Some replies i found suggest that its actually impossible but then how any task or to-do app can achieve something like that?


Solution

  • I ended up using multiple notifications for each weekday but set it up in little different way:

    First set up daily reminder using weekday Int as identifier

    func setWeekdayReminder(weekday: Int) {
            let center = UNUserNotificationCenter.current()
            let content = UNMutableNotificationContent()
            content.title = "Daily reminder"
            content.body = "You still have some tasks to complete today."
            content.sound = UNNotificationSound.default
            var dateComponents = DateComponents()
            dateComponents.hour = 18
            dateComponents.minute = 35
            dateComponents.weekday = weekday
            let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true
            let request = UNNotificationRequest(identifier: String(weekday), content: content, trigger: trigger)
    
            center.add(request) { (error) in
                if let error = error {
                    print("Notification Error: ", error)
                }
            }
        }
    

    then i made a function to check if there is any missing day after users launches app (except today, so i won't request todays notification again even after removing it earlier when user completes the task)

    func checkDailyReminder() {
    
           let currentWeekday = Calendar.current.component(.weekday, from: Date())
    
           center.getPendingNotificationRequests { (requests) in
                var weekdayArray : [Int] = []
    
                for each in requests {
                   weekdayArray.append(Int(each.identifier)!)
                }
                for number in 1...7 {
                    if weekdayArray.contains(number) {
                        print("weekdayArray contains weekday \(number)")
                    } else {
                        print("weekdayArray doesnt contain weekday \(number)")
                        if number != currentWeekday {
                              self.setWeekdayReminder(weekday: number)
                        }
                    }
                }
    
            }
        }
    

    Of course it's kind of a hack and when user completes the task and somehow won't go back for a week and open it again on the same weekday then he won't get notification that day but it works for rest of the time.