Explorar o código

Parse userInfo into Sendable PushMessage in AppDelegate and adjust handleRemoteNotification accordingly

Jonas Björkert hai 1 ano
pai
achega
b78f95c9c1

+ 11 - 3
FreeAPS/Sources/Application/AppDelegate.swift

@@ -19,9 +19,17 @@ class AppDelegate: NSObject, UIApplicationDelegate, ObservableObject, UNUserNoti
     ) {
         debug(.remoteControl, "Received notification")
 
-        Task {
-            await TrioRemoteControl.shared.handleRemoteNotification(userInfo: userInfo)
-            completionHandler(.newData)
+        do {
+            let jsonData = try JSONSerialization.data(withJSONObject: userInfo)
+            let pushMessage = try JSONDecoder().decode(PushMessage.self, from: jsonData)
+
+            Task {
+                await TrioRemoteControl.shared.handleRemoteNotification(pushMessage: pushMessage)
+                completionHandler(.newData)
+            }
+        } catch {
+            debug(.remoteControl, "Error decoding push message: \(error.localizedDescription)")
+            completionHandler(.failed)
         }
     }
 

+ 1 - 1
FreeAPS/Sources/Models/PushMessage.swift

@@ -1,6 +1,6 @@
 import Foundation
 
-struct PushMessage: Codable {
+struct PushMessage: Codable, Sendable {
     var user: String
     var commandType: TrioRemoteControl.CommandType
     var bolusAmount: Decimal?

+ 46 - 52
FreeAPS/Sources/Modules/RemoteControl/TrioRemoteControl.swift

@@ -31,68 +31,62 @@ class TrioRemoteControl: Injectable {
         await nightscoutManager.uploadNoteTreatment(note: note)
     }
 
-    func handleRemoteNotification(userInfo: [AnyHashable: Any]) async {
+    func handleRemoteNotification(pushMessage: PushMessage) async {
         let isTrioRemoteControlEnabled = UserDefaults.standard.bool(forKey: "isTrioRemoteControlEnabled")
         guard isTrioRemoteControlEnabled else {
             await logError("Remote command received, but remote control is disabled in settings. Ignoring the command.")
             return
         }
 
-        do {
-            let jsonData = try JSONSerialization.data(withJSONObject: userInfo)
-            let pushMessage = try JSONDecoder().decode(PushMessage.self, from: jsonData)
-            let currentTime = Date().timeIntervalSince1970
-            let timeDifference = currentTime - pushMessage.timestamp
-
-            if timeDifference > timeWindow {
-                await logError(
-                    "Command rejected: the message is too old (sent \(Int(timeDifference)) seconds ago, which exceeds the allowed limit).",
-                    pushMessage: pushMessage
-                )
-                return
-            } else if timeDifference < -timeWindow {
-                await logError(
-                    "Command rejected: the message has an invalid future timestamp (timestamp is \(Int(-timeDifference)) seconds ahead of the current time).",
-                    pushMessage: pushMessage
-                )
-                return
-            }
+        let currentTime = Date().timeIntervalSince1970
+        let timeDifference = currentTime - pushMessage.timestamp
 
-            debug(.remoteControl, "Command received with acceptable time difference: \(Int(timeDifference)) seconds.")
+        if timeDifference > timeWindow {
+            await logError(
+                "Command rejected: the message is too old (sent \(Int(timeDifference)) seconds ago, which exceeds the allowed limit).",
+                pushMessage: pushMessage
+            )
+            return
+        } else if timeDifference < -timeWindow {
+            await logError(
+                "Command rejected: the message has an invalid future timestamp (timestamp is \(Int(-timeDifference)) seconds ahead of the current time).",
+                pushMessage: pushMessage
+            )
+            return
+        }
 
-            let storedSecret = UserDefaults.standard.string(forKey: "trioRemoteControlSharedSecret") ?? ""
-            guard !storedSecret.isEmpty else {
-                await logError(
-                    "Command rejected: shared secret is missing in settings. Cannot authenticate the command.",
-                    pushMessage: pushMessage
-                )
-                return
-            }
+        debug(.remoteControl, "Command received with acceptable time difference: \(Int(timeDifference)) seconds.")
 
-            guard pushMessage.sharedSecret == storedSecret else {
-                await logError(
-                    "Command rejected: shared secret does not match. Cannot authenticate the command.",
-                    pushMessage: pushMessage
-                )
-                return
-            }
+        let storedSecret = UserDefaults.standard.string(forKey: "trioRemoteControlSharedSecret") ?? ""
+        guard !storedSecret.isEmpty else {
+            await logError(
+                "Command rejected: shared secret is missing in settings. Cannot authenticate the command.",
+                pushMessage: pushMessage
+            )
+            return
+        }
 
-            switch pushMessage.commandType {
-            case .bolus:
-                await handleBolusCommand(pushMessage)
-            case .tempTarget:
-                await handleTempTargetCommand(pushMessage)
-            case .cancelTempTarget:
-                await cancelTempTarget(pushMessage)
-            case .meal:
-                await handleMealCommand(pushMessage)
-            case .startOverride:
-                await handleStartOverrideCommand(pushMessage)
-            case .cancelOverride:
-                await handleCancelOverrideCommand(pushMessage)
-            }
-        } catch {
-            await logError("Error: unable to process the command due to decoding failure (\(error.localizedDescription)).")
+        guard pushMessage.sharedSecret == storedSecret else {
+            await logError(
+                "Command rejected: shared secret does not match. Cannot authenticate the command.",
+                pushMessage: pushMessage
+            )
+            return
+        }
+
+        switch pushMessage.commandType {
+        case .bolus:
+            await handleBolusCommand(pushMessage)
+        case .tempTarget:
+            await handleTempTargetCommand(pushMessage)
+        case .cancelTempTarget:
+            await cancelTempTarget(pushMessage)
+        case .meal:
+            await handleMealCommand(pushMessage)
+        case .startOverride:
+            await handleStartOverrideCommand(pushMessage)
+        case .cancelOverride:
+            await handleCancelOverrideCommand(pushMessage)
         }
     }