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

Refactor Healthkit manager for Insulin

Refactor the code to sync with HK to be less battery drain. Limit to 100 last data.
Pierre L пре 2 година
родитељ
комит
3f2eddcb55
1 измењених фајлова са 17 додато и 25 уклоњено
  1. 17 25
      FreeAPS/Sources/Services/HealthKit/HealthKitManager.swift

+ 17 - 25
FreeAPS/Sources/Services/HealthKit/HealthKitManager.swift

@@ -227,23 +227,22 @@ final class BaseHealthKitManager: HealthKitManager, Injectable, CarbsObserver, P
               events.isNotEmpty
               events.isNotEmpty
         else { return }
         else { return }
 
 
-        func delete(syncIds: [String]?) {
-            syncIds?.forEach { syncID in
+        func save(bolusToModify: [InsulinBolus], bolus: [InsulinBolus], basal: [InsulinBasal]) {
+            // first step : delete the HK value
+            // second step : recreate with the new value !
+            bolusToModify.forEach { syncID in
                 let predicate = HKQuery.predicateForObjects(
                 let predicate = HKQuery.predicateForObjects(
                     withMetadataKey: HKMetadataKeySyncIdentifier,
                     withMetadataKey: HKMetadataKeySyncIdentifier,
                     operatorType: .equalTo,
                     operatorType: .equalTo,
                     value: syncID
                     value: syncID
                 )
                 )
-
                 self.healthKitStore.deleteObjects(of: sampleType, predicate: predicate) { _, _, error in
                 self.healthKitStore.deleteObjects(of: sampleType, predicate: predicate) { _, _, error in
                     guard let error = error else { return }
                     guard let error = error else { return }
                     warning(.service, "Cannot delete sample with syncID: \(syncID)", error: error)
                     warning(.service, "Cannot delete sample with syncID: \(syncID)", error: error)
                 }
                 }
             }
             }
-        }
-
-        func save(bolus: [InsulinBolus], basal: [InsulinBasal]) {
-            let bolusSamples = bolus
+            let bolusTotal = bolus + bolusToModify
+            let bolusSamples = bolusTotal
                 .map {
                 .map {
                     HKQuantitySample(
                     HKQuantitySample(
                         type: sampleType,
                         type: sampleType,
@@ -280,30 +279,21 @@ final class BaseHealthKitManager: HealthKitManager, Injectable, CarbsObserver, P
             healthKitStore.save(bolusSamples + basalSamples) { _, _ in }
             healthKitStore.save(bolusSamples + basalSamples) { _, _ in }
         }
         }
 
 
-        // delete existing event in HK where the amount is not the last value in the pumphistory
         loadSamplesFromHealth(sampleType: sampleType, withIDs: events.map(\.id))
         loadSamplesFromHealth(sampleType: sampleType, withIDs: events.map(\.id))
             .receive(on: processQueue)
             .receive(on: processQueue)
-            .compactMap { samples -> [String] in
+            .compactMap { samples -> ([InsulinBolus], [InsulinBolus], [InsulinBasal]) in
                 let sampleIDs = samples.compactMap(\.syncIdentifier)
                 let sampleIDs = samples.compactMap(\.syncIdentifier)
-                let bolusToDelete = events
+                let bolusToModify = events
                     .filter { $0.type == .bolus && sampleIDs.contains($0.id) }
                     .filter { $0.type == .bolus && sampleIDs.contains($0.id) }
-                    .compactMap { event -> String? in
+                    .compactMap { event -> InsulinBolus? in
                         guard let amount = event.amount else { return nil }
                         guard let amount = event.amount else { return nil }
                         guard let sampleAmount = samples.first(where: { $0.syncIdentifier == event.id }) as? HKQuantitySample
                         guard let sampleAmount = samples.first(where: { $0.syncIdentifier == event.id }) as? HKQuantitySample
                         else { return nil }
                         else { return nil }
                         if Double(amount) != sampleAmount.quantity.doubleValue(for: .internationalUnit()) {
                         if Double(amount) != sampleAmount.quantity.doubleValue(for: .internationalUnit()) {
-                            return sampleAmount.syncIdentifier
+                            return InsulinBolus(id: sampleAmount.syncIdentifier!, amount: amount, date: event.timestamp)
                         } else { return nil }
                         } else { return nil }
                     }
                     }
-                return bolusToDelete
-            }
-            .sink(receiveValue: delete)
-            .store(in: &lifetime)
 
 
-        loadSamplesFromHealth(sampleType: sampleType, withIDs: events.map(\.id))
-            .receive(on: processQueue)
-            .compactMap { samples -> ([InsulinBolus], [InsulinBasal]) in
-                let sampleIDs = samples.compactMap(\.syncIdentifier)
                 let bolus = events
                 let bolus = events
                     .filter { $0.type == .bolus && !sampleIDs.contains($0.id) }
                     .filter { $0.type == .bolus && !sampleIDs.contains($0.id) }
                     .compactMap { event -> InsulinBolus? in
                     .compactMap { event -> InsulinBolus? in
@@ -348,7 +338,7 @@ final class BaseHealthKitManager: HealthKitManager, Injectable, CarbsObserver, P
                             endDelivery: nextBasalEvent.timestamp
                             endDelivery: nextBasalEvent.timestamp
                         )
                         )
                     }
                     }
-                return (bolus, basal)
+                return (bolusToModify, bolus, basal)
             }
             }
             .sink(receiveValue: save)
             .sink(receiveValue: save)
             .store(in: &lifetime)
             .store(in: &lifetime)
@@ -407,13 +397,14 @@ final class BaseHealthKitManager: HealthKitManager, Injectable, CarbsObserver, P
 
 
     /// Try to load samples from Health store
     /// Try to load samples from Health store
     private func loadSamplesFromHealth(
     private func loadSamplesFromHealth(
-        sampleType: HKQuantityType
+        sampleType: HKQuantityType,
+        limit: Int = 100
     ) -> Future<[HKSample], Never> {
     ) -> Future<[HKSample], Never> {
         Future { promise in
         Future { promise in
             let query = HKSampleQuery(
             let query = HKSampleQuery(
                 sampleType: sampleType,
                 sampleType: sampleType,
                 predicate: nil,
                 predicate: nil,
-                limit: 1000,
+                limit: limit,
                 sortDescriptors: nil
                 sortDescriptors: nil
             ) { _, results, _ in
             ) { _, results, _ in
                 promise(.success((results as? [HKQuantitySample]) ?? []))
                 promise(.success((results as? [HKQuantitySample]) ?? []))
@@ -425,7 +416,8 @@ final class BaseHealthKitManager: HealthKitManager, Injectable, CarbsObserver, P
     /// Try to load samples from Health store with id and do some work
     /// Try to load samples from Health store with id and do some work
     private func loadSamplesFromHealth(
     private func loadSamplesFromHealth(
         sampleType: HKQuantityType,
         sampleType: HKQuantityType,
-        withIDs ids: [String]
+        withIDs ids: [String],
+        limit: Int = 100
     ) -> Future<[HKSample], Never> {
     ) -> Future<[HKSample], Never> {
         Future { promise in
         Future { promise in
             let predicate = HKQuery.predicateForObjects(
             let predicate = HKQuery.predicateForObjects(
@@ -436,7 +428,7 @@ final class BaseHealthKitManager: HealthKitManager, Injectable, CarbsObserver, P
             let query = HKSampleQuery(
             let query = HKSampleQuery(
                 sampleType: sampleType,
                 sampleType: sampleType,
                 predicate: predicate,
                 predicate: predicate,
-                limit: 1000,
+                limit: limit,
                 sortDescriptors: nil
                 sortDescriptors: nil
             ) { _, results, _ in
             ) { _, results, _ in
                 promise(.success((results as? [HKQuantitySample]) ?? []))
                 promise(.success((results as? [HKQuantitySample]) ?? []))