Notifications are coming outside specified time range

20 Views Asked by At

I have created a method to schedule notifications and calling in the SceneDelegate. I'm setting a time range which can be later changed from the settings of the App. Right now it works but if I set some small range to test, the notifications come even after that range. Also notified sometimes if I set range from 9 AM to 10 PM, notifications come even after 10 PM. I added some logic to schedule number of notifications based on current time and remaining final time but it's not working that well. I'm not sure why notifications are even coming even though I have specified the end time. Here is the method that I have written to schedule notifications between some time range:

func scheduleNotifications(pendingNotications: Int) {
    // Default min and max random notifications values
    var minValue = 5
    var maxValue = 10
    
    // Default Start and End time for Notifications
    var startTime = 9
    var endTime = 21
    
    let center = UNUserNotificationCenter.current()
    
    let content = UNMutableNotificationContent()
    content.title = "Test"
    content.body = "Test Notification"
    content.sound = UNNotificationSound.default
    
    // Calculate the time range for notifications
    let calendar = Calendar.current
    let now = Date()
    let startOfDay = calendar.startOfDay(for: now)
    
    let startDate = calendar.date(bySettingHour: startTime, minute: 0, second: 0, of: startOfDay)!
    let endDate = calendar.date(bySettingHour: endTime, minute: 0, second: 0, of: startOfDay)!
    
    let timeRange = endDate.timeIntervalSince(startDate)
    
    // Calculate the number of notifications to send today
    let numberOfNotifications: Int
    
    if pendingNotications != 0 {
        minValue = Int.random(in: 0...minValue)
        maxValue = Int.random(in: minValue...maxValue)
        if now < startDate || now < endDate {
            numberOfNotifications = Int.random(in: minValue...maxValue)
        }
        else {
            numberOfNotifications = 0
        }
    }
    else {
        // Loaded for first time
        if now < startDate {
            numberOfNotifications = Int.random(in: 5...10)
        } else if now < endDate {
            let remainingTimeRange = endDate.timeIntervalSince(now)
            let remainingMinutes = Int(floor(remainingTimeRange / 60))
            var maxNotifications = Int.random(in: 5...10)
            if remainingMinutes < 45 {
                maxNotifications = 1
                numberOfNotifications = Int.random(in: 0...maxNotifications)
            } else if remainingMinutes < 120 {
                maxNotifications = 2
                numberOfNotifications = Int.random(in: 1...maxNotifications)
            } else if remainingMinutes < 180 {
                maxNotifications = 3
                numberOfNotifications = Int.random(in: 1...maxNotifications)
            } else if remainingMinutes < 240 {
                maxNotifications = 6
                numberOfNotifications = Int.random(in: 1...maxNotifications)
            }
            else {
                numberOfNotifications = Int.random(in: 5...10)
            }
        } else {
            numberOfNotifications = 0
        }
    }
    
    // Schedule only if number of notifications is not 0
    if numberOfNotifications > 0 {
        let intervalBetweenNotifications = timeRange / TimeInterval(numberOfNotifications)
        
        for i in 1...numberOfNotifications {
            let randomTimeInterval = TimeInterval.random(in: 0...intervalBetweenNotifications)
            let notificationDate = startDate.addingTimeInterval(TimeInterval(i) * intervalBetweenNotifications + randomTimeInterval)
            
            let dateComponents = calendar.dateComponents([.year, .month, .day, .hour, .minute, .second], from: notificationDate)
            let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: false)
            
            let userInfo = ["notificationFiredAt": notificationDate]
            content.userInfo = userInfo
            
            let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
            
            center.add(request) { error in
                if let error = error {
                    debugPrint(error)
                }
            }
            
            if UIApplication.shared.applicationState != .active {
                center.add(request) { error in
                    if let error = error {
                        debugPrint(error)
                    }
                }
            }
        }
    }
    
    DispatchQueue.main.async {
        debugPrint("totalNotifications - ", numberOfNotifications)
        let vc = HomeViewController()
        self.navigationController?.pushViewController(vc, animated: true)
    }
}
0

There are 0 best solutions below