Просмотр исходного кода

Merge pull request #674 from marv-out/watch

Optimize watch managers to skip processing when no watch is connected
Deniz Cengiz 9 месяцев назад
Родитель
Сommit
ce12840ddb

+ 30 - 1
Trio/Sources/Services/WatchManager/AppleWatchManager.swift

@@ -69,6 +69,9 @@ final class BaseWatchManager: NSObject, WCSessionDelegate, Injectable, WatchMana
             .receive(on: DispatchQueue.global(qos: .background))
             .sink { [weak self] _ in
                 guard let self = self else { return }
+                // Skip if no watch is paired or app not installed
+                guard let session = self.session, session.isPaired, session.isReachable,
+                      session.isWatchAppInstalled else { return }
                 Task {
                     let state = await self.setupWatchState()
                     await self.sendDataToWatch(state)
@@ -82,6 +85,8 @@ final class BaseWatchManager: NSObject, WCSessionDelegate, Injectable, WatchMana
     private func registerHandlers() {
         coreDataPublisher?.filteredByEntityName("OrefDetermination").sink { [weak self] _ in
             guard let self = self else { return }
+            // Skip if no watch is paired or app not installed
+            guard let session = self.session, session.isPaired, session.isReachable, session.isWatchAppInstalled else { return }
             Task {
                 let state = await self.setupWatchState()
                 await self.sendDataToWatch(state)
@@ -91,6 +96,8 @@ final class BaseWatchManager: NSObject, WCSessionDelegate, Injectable, WatchMana
         // Due to the Batch insert this only is used for observing Deletion of Glucose entries
         coreDataPublisher?.filteredByEntityName("GlucoseStored").sink { [weak self] _ in
             guard let self = self else { return }
+            // Skip if no watch is paired or app not installed
+            guard let session = self.session, session.isPaired, session.isReachable, session.isWatchAppInstalled else { return }
             Task {
                 let state = await self.setupWatchState()
                 await self.sendDataToWatch(state)
@@ -106,6 +113,8 @@ final class BaseWatchManager: NSObject, WCSessionDelegate, Injectable, WatchMana
 
         coreDataPublisher?.filteredByEntityName("OverrideStored").sink { [weak self] _ in
             guard let self = self else { return }
+            // Skip if no watch is paired or app not installed
+            guard let session = self.session, session.isPaired, session.isReachable, session.isWatchAppInstalled else { return }
             Task {
                 let state = await self.setupWatchState()
                 await self.sendDataToWatch(state)
@@ -114,6 +123,8 @@ final class BaseWatchManager: NSObject, WCSessionDelegate, Injectable, WatchMana
 
         coreDataPublisher?.filteredByEntityName("TempTargetStored").sink { [weak self] _ in
             guard let self = self else { return }
+            // Skip if no watch is paired or app not installed
+            guard let session = self.session, session.isPaired, session.isReachable, session.isWatchAppInstalled else { return }
             Task {
                 let state = await self.setupWatchState()
                 await self.sendDataToWatch(state)
@@ -148,6 +159,17 @@ final class BaseWatchManager: NSObject, WCSessionDelegate, Injectable, WatchMana
     /// Prepares the current state data to be sent to the Watch
     /// - Returns: WatchState containing current glucose readings and trends and determination infos for displaying cob and iob in the view
     func setupWatchState() async -> WatchState {
+        // Check if a watch is paired and reachable before doing expensive calculations
+        guard let session = session, session.isPaired, session.isReachable, session.isWatchAppInstalled else {
+            debug(.watchManager, "⌚️❌ Skipping setupWatchState - No Watch is paired or app not installed")
+            return WatchState(date: Date())
+        }
+
+        // Skip if watch session is not activated
+        guard session.activationState == .activated else {
+            debug(.watchManager, "⌚️❌ Skipping setupWatchState - Watch session not activated")
+            return WatchState(date: Date())
+        }
         do {
             // Get NSManagedObjectIDs
             let glucoseIds = try await fetchGlucose()
@@ -527,7 +549,9 @@ final class BaseWatchManager: NSObject, WCSessionDelegate, Injectable, WatchMana
             {
                 debug(.watchManager, "📱 Watch requested watch state data update.")
                 guard let self = self else { return }
-
+                // Skip if no watch is paired or app not installed
+                guard let session = self.session, session.isPaired, session.isReachable,
+                      session.isWatchAppInstalled else { return }
                 Task {
                     let state = await self.setupWatchState()
                     await self.sendDataToWatch(state)
@@ -1137,6 +1161,8 @@ final class BaseWatchManager: NSObject, WCSessionDelegate, Injectable, WatchMana
 extension BaseWatchManager: SettingsObserver, PumpSettingsObserver {
     // to update maxBolus
     func pumpSettingsDidChange(_: PumpSettings) {
+        // Skip if no watch is paired or app not installed
+        guard let session = self.session, session.isPaired, session.isReachable, session.isWatchAppInstalled else { return }
         Task {
             let state = await self.setupWatchState()
             await self.sendDataToWatch(state)
@@ -1150,6 +1176,9 @@ extension BaseWatchManager: SettingsObserver, PumpSettingsObserver {
         lowGlucose = settingsManager.settings.low
         highGlucose = settingsManager.settings.high
 
+        // Skip if no watch is paired or app not installed
+        guard let session = self.session, session.isPaired, session.isReachable, session.isWatchAppInstalled else { return }
+
         Task {
             let state = await self.setupWatchState()
             await self.sendDataToWatch(state)

+ 11 - 0
Trio/Sources/Services/WatchManager/GarminManager.swift

@@ -133,6 +133,8 @@ final class BaseGarminManager: NSObject, GarminManager, Injectable {
             .receive(on: DispatchQueue.global(qos: .background))
             .sink { [weak self] _ in
                 guard let self = self else { return }
+                // Skip if no Garmin devices are connected
+                guard !self.devices.isEmpty else { return }
                 Task {
                     do {
                         let watchState = try await self.setupGarminWatchState()
@@ -160,6 +162,8 @@ final class BaseGarminManager: NSObject, GarminManager, Injectable {
             .filteredByEntityName("OrefDetermination")
             .sink { [weak self] _ in
                 guard let self = self else { return }
+                // Skip if no Garmin devices are connected
+                guard !self.devices.isEmpty else { return }
                 Task {
                     do {
                         let watchState = try await self.setupGarminWatchState()
@@ -180,6 +184,8 @@ final class BaseGarminManager: NSObject, GarminManager, Injectable {
             .filteredByEntityName("GlucoseStored")
             .sink { [weak self] _ in
                 guard let self = self else { return }
+                // Skip if no Garmin devices are connected
+                guard !self.devices.isEmpty else { return }
                 Task {
                     do {
                         let watchState = try await self.setupGarminWatchState()
@@ -219,6 +225,11 @@ final class BaseGarminManager: NSObject, GarminManager, Injectable {
     /// Builds a `GarminWatchState` reflecting the latest glucose, trend, delta, eventual BG, ISF, IOB, and COB.
     /// - Returns: A `GarminWatchState` containing the most recent device- and therapy-related info.
     func setupGarminWatchState() async throws -> GarminWatchState {
+        // Skip expensive calculations if no Garmin devices are connected
+        guard !devices.isEmpty else {
+            debug(.watchManager, "⌚️❌ Skipping setupGarminWatchState - No Garmin devices connected")
+            return GarminWatchState()
+        }
         do {
             // Get Glucose IDs
             let glucoseIds = try await fetchGlucose()