Преглед изворни кода

Clear pending and delivered non-looping notifications on app (re-)init

Deniz Cengiz пре 1 година
родитељ
комит
0b9f07b26c

+ 1 - 1
Trio.xcworkspace/xcshareddata/swiftpm/Package.resolved

@@ -1,5 +1,5 @@
 {
-  "originHash" : "52d77fc35af7fe71614051dee0b291e2a0d38522eac7ae4d37d2442e81c7530c",
+  "originHash" : "b10fee57248e5d754951672d55dd1e425fadd3089d06858aed6f0f5206be7e5c",
   "pins" : [
     {
       "identity" : "cryptoswift",

+ 31 - 0
Trio/Sources/Application/TrioApp.swift

@@ -111,8 +111,14 @@ extension Notification.Name {
                     cleanupOldData()
 
                     self.initState.complete = true
+
+                    // Notifications handling
+                    // Notify of completed initialization
                     Foundation.NotificationCenter.default.post(name: .initializationCompleted, object: nil)
                     UIApplication.shared.registerForRemoteNotifications()
+                    // Cancel scheduled not looping notifications when app was completely shut down and has now re-initialized completely
+                    self.clearNotLoopingNotifications()
+
                     do {
                         try await BuildDetails.shared.handleExpireDateChange()
                     } catch {
@@ -133,6 +139,31 @@ extension Notification.Name {
         }
     }
 
+    /// Clears any delivered and pending notifications related to non-looping alerts.
+    /// It targets the following notifications:
+    /// - `noLoopFirstNotification`: The first notification for non-looping alerts.
+    /// - `noLoopSecondNotification`: The second notification for non-looping alerts.
+    ///
+    /// It ensures that any notifications that have already been shown to the user, as well as
+    /// any that are scheduled for the future, are removed when the system no longer needs to
+    /// alert about non-looping conditions.
+    ///
+    /// This function is typically used when the app was completely shut down and restarted,
+    /// i.e., underwent a fresh initialization and boot-up,  to avoid bogus not looping notifications
+    /// due to dangling "zombie" pending notification requests.
+    ///
+    /// Delivered notifications are cleared for completeness.
+    private func clearNotLoopingNotifications() {
+        UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [
+            BaseUserNotificationsManager.Identifier.noLoopFirstNotification.rawValue,
+            BaseUserNotificationsManager.Identifier.noLoopSecondNotification.rawValue
+        ])
+        UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: [
+            BaseUserNotificationsManager.Identifier.noLoopFirstNotification.rawValue,
+            BaseUserNotificationsManager.Identifier.noLoopSecondNotification.rawValue
+        ])
+    }
+
     /// Attempts to initialize the CoreDataStack again after a previous failure.
     ///
     /// Resets error states and triggers the initialization process from the beginning. Called in response

+ 1 - 1
Trio/Sources/Services/UserNotifications/UserNotificationsManager.swift

@@ -38,7 +38,7 @@ protocol pumpNotificationObserver {
 }
 
 final class BaseUserNotificationsManager: NSObject, UserNotificationsManager, Injectable {
-    private enum Identifier: String {
+    enum Identifier: String {
         case glucoseNotification = "Trio.glucoseNotification"
         case carbsRequiredNotification = "Trio.carbsRequiredNotification"
         case noLoopFirstNotification = "Trio.noLoopFirstNotification"