From cd02a63cf686aa645ec2a78aae3805814867e990 Mon Sep 17 00:00:00 2001 From: Paul Plant Date: Wed, 27 Dec 2023 17:11:42 +0100 Subject: [PATCH] fix alarms for Nightscout follower mode --- xdrip/Managers/Alerts/AlertManager.swift | 25 +++++++------------ .../RootViewController.swift | 25 +++++++++++++++---- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/xdrip/Managers/Alerts/AlertManager.swift b/xdrip/Managers/Alerts/AlertManager.swift index e6a1e9e5b..a57c7115a 100644 --- a/xdrip/Managers/Alerts/AlertManager.swift +++ b/xdrip/Managers/Alerts/AlertManager.swift @@ -171,14 +171,9 @@ public class AlertManager:NSObject { } } - - // don't set this alert if it is in follower mode without an active sensor or if keep alive is disabled - if UserDefaults.standard.isMaster || (!UserDefaults.standard.isMaster && UserDefaults.standard.followerBackgroundKeepAliveType != .disabled && UserDefaults.standard.activeSensorStartDate != nil) { // the missed reading alert will be a future planned alert _ = checkAlertAndFireHelper(.missedreading) - - } } else { trace("in checkAlerts, latestBgReadings is older than %{public}@ minutes", log: self.log, category: ConstantsLog.categoryAlertManager, type: .info, maxAgeOfLastBgReadingInSeconds.description) @@ -390,12 +385,9 @@ public class AlertManager:NSObject { if alertKind == .missedreading { if let response = response { - - if UserDefaults.standard.isMaster || (!UserDefaults.standard.isMaster && UserDefaults.standard.followerBackgroundKeepAliveType.rawValue > 0 && UserDefaults.standard.activeSensorStartDate != nil) { scheduleMissedReadingAlert(snoozePeriodInMinutes: snoozePeriodInMinutes, content: response.notification.request.content) - - } + } } else { @@ -563,7 +555,7 @@ public class AlertManager:NSObject { } - if alertNeeded && (UserDefaults.standard.isMaster || (!UserDefaults.standard.isMaster && UserDefaults.standard.followerBackgroundKeepAliveType != .disabled && UserDefaults.standard.activeSensorStartDate != nil)) { + if alertNeeded && (UserDefaults.standard.isMaster || (!UserDefaults.standard.isMaster && UserDefaults.standard.followerBackgroundKeepAliveType != .disabled)) { // alert needs to be raised @@ -659,12 +651,12 @@ public class AlertManager:NSObject { } } else { // mute should not be overriden, by adding the sound to the notification, we let iOS decide if the sound will be played or not - content.sound = UNNotificationSound.init(named: UNNotificationSoundName.init(soundToSet)) + content.sound = UNNotificationSound.init(named: UNNotificationSoundName(soundToSet)) } } } else { // default sound to be played - content.sound = UNNotificationSound.init(named: UNNotificationSoundName.init("")) + content.sound = UNNotificationSound.init(named: UNNotificationSoundName("")) } // create the trigger, only for notifications with delay @@ -699,9 +691,10 @@ public class AlertManager:NSObject { } // log the result - trace("in checkAlert, raising alert %{public}@", log: self.log, category: ConstantsLog.categoryAlertManager, type: .info, alertKind.descriptionForLogging()) - if delayInSecondsToUse > 0 { - trace(" delay = %{public}@ seconds, = %{public}@ minutes - which means this is a future planned alert, it will not go off now", log: self.log, category: ConstantsLog.categoryAlertManager, type: .info, delayInSecondsToUse.description, ((round(Double(delayInSecondsToUse)/60*10))/10).description) + if delayInSecondsToUse == 0 { + trace("in checkAlert, raising alert %{public}@", log: self.log, category: ConstantsLog.categoryAlertManager, type: .info, alertKind.descriptionForLogging()) + } else { + trace("in checkAlert, raising alert %{public}@ with a delay of %{public}@ minutes - this is a scheduled future alert, it will not go off now", log: self.log, category: ConstantsLog.categoryAlertManager, type: .info, ((round(Double(delayInSecondsToUse)/60*10))/10).description) } // check if app is allowed to send local notification and if not write info to trace @@ -727,7 +720,7 @@ public class AlertManager:NSObject { } else { - if !UserDefaults.standard.isMaster && UserDefaults.standard.followerBackgroundKeepAliveType != .disabled && UserDefaults.standard.activeSensorStartDate != nil { + if !UserDefaults.standard.isMaster && UserDefaults.standard.followerBackgroundKeepAliveType == .disabled { trace("in checkAlert, there's no need to raise alert %{public}@ because we're in follower mode and keep-alive is disabled", log: self.log, category: ConstantsLog.categoryAlertManager, type: .info, alertKind.descriptionForLogging()) diff --git a/xdrip/View Controllers/Root View Controller/RootViewController.swift b/xdrip/View Controllers/Root View Controller/RootViewController.swift index fcd63c6f5..1ac0bf770 100644 --- a/xdrip/View Controllers/Root View Controller/RootViewController.swift +++ b/xdrip/View Controllers/Root View Controller/RootViewController.swift @@ -884,6 +884,9 @@ final class RootViewController: UIViewController, ObservableObject { // add observer for stopActiveSensor, this will reset the active sensor to nil when the user disconnects an intergrated transmitter/sensor (e.g. Libre 2 Direct). This will help ensure that the data source info is updated/disabled until a new sensor is started. UserDefaults.standard.addObserver(self, forKeyPath: UserDefaults.Key.stopActiveSensor.rawValue, options: .new, context: nil) + + // add observer for followerKeepAliveType, to reset the app badge notification if in follower mode and keep-alive is set to disabled + UserDefaults.standard.addObserver(self, forKeyPath: UserDefaults.Key.followerBackgroundKeepAliveType.rawValue, options: .new, context: nil) // setup delegate for UNUserNotificationCenter UNUserNotificationCenter.current().delegate = self @@ -1502,7 +1505,7 @@ final class RootViewController: UIViewController, ObservableObject { // first check keyValueObserverTimeKeeper switch keyPathEnum { - case UserDefaults.Key.isMaster, UserDefaults.Key.multipleAppBadgeValueWith10, UserDefaults.Key.showReadingInAppBadge, UserDefaults.Key.bloodGlucoseUnitIsMgDl, UserDefaults.Key.daysToUseStatistics, UserDefaults.Key.showMiniChart, UserDefaults.Key.activeSensorStartDate : + case UserDefaults.Key.isMaster, UserDefaults.Key.multipleAppBadgeValueWith10, UserDefaults.Key.showReadingInAppBadge, UserDefaults.Key.followerBackgroundKeepAliveType, UserDefaults.Key.bloodGlucoseUnitIsMgDl, UserDefaults.Key.daysToUseStatistics, UserDefaults.Key.showMiniChart, UserDefaults.Key.activeSensorStartDate : // transmittertype change triggered by user, should not be done within 200 ms if !keyValueObserverTimeKeeper.verifyKey(forKey: keyPathEnum.rawValue, withMinimumDelayMilliSeconds: 200) { @@ -1532,13 +1535,25 @@ final class RootViewController: UIViewController, ObservableObject { } - case UserDefaults.Key.multipleAppBadgeValueWith10, UserDefaults.Key.showReadingInAppBadge, UserDefaults.Key.bloodGlucoseUnitIsMgDl: + case UserDefaults.Key.multipleAppBadgeValueWith10, UserDefaults.Key.showReadingInAppBadge, UserDefaults.Key.bloodGlucoseUnitIsMgDl, UserDefaults.Key.followerBackgroundKeepAliveType: // if showReadingInAppBadge = false, means user set it from true to false - // set applicationIconBadgeNumber to 0. This will cause removal of the badge counter, but als removal of any existing notification on the screen - if !UserDefaults.standard.showReadingInAppBadge { + // set the app badge to 0. This will cause removal of the badge counter, but also removal of any existing notification on the screen + if !UserDefaults.standard.showReadingInAppBadge || (!UserDefaults.standard.isMaster && UserDefaults.standard.followerBackgroundKeepAliveType == .disabled) { + + // applicationIconBadgeNumber has been deprecated for iOS17 but as we currently have a minimum deployment target of iOS15, let's add a conditional check + if #available(iOS 16.0, *) { + UNUserNotificationCenter.current().setBadgeCount(0) + } else { + UIApplication.shared.applicationIconBadgeNumber = 0 + } + + } + + // make sure that any pending (i.e. already scheduled in the future) missed reading notifications are removed + if !UserDefaults.standard.isMaster && UserDefaults.standard.followerBackgroundKeepAliveType == .disabled { - UIApplication.shared.applicationIconBadgeNumber = 0 + UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: [ConstantsNotifications.NotificationIdentifiersForAlerts.missedReadingAlert]) }