iosnotificationsreminders

Looking for a way to present notification on even & odd days


I'm looking for a way to present notifications on even (2,4,6,8,10,12...) & odd (1,3,5,7,9,11...) days.

I did something similar in reminders:

/// Creates a reminder
func create(_ title: String, isOddDays: Bool, hour: Int, minute: Int) {
    let dueDate = Date()
    let gregorian = Calendar(identifier: .gregorian)
    
    let daysOfTheMonth: [NSNumber]
    if isOddDays {
        daysOfTheMonth = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31]
    } else {
        daysOfTheMonth = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30]
    }
    
    let rule = EKRecurrenceRule(
        recurrenceWith: .monthly,
        interval: 1,
        daysOfTheWeek: nil,
        daysOfTheMonth: daysOfTheMonth,
        monthsOfTheYear: nil,
        weeksOfTheYear: nil,
        daysOfTheYear: nil,
        setPositions: nil,
        end: nil
    )
    
    guard let reminder: EKReminder = self.setUpReminder(with: title, priority: 0) else {
        return
    }
    
    reminder.dueDateComponents = gregorian.dateComponents([.day, .month, .year, .hour, .minute, .second], from: dueDate)
    reminder.addRecurrenceRule(rule)
    
    let todayDateComponents = gregorian.dateComponents([.day, .month, .year], from: Date())
    let day: Int = isOddDays ? 1 : 2
    let month: Int = todayDateComponents.month!
    let year: Int = todayDateComponents.year!
    
    let absoluteDate = Date.create(day: day, month: month, year: year, hour: hour, minute: minute, second: 0)
    
    let alarm = EKAlarm(absoluteDate: absoluteDate)
    reminder.addAlarm(alarm)
    
    UserDefaults.standard.set(reminder.calendarItemIdentifier, forKey: ReminderStoreManager.reminderDefaultsKey)
    
    self.saveReminder(reminder)
}

I want to do something similar with local notifications in order to send an acknowledgment back to the server.

EDIT: Screenshot added. enter image description here


Solution

  • Apparently I can use DateComponents without month & year and It will do the rest:

    private func scheduleEveryTwoDaysNotification(prefix: String, isOddDay: Bool, title: String, triggerDate: Date) {
        let triggerDateComponents = Calendar.current.dateComponents([.day, .month, .year, .hour, .minute], from: triggerDate)
        
        guard let hour = triggerDateComponents.hour, let minute = triggerDateComponents.minute else {
            return
        }
        
        let days: [Int]
        if isOddDay {
            days = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31]
        } else {
            days = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30]
        }
        
        for day in days {
            let content = UNMutableNotificationContent()
            content.title = title
            content.sound = .default
            
            var components = DateComponents()
            components.day = day
            components.hour = hour
            components.minute = minute
            components.second = 0
            
            
            let calendarTrigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: true)
            let identifier: String = "\(prefix).\(day)"
            let request = UNNotificationRequest(identifier: identifier, content: content, trigger: calendarTrigger)
            
            UNUserNotificationCenter.current().add(request) { (error) in
                if let error {
                    debugPrint(#fileID, #function, error)
                } else {
                    debugPrint(#function, request)
                }
            }
        }
    }