Sfoglia il codice sorgente

fix properties to fetch

polscm32 aka Marvout 1 anno fa
parent
commit
507622a98e

+ 26 - 13
FreeAPS/Sources/APS/APSManager.swift

@@ -624,7 +624,8 @@ final class BaseAPSManager: APSManager, Injectable {
         )
 
         let fetchedTempBasal = await privateContext.perform {
-            guard let tempBasalEvent = results.first,
+            guard let fetchedResults = results as? [PumpEventStored],
+                  let tempBasalEvent = fetchedResults.first,
                   let tempBasal = tempBasalEvent.tempBasal,
                   let eventTimestamp = tempBasalEvent.timestamp
             else {
@@ -896,7 +897,7 @@ final class BaseAPSManager: APSManager, Injectable {
 
     // fetch glucose for time interval
     func fetchGlucose(predicate: NSPredicate, fetchLimit: Int? = nil, batchSize: Int? = nil) async -> [GlucoseStored] {
-        await CoreDataStack.shared.fetchEntitiesAsync(
+        let results = await CoreDataStack.shared.fetchEntitiesAsync(
             ofType: GlucoseStored.self,
             onContext: privateContext,
             predicate: predicate,
@@ -905,6 +906,12 @@ final class BaseAPSManager: APSManager, Injectable {
             fetchLimit: fetchLimit,
             batchSize: batchSize
         )
+
+        guard let glucoseResults = results as? [GlucoseStored] else {
+            return []
+        }
+
+        return glucoseResults
     }
 
     // TODO: - Refactor this whole shit here...
@@ -1142,28 +1149,34 @@ final class BaseAPSManager: APSManager, Injectable {
     }
 
     private func tddForStats() async -> (currentTDD: Decimal, tddTotalAverage: Decimal) {
-        let requestTDD = OrefDetermination.fetchRequest() as NSFetchRequest<OrefDetermination>
+        let requestTDD = OrefDetermination.fetchRequest() as NSFetchRequest<NSFetchRequestResult>
         let sort = NSSortDescriptor(key: "timestamp", ascending: false)
-        let daysOf14Ago = Date().addingTimeInterval(-14.days.timeInterval)
+        let daysOf14Ago = Date().addingTimeInterval(-14 * 24 * 60 * 60)
         requestTDD.predicate = NSPredicate(format: "timestamp > %@", daysOf14Ago as NSDate)
         requestTDD.sortDescriptors = [sort]
         requestTDD.propertiesToFetch = ["timestamp", "totalDailyDose"]
+        requestTDD.resultType = .dictionaryResultType
 
-        var tdds = [OrefDetermination]()
         var currentTDD: Decimal = 0
         var tddTotalAverage: Decimal = 0
 
-        await privateContext.perform {
+        let results = await privateContext.perform {
             do {
-                try tdds = self.privateContext.fetch(requestTDD)
-
-                if !tdds.isEmpty {
-                    currentTDD = tdds[0].totalDailyDose?.decimalValue ?? 0
-                    let tddArray = tdds.compactMap({ insulin in insulin.totalDailyDose as? Decimal ?? 0 })
-                    tddTotalAverage = tddArray.reduce(0, +) / Decimal(tddArray.count)
-                }
+                let fetchedResults = try self.privateContext.fetch(requestTDD) as? [[String: Any]]
+                return fetchedResults ?? []
             } catch {
                 debugPrint("\(DebuggingIdentifiers.failed) \(#file) \(#function) Failed to get TDD Data for Statistics Upload")
+                return []
+            }
+        }
+
+        if !results.isEmpty {
+            if let latestTDD = results.first?["totalDailyDose"] as? NSDecimalNumber {
+                currentTDD = latestTDD.decimalValue
+            }
+            let tddArray = results.compactMap { ($0["totalDailyDose"] as? NSDecimalNumber)?.decimalValue }
+            if !tddArray.isEmpty {
+                tddTotalAverage = tddArray.reduce(0, +) / Decimal(tddArray.count)
             }
         }
 

+ 39 - 13
FreeAPS/Sources/APS/OpenAPS/OpenAPS.swift

@@ -93,7 +93,7 @@ final class OpenAPS {
     }
 
     func checkForCobIobUpdate(_ determination: Determination) async {
-        let previousDeterminations = await CoreDataStack.shared.fetchEntitiesAsync(
+        let results = await CoreDataStack.shared.fetchEntitiesAsync(
             ofType: OrefDetermination.self,
             onContext: context,
             predicate: NSPredicate.predicateFor30MinAgoForDetermination,
@@ -102,6 +102,10 @@ final class OpenAPS {
             fetchLimit: 2
         )
 
+        guard let previousDeterminations = results as? [OrefDetermination] else {
+            return
+        }
+
         // We need to get the second last Determination for this comparison because we have saved the current Determination already to Core Data
         if let previousDetermination = previousDeterminations.dropFirst().first {
             let iobChanged = previousDetermination.iob != decimalToNSDecimalNumber(determination.iob)
@@ -136,9 +140,13 @@ final class OpenAPS {
             batchSize: 24
         )
 
+        guard let glucoseResults = results as? [GlucoseStored] else {
+            return ""
+        }
+
         return await context.perform {
-            // convert to json
-            return self.jsonConverter.convertToJSON(results)
+            // convert to JSON
+            return self.jsonConverter.convertToJSON(glucoseResults)
         }
     }
 
@@ -151,9 +159,13 @@ final class OpenAPS {
             ascending: false
         )
 
-        // convert to json
+        guard let carbResults = results as? [CarbEntryStored] else {
+            return ""
+        }
+
+        // convert to JSON
         return await context.perform {
-            return self.jsonConverter.convertToJSON(results)
+            return self.jsonConverter.convertToJSON(carbResults)
         }
     }
 
@@ -166,8 +178,13 @@ final class OpenAPS {
             ascending: false,
             batchSize: 50
         )
+
+        guard let pumpEventResults = results as? [PumpEventStored] else {
+            return nil
+        }
+
         return await context.perform {
-            return results.map(\.objectID)
+            return pumpEventResults.map(\.objectID)
         }
     }
 
@@ -311,13 +328,21 @@ final class OpenAPS {
             let tenDaysAgo = Date().addingTimeInterval(-10.days.timeInterval)
             let twoHoursAgo = Date().addingTimeInterval(-2.hours.timeInterval)
 
-            var uniqueEvents = [OrefDetermination]()
-            let requestTDD = OrefDetermination.fetchRequest() as NSFetchRequest<OrefDetermination>
+            var uniqueEvents = [[String: Any]]()
+            let requestTDD = OrefDetermination.fetchRequest() as NSFetchRequest<NSFetchRequestResult>
             requestTDD.predicate = NSPredicate(format: "timestamp > %@ AND totalDailyDose > 0", tenDaysAgo as NSDate)
             requestTDD.propertiesToFetch = ["timestamp", "totalDailyDose"]
             let sortTDD = NSSortDescriptor(key: "timestamp", ascending: true)
             requestTDD.sortDescriptors = [sortTDD]
-            try? uniqueEvents = self.context.fetch(requestTDD)
+            requestTDD.resultType = .dictionaryResultType
+
+            do {
+                if let fetchedResults = try self.context.fetch(requestTDD) as? [[String: Any]] {
+                    uniqueEvents = fetchedResults
+                }
+            } catch {
+                debugPrint("\(DebuggingIdentifiers.failed) \(#file) \(#function) Failed to fetch TDD Data")
+            }
 
             var sliderArray = [TempTargetsSlider]()
             let requestIsEnbled = TempTargetsSlider.fetchRequest() as NSFetchRequest<TempTargetsSlider>
@@ -342,12 +367,13 @@ final class OpenAPS {
             requestTempTargets.fetchLimit = 1
             try? tempTargetsArray = self.context.fetch(requestTempTargets)
 
-            let total = uniqueEvents.compactMap({ each in each.totalDailyDose as? Decimal ?? 0 }).reduce(0, +)
+            let total = uniqueEvents.compactMap({ ($0["totalDailyDose"] as? NSDecimalNumber)?.decimalValue ?? 0 }).reduce(0, +)
             var indeces = uniqueEvents.count
             // Only fetch once. Use same (previous) fetch
-            let twoHoursArray = uniqueEvents.filter({ ($0.timestamp ?? Date()) >= twoHoursAgo })
+            let twoHoursArray = uniqueEvents.filter({ ($0["timestamp"] as? Date ?? Date()) >= twoHoursAgo })
             var nrOfIndeces = twoHoursArray.count
-            let totalAmount = twoHoursArray.compactMap({ each in each.totalDailyDose as? Decimal ?? 0 }).reduce(0, +)
+            let totalAmount = twoHoursArray.compactMap({ ($0["totalDailyDose"] as? NSDecimalNumber)?.decimalValue ?? 0 })
+                .reduce(0, +)
 
             var temptargetActive = tempTargetsArray.first?.active ?? false
             let isPercentageEnabled = sliderArray.first?.enabled ?? false
@@ -357,7 +383,7 @@ final class OpenAPS {
             var unlimited = overrideArray.first?.indefinite ?? true
             var disableSMBs = overrideArray.first?.smbIsOff ?? false
 
-            let currentTDD = (uniqueEvents.last?.totalDailyDose ?? 0) as Decimal
+            let currentTDD = (uniqueEvents.last?["totalDailyDose"] as? NSDecimalNumber)?.decimalValue ?? 0
 
             if indeces == 0 {
                 indeces = 1

+ 8 - 2
FreeAPS/Sources/APS/Storage/CarbsStorage.swift

@@ -247,8 +247,12 @@ final class BaseCarbsStorage: CarbsStorage, Injectable {
             ascending: false
         )
 
+        guard let carbEntries = results as? [CarbEntryStored] else {
+            return []
+        }
+
         return await coredataContext.perform {
-            return results.map { result in
+            return carbEntries.map { result in
                 NightscoutTreatment(
                     duration: nil,
                     rawDuration: nil,
@@ -281,8 +285,10 @@ final class BaseCarbsStorage: CarbsStorage, Injectable {
             ascending: false
         )
 
+        guard let fpuEntries = results as? [CarbEntryStored] else { return [] }
+
         return await coredataContext.perform {
-            return results.map { result in
+            return fpuEntries.map { result in
                 NightscoutTreatment(
                     duration: nil,
                     rawDuration: nil,

+ 4 - 1
FreeAPS/Sources/APS/Storage/DeterminationStorage.swift

@@ -26,8 +26,11 @@ final class BaseDeterminationStorage: DeterminationStorage, Injectable {
             ascending: false,
             fetchLimit: 1
         )
+
+        guard let fetchedResults = results as? [OrefDetermination] else { return [] }
+
         return await backgroundContext.perform {
-            results.map(\.objectID)
+            fetchedResults.map(\.objectID)
         }
     }
 

+ 8 - 2
FreeAPS/Sources/APS/Storage/GlucoseStorage.swift

@@ -243,8 +243,11 @@ final class BaseGlucoseStorage: GlucoseStorage, Injectable {
             ascending: false,
             fetchLimit: 288
         )
+
+        guard let fetchedResults = results as? [GlucoseStored] else { return [] }
+
         return await coredataContext.perform {
-            return results.map { result in
+            return fetchedResults.map { result in
                 BloodGlucose(
                     _id: result.id?.uuidString ?? UUID().uuidString,
                     sgv: Int(result.glucose),
@@ -271,8 +274,11 @@ final class BaseGlucoseStorage: GlucoseStorage, Injectable {
             ascending: false,
             fetchLimit: 288
         )
+
+        guard let fetchedResults = results as? [GlucoseStored] else { return [] }
+
         return await coredataContext.perform {
-            return results.map { result in
+            return fetchedResults.map { result in
                 NightscoutTreatment(
                     duration: nil,
                     rawDuration: nil,

+ 16 - 6
FreeAPS/Sources/APS/Storage/OverrideStorage.swift

@@ -45,8 +45,10 @@ final class BaseOverrideStorage: OverrideStorage, Injectable {
             fetchLimit: 1
         )
 
+        guard let fetchedResults = results as? [OverrideStored] else { return [] }
+
         return await backgroundContext.perform {
-            return results.map(\.objectID)
+            return fetchedResults.map(\.objectID)
         }
     }
 
@@ -60,14 +62,16 @@ final class BaseOverrideStorage: OverrideStorage, Injectable {
             fetchLimit: fetchLimit
         )
 
+        guard let fetchedResults = results as? [OverrideStored] else { return [] }
+
         return await backgroundContext.perform {
-            return results.map(\.objectID)
+            return fetchedResults.map(\.objectID)
         }
     }
 
     /// Returns the NSManagedObjectID of the Override Presets
     func fetchForOverridePresets() async -> [NSManagedObjectID] {
-        let result = await CoreDataStack.shared.fetchEntitiesAsync(
+        let results = await CoreDataStack.shared.fetchEntitiesAsync(
             ofType: OverrideStored.self,
             onContext: backgroundContext,
             predicate: NSPredicate.allOverridePresets,
@@ -75,8 +79,10 @@ final class BaseOverrideStorage: OverrideStorage, Injectable {
             ascending: true
         )
 
+        guard let fetchedResults = results as? [OverrideStored] else { return [] }
+
         return await backgroundContext.perform {
-            return result.map(\.objectID)
+            return fetchedResults.map(\.objectID)
         }
     }
 
@@ -206,7 +212,7 @@ final class BaseOverrideStorage: OverrideStorage, Injectable {
     }
 
     func getOverridesNotYetUploadedToNightscout() async -> [NightscoutExercise] {
-        let fetchedOverrides = await CoreDataStack.shared.fetchEntitiesAsync(
+        let results = await CoreDataStack.shared.fetchEntitiesAsync(
             ofType: OverrideStored.self,
             onContext: backgroundContext,
             predicate: NSPredicate.lastActiveOverrideNotYetUploadedToNightscout,
@@ -214,6 +220,8 @@ final class BaseOverrideStorage: OverrideStorage, Injectable {
             ascending: false
         )
 
+        guard let fetchedOverrides = results as? [OverrideStored] else { return [] }
+
         return await backgroundContext.perform {
             return fetchedOverrides.map { override in
                 let duration = override.indefinite ? 1440 : override.duration ?? 0 // 1440 min = 1 day
@@ -230,7 +238,7 @@ final class BaseOverrideStorage: OverrideStorage, Injectable {
     }
 
     func getOverrideRunsNotYetUploadedToNightscout() async -> [NightscoutExercise] {
-        let fetchedOverrideRuns = await CoreDataStack.shared.fetchEntitiesAsync(
+        let results = await CoreDataStack.shared.fetchEntitiesAsync(
             ofType: OverrideRunStored.self,
             onContext: backgroundContext,
             predicate: NSPredicate(
@@ -242,6 +250,8 @@ final class BaseOverrideStorage: OverrideStorage, Injectable {
             ascending: false
         )
 
+        guard let fetchedOverrideRuns = results as? [OverrideRunStored] else { return [] }
+
         return await backgroundContext.perform {
             return fetchedOverrideRuns.map { overrideRun in
                 var durationInMinutes = (overrideRun.endDate?.timeIntervalSince(overrideRun.startDate ?? Date()) ?? 1) / 60

+ 3 - 1
FreeAPS/Sources/APS/Storage/PumpHistoryStorage.swift

@@ -253,7 +253,7 @@ final class BasePumpHistoryStorage: PumpHistoryStorage, Injectable {
     }
 
     func getPumpHistoryNotYetUploadedToNightscout() async -> [NightscoutTreatment] {
-        let fetchedPumpEvents = await CoreDataStack.shared.fetchEntitiesAsync(
+        let results = await CoreDataStack.shared.fetchEntitiesAsync(
             ofType: PumpEventStored.self,
             onContext: context,
             predicate: NSPredicate.pumpEventsNotYetUploadedToNightscout,
@@ -262,6 +262,8 @@ final class BasePumpHistoryStorage: PumpHistoryStorage, Injectable {
             fetchLimit: 288
         )
 
+        guard let fetchedPumpEvents = results as? [PumpEventStored] else { return [] }
+
         return await context.perform { [self] in
             fetchedPumpEvents.map { event in
                 switch event.type {

+ 3 - 1
FreeAPS/Sources/Modules/Bolus/BolusStateModel.swift

@@ -583,8 +583,10 @@ extension Bolus.StateModel {
             fetchLimit: 3
         )
 
+        guard let fetchedResults = results as? [GlucoseStored] else { return [] }
+
         return await backgroundContext.perform {
-            return results.map(\.objectID)
+            return fetchedResults.map(\.objectID)
         }
     }
 

+ 34 - 10
FreeAPS/Sources/Modules/Home/HomeStateModel.swift

@@ -574,8 +574,10 @@ extension Home.StateModel {
             fetchLimit: 288
         )
 
+        guard let fetchedResults = results as? [GlucoseStored] else { return [] }
+
         return await context.perform {
-            return results.map(\.objectID)
+            return fetchedResults.map(\.objectID)
         }
     }
 
@@ -610,8 +612,10 @@ extension Home.StateModel {
             fetchLimit: 288
         )
 
+        guard let fetchedResults = results as? [GlucoseStored] else { return [] }
+
         return await context.perform {
-            return results.map(\.objectID)
+            return fetchedResults.map(\.objectID)
         }
     }
 
@@ -645,8 +649,10 @@ extension Home.StateModel {
             ascending: false
         )
 
+        guard let fetchedResults = results as? [CarbEntryStored] else { return [] }
+
         return await context.perform {
-            return results.map(\.objectID)
+            return fetchedResults.map(\.objectID)
         }
     }
 
@@ -680,8 +686,10 @@ extension Home.StateModel {
             ascending: false
         )
 
+        guard let fetchedResults = results as? [CarbEntryStored] else { return [] }
+
         return await context.perform {
-            return results.map(\.objectID)
+            return fetchedResults.map(\.objectID)
         }
     }
 
@@ -710,8 +718,12 @@ extension Home.StateModel {
             propertiesToFetch: ["cob", "iob", "deliverAt"]
         )
 
+        guard let fetchedResults = results as? [[String: Any]] else {
+            return []
+        }
+
         return await context.perform {
-            return results.map(\.objectID)
+            return fetchedResults.compactMap { $0["objectID"] as? NSManagedObjectID }
         }
     }
 
@@ -770,8 +782,12 @@ extension Home.StateModel {
             ascending: true
         )
 
+        guard let pumpEvents = results as? [PumpEventStored] else {
+            return []
+        }
+
         return await context.perform {
-            return results.map(\.objectID)
+            return pumpEvents.map(\.objectID)
         }
     }
 
@@ -821,8 +837,10 @@ extension Home.StateModel {
             fetchLimit: 1
         )
 
+        guard let fetchedResults = results as? [PumpEventStored] else { return [].first }
+
         return await context.perform {
-            return results.map(\.objectID).first
+            return fetchedResults.map(\.objectID).first
         }
     }
 
@@ -853,8 +871,10 @@ extension Home.StateModel {
             ascending: false
         )
 
+        guard let fetchedResults = results as? [OpenAPS_Battery] else { return [] }
+
         return await context.perform {
-            return results.map(\.objectID)
+            return fetchedResults.map(\.objectID)
         }
     }
 
@@ -890,8 +910,10 @@ extension Home.StateModel {
             ascending: false
         )
 
+        guard let fetchedResults = results as? [OverrideStored] else { return [] }
+
         return await context.perform {
-            return results.map(\.objectID)
+            return fetchedResults.map(\.objectID)
         }
     }
 
@@ -941,8 +963,10 @@ extension Home.StateModel {
             ascending: false
         )
 
+        guard let fetchedResults = results as? [OverrideRunStored] else { return [] }
+
         return await context.perform {
-            return results.map(\.objectID)
+            return fetchedResults.map(\.objectID)
         }
     }
 

+ 27 - 23
FreeAPS/Sources/Modules/Stat/StatStateModel.swift

@@ -45,31 +45,35 @@ extension Stat {
         }
 
         private func fetchGlucose(for duration: Duration) async -> [NSManagedObjectID] {
-            await context.perform {
-                let predicate: NSPredicate
+            let predicate: NSPredicate
 
-                switch duration {
-                case .Day:
-                    predicate = NSPredicate.glucoseForStatsDay
-                case .Week:
-                    predicate = NSPredicate.glucoseForStatsWeek
-                case .Today:
-                    predicate = NSPredicate.glucoseForStatsToday
-                case .Month:
-                    predicate = NSPredicate.glucoseForStatsMonth
-                case .Total:
-                    predicate = NSPredicate.glucoseForStatsTotal
-                }
+            switch duration {
+            case .Day:
+                predicate = NSPredicate.glucoseForStatsDay
+            case .Week:
+                predicate = NSPredicate.glucoseForStatsWeek
+            case .Today:
+                predicate = NSPredicate.glucoseForStatsToday
+            case .Month:
+                predicate = NSPredicate.glucoseForStatsMonth
+            case .Total:
+                predicate = NSPredicate.glucoseForStatsTotal
+            }
+
+            let results = await CoreDataStack.shared.fetchEntitiesAsync(
+                ofType: GlucoseStored.self,
+                onContext: context,
+                predicate: predicate,
+                key: "date",
+                ascending: false,
+                batchSize: 100,
+                propertiesToFetch: ["glucose", "date"]
+            )
+
+            guard let fetchedResults = results as? [GlucoseStored] else { return [] }
 
-                return CoreDataStack.shared.fetchEntities(
-                    ofType: GlucoseStored.self,
-                    onContext: self.context,
-                    predicate: predicate,
-                    key: "date",
-                    ascending: false,
-                    batchSize: 100,
-                    propertiesToFetch: ["glucose", "date"]
-                ).map(\.objectID)
+            return await context.perform {
+                return fetchedResults.map(\.objectID)
             }
         }
 

+ 32 - 8
FreeAPS/Sources/Services/LiveActivity/Data/DataManager.swift

@@ -5,7 +5,7 @@ import Foundation
 @available(iOS 16.2, *)
 extension LiveActivityBridge {
     func fetchAndMapGlucose() async {
-        let result = await CoreDataStack.shared.fetchEntitiesAsync(
+        let results = await CoreDataStack.shared.fetchEntitiesAsync(
             ofType: GlucoseStored.self,
             onContext: context,
             predicate: NSPredicate.predicateForSixHoursAgo,
@@ -13,14 +13,20 @@ extension LiveActivityBridge {
             ascending: false,
             fetchLimit: 72
         )
+
+        guard let glucoseResults = results as? [GlucoseStored] else {
+            return
+        }
+
         await context.perform {
-            self.glucoseFromPersistence = result
-                .map { GlucoseData(glucose: Int($0.glucose), date: $0.date ?? Date(), direction: $0.directionEnum) }
+            self.glucoseFromPersistence = glucoseResults.map {
+                GlucoseData(glucose: Int($0.glucose), date: $0.date ?? Date(), direction: $0.directionEnum)
+            }
         }
     }
 
     func fetchAndMapDetermination() async {
-        let result = await CoreDataStack.shared.fetchEntitiesAsync(
+        let results = await CoreDataStack.shared.fetchEntitiesAsync(
             ofType: OrefDetermination.self,
             onContext: context,
             predicate: NSPredicate.predicateFor30MinAgoForDetermination,
@@ -29,22 +35,40 @@ extension LiveActivityBridge {
             fetchLimit: 1,
             propertiesToFetch: ["iob", "cob", "deliverAt"]
         )
+
+        guard let determinationResults = results as? [[String: Any]] else {
+            return
+        }
+
         await context.perform {
-            self.determination = result.first.map { DeterminationData(cob: Int($0.cob), iob: $0.iob?.decimalValue ?? 0) }
+            self.determination = determinationResults.first.map {
+                DeterminationData(
+                    cob: ($0["cob"] as? Int) ?? 0,
+                    iob: ($0["iob"] as? NSDecimalNumber)?.decimalValue ?? 0
+                )
+            }
         }
     }
 
     func fetchAndMapOverride() async {
-        let result = await CoreDataStack.shared.fetchEntitiesAsync(
+        let results = await CoreDataStack.shared.fetchEntitiesAsync(
             ofType: OverrideStored.self,
             onContext: context,
             predicate: NSPredicate.predicateForOneDayAgo,
             key: "date",
             ascending: false,
-            fetchLimit: 1
+            fetchLimit: 1,
+            propertiesToFetch: ["enabled"]
         )
+
+        guard let overrideResults = results as? [[String: Any]] else {
+            return
+        }
+
         await context.perform {
-            self.isOverridesActive = result.first.map { OverrideData(isActive: $0.enabled) }
+            self.isOverridesActive = overrideResults.first.map {
+                OverrideData(isActive: $0["enabled"] as? Bool ?? false)
+            }
         }
     }
 }

+ 4 - 1
FreeAPS/Sources/Services/UserNotifications/UserNotificationsManager.swift

@@ -225,8 +225,11 @@ final class BaseUserNotificationsManager: NSObject, UserNotificationsManager, In
             ascending: false,
             fetchLimit: 3
         )
+
+        guard let fetchedResults = results as? [GlucoseStored] else { return [] }
+
         return await backgroundContext.perform {
-            return results.map(\.objectID)
+            return fetchedResults.map(\.objectID)
         }
     }
 

+ 14 - 6
FreeAPS/Sources/Services/WatchManager/WatchManager.swift

@@ -142,12 +142,13 @@ final class BaseWatchManager: NSObject, WatchManager, Injectable {
             predicate: NSPredicate.enactedDetermination,
             key: "timestamp",
             ascending: false,
-            fetchLimit: 1,
-            propertiesToFetch: ["timestamp"]
+            fetchLimit: 1
         )
 
+        guard let fetchedResults = results as? [OrefDetermination] else { return [] }
+
         return await context.perform {
-            results.map(\.objectID)
+            fetchedResults.map(\.objectID)
         }
     }
 
@@ -158,11 +159,14 @@ final class BaseWatchManager: NSObject, WatchManager, Injectable {
             predicate: NSPredicate.predicateForOneDayAgo,
             key: "date",
             ascending: false,
-            fetchLimit: 1
+            fetchLimit: 1,
+            propertiesToFetch: ["enabled", "percentage"]
         )
 
+        guard let fetchedResults = results as? [[String: Any]] else { return nil }
+
         return await context.perform {
-            results.map(\.objectID).first
+            fetchedResults.compactMap { $0["objectID"] as? NSManagedObjectID }.first
         }
     }
 
@@ -177,8 +181,12 @@ final class BaseWatchManager: NSObject, WatchManager, Injectable {
             batchSize: 12
         )
 
+        guard let glucoseResults = results as? [GlucoseStored] else {
+            return []
+        }
+
         return await context.perform {
-            results.map(\.objectID)
+            glucoseResults.map(\.objectID)
         }
     }
 

+ 10 - 6
Model/CoreDataStack.swift

@@ -365,8 +365,8 @@ extension CoreDataStack {
         propertiesToFetch: [String]? = nil,
         callingFunction: String = #function,
         callingClass: String = #fileID
-    ) async -> [T] {
-        let request = NSFetchRequest<T>(entityName: String(describing: type))
+    ) async -> Any {
+        let request: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: String(describing: type))
         request.sortDescriptors = [NSSortDescriptor(key: key, ascending: ascending)]
         request.predicate = predicate
         if let limit = fetchLimit {
@@ -375,9 +375,9 @@ extension CoreDataStack {
         if let batchSize = batchSize {
             request.fetchBatchSize = batchSize
         }
-        if let propertiesTofetch = propertiesToFetch {
-            request.propertiesToFetch = propertiesTofetch
-            request.resultType = .managedObjectResultType
+        if let propertiesToFetch = propertiesToFetch {
+            request.propertiesToFetch = propertiesToFetch
+            request.resultType = .dictionaryResultType
         } else {
             request.resultType = .managedObjectResultType
         }
@@ -390,7 +390,11 @@ extension CoreDataStack {
                 debugPrint(
                     "Fetching \(T.self) in \(callingFunction) from \(callingClass): \(DebuggingIdentifiers.succeeded) on Thread: \(Thread.current)"
                 )
-                return try context.fetch(request)
+                if propertiesToFetch != nil {
+                    return try context.fetch(request) as? [[String: Any]] ?? []
+                } else {
+                    return try context.fetch(request) as? [T] ?? []
+                }
             } catch let error as NSError {
                 debugPrint(
                     "Fetching \(T.self) in \(callingFunction) from \(callingClass): \(DebuggingIdentifiers.failed) \(error) on Thread: \(Thread.current)"