Selaa lähdekoodia

HealthKit fixes

Ivan Valkou 4 vuotta sitten
vanhempi
commit
4019437bc8

+ 3 - 3
FreeAPS.xcodeproj/xcuserdata/i.valkou.xcuserdatad/xcschemes/xcschememanagement.plist

@@ -33,17 +33,17 @@
 		<key>FreeAPSWatch (Complication).xcscheme_^#shared#^_</key>
 		<key>FreeAPSWatch (Complication).xcscheme_^#shared#^_</key>
 		<dict>
 		<dict>
 			<key>orderHint</key>
 			<key>orderHint</key>
-			<integer>18</integer>
+			<integer>11</integer>
 		</dict>
 		</dict>
 		<key>FreeAPSWatch (Notification).xcscheme_^#shared#^_</key>
 		<key>FreeAPSWatch (Notification).xcscheme_^#shared#^_</key>
 		<dict>
 		<dict>
 			<key>orderHint</key>
 			<key>orderHint</key>
-			<integer>17</integer>
+			<integer>12</integer>
 		</dict>
 		</dict>
 		<key>FreeAPSWatch.xcscheme_^#shared#^_</key>
 		<key>FreeAPSWatch.xcscheme_^#shared#^_</key>
 		<dict>
 		<dict>
 			<key>orderHint</key>
 			<key>orderHint</key>
-			<integer>16</integer>
+			<integer>8</integer>
 		</dict>
 		</dict>
 		<key>ReactiveSwift (Playground) 1.xcscheme</key>
 		<key>ReactiveSwift (Playground) 1.xcscheme</key>
 		<dict>
 		<dict>

+ 2 - 1
FreeAPS/Sources/APS/FetchGlucoseManager.swift

@@ -59,7 +59,8 @@ final class BaseFetchGlucoseManager: FetchGlucoseManager, Injectable {
                 return Publishers.CombineLatest3(
                 return Publishers.CombineLatest3(
                     Just(date),
                     Just(date),
                     Just(self.glucoseStorage.syncDate()),
                     Just(self.glucoseStorage.syncDate()),
-                    self.glucoseSource.fetch()
+                    self.glucoseSource.fetch().merge(with: self.healthKitManager.fetch())
+                        .eraseToAnyPublisher()
                 )
                 )
                 .eraseToAnyPublisher()
                 .eraseToAnyPublisher()
             }
             }

+ 4 - 4
FreeAPS/Sources/APS/Storage/GlucoseStorage.swift

@@ -54,8 +54,8 @@ final class BaseGlucoseStorage: GlucoseStorage, Injectable {
         processQueue.sync {
         processQueue.sync {
             let file = OpenAPS.Monitor.glucose
             let file = OpenAPS.Monitor.glucose
             self.storage.transaction { storage in
             self.storage.transaction { storage in
-                let BGInStorage = storage.retrieve(file, as: [BloodGlucose].self)
-                let filteredBG = BGInStorage?.filter { !ids.contains($0.id) } ?? []
+                let bgInStorage = storage.retrieve(file, as: [BloodGlucose].self)
+                let filteredBG = bgInStorage?.filter { !ids.contains($0.id) } ?? []
                 storage.save(filteredBG, as: file)
                 storage.save(filteredBG, as: file)
 
 
                 DispatchQueue.main.async {
                 DispatchQueue.main.async {
@@ -71,8 +71,8 @@ final class BaseGlucoseStorage: GlucoseStorage, Injectable {
         processQueue.sync {
         processQueue.sync {
             let file = OpenAPS.Monitor.glucose
             let file = OpenAPS.Monitor.glucose
             self.storage.transaction { storage in
             self.storage.transaction { storage in
-                let BGInStorage = storage.retrieve(file, as: [BloodGlucose].self)
-                let filteredBG = BGInStorage?.filter { $0.id != id } ?? []
+                let bgInStorage = storage.retrieve(file, as: [BloodGlucose].self)
+                let filteredBG = bgInStorage?.filter { $0.id != id } ?? []
                 storage.save(filteredBG, as: file)
                 storage.save(filteredBG, as: file)
 
 
                 DispatchQueue.main.async {
                 DispatchQueue.main.async {

+ 36 - 21
FreeAPS/Sources/Services/HealthKit/HealthKitManager.swift

@@ -1,8 +1,9 @@
+import Combine
 import Foundation
 import Foundation
 import HealthKit
 import HealthKit
 import Swinject
 import Swinject
 
 
-protocol HealthKitManager {
+protocol HealthKitManager: GlucoseSource {
     /// Check availability HealthKit on current device and user's permissions
     /// Check availability HealthKit on current device and user's permissions
     var isAvailableOnCurrentDevice: Bool { get }
     var isAvailableOnCurrentDevice: Bool { get }
     /// Check all needed permissions
     /// Check all needed permissions
@@ -24,6 +25,7 @@ final class BaseHealthKitManager: HealthKitManager, Injectable {
     @Injected() private var fileStorage: FileStorage!
     @Injected() private var fileStorage: FileStorage!
     @Injected() private var glucoseStorage: GlucoseStorage!
     @Injected() private var glucoseStorage: GlucoseStorage!
     @Injected() private var healthKitStore: HKHealthStore!
     @Injected() private var healthKitStore: HKHealthStore!
+    @Injected() private var settingsManager: SettingsManager!
 
 
     private enum Config {
     private enum Config {
         // unwraped HKObjects
         // unwraped HKObjects
@@ -42,6 +44,8 @@ final class BaseHealthKitManager: HealthKitManager, Injectable {
         static let frequencyBackgroundDeliveryBloodGlucoseFromHealth = HKUpdateFrequency(rawValue: 10)!
         static let frequencyBackgroundDeliveryBloodGlucoseFromHealth = HKUpdateFrequency(rawValue: 10)!
     }
     }
 
 
+    private var newGlucose: [BloodGlucose] = []
+
     var isAvailableOnCurrentDevice: Bool {
     var isAvailableOnCurrentDevice: Bool {
         HKHealthStore.isHealthDataAvailable()
         HKHealthStore.isHealthDataAvailable()
     }
     }
@@ -98,6 +102,8 @@ final class BaseHealthKitManager: HealthKitManager, Injectable {
     }
     }
 
 
     func save(bloodGlucoses: [BloodGlucose], completion: ((Result<Bool, Error>) -> Void)? = nil) {
     func save(bloodGlucoses: [BloodGlucose], completion: ((Result<Bool, Error>) -> Void)? = nil) {
+        guard settingsManager.settings.useAppleHealth else { return }
+
         for bgItem in bloodGlucoses {
         for bgItem in bloodGlucoses {
             let bgQuantity = HKQuantity(
             let bgQuantity = HKQuantity(
                 unit: .milligramsPerDeciliter,
                 unit: .milligramsPerDeciliter,
@@ -128,6 +134,8 @@ final class BaseHealthKitManager: HealthKitManager, Injectable {
     }
     }
 
 
     func createObserver() {
     func createObserver() {
+        guard settingsManager.settings.useAppleHealth else { return }
+
         guard let bgType = Config.healthBGObject else {
         guard let bgType = Config.healthBGObject else {
             warning(
             warning(
                 .service,
                 .service,
@@ -158,6 +166,8 @@ final class BaseHealthKitManager: HealthKitManager, Injectable {
     }
     }
 
 
     func enableBackgroundDelivery() {
     func enableBackgroundDelivery() {
+        guard settingsManager.settings.useAppleHealth else { return }
+
         guard let bgType = Config.healthBGObject else {
         guard let bgType = Config.healthBGObject else {
             warning(
             warning(
                 .service,
                 .service,
@@ -192,13 +202,8 @@ final class BaseHealthKitManager: HealthKitManager, Injectable {
             }
             }
 
 
             DispatchQueue.global(qos: .utility).async {
             DispatchQueue.global(qos: .utility).async {
-                var removingBGID = [String]()
-                samples.forEach {
-                    if let idString = $0.metadata?["HKMetadataKeySyncIdentifier"] as? String {
-                        removingBGID.append(idString)
-                    } else {
-                        removingBGID.append($0.uuid.uuidString)
-                    }
+                let removingBGID = samples.map {
+                    $0.metadata?["HKMetadataKeySyncIdentifier"] as? String ?? $0.uuid.uuidString
                 }
                 }
                 glucoseStorage.removeGlucose(byIDCollection: removingBGID)
                 glucoseStorage.removeGlucose(byIDCollection: removingBGID)
             }
             }
@@ -214,29 +219,29 @@ final class BaseHealthKitManager: HealthKitManager, Injectable {
             sortDescriptors: nil
             sortDescriptors: nil
         ) { [unowned self] _, results, _ in
         ) { [unowned self] _, results, _ in
 
 
-            guard let samples = results as? [HKQuantitySample] else {
+            guard let samples = results as? [HKQuantitySample], samples.isNotEmpty else {
                 return
                 return
             }
             }
 
 
             let oldSamples: [HealthKitSample] = fileStorage
             let oldSamples: [HealthKitSample] = fileStorage
                 .retrieve(OpenAPS.HealthKit.downloadedGlucose, as: [HealthKitSample].self) ?? []
                 .retrieve(OpenAPS.HealthKit.downloadedGlucose, as: [HealthKitSample].self) ?? []
 
 
-            var newSamples = [HealthKitSample]()
-            for sample in samples {
-                if sample.wasUserEntered {
-                    newSamples.append(HealthKitSample(
+            let newSamples = samples
+                .compactMap { sample -> HealthKitSample? in
+                    let fromFAX = sample.metadata?["fromFreeAPSX"] as? Bool ?? false
+                    guard !fromFAX else { return nil }
+                    return HealthKitSample(
                         healthKitId: sample.uuid.uuidString,
                         healthKitId: sample.uuid.uuidString,
                         date: sample.startDate,
                         date: sample.startDate,
                         glucose: Int(round(sample.quantity.doubleValue(for: .milligramsPerDeciliter)))
                         glucose: Int(round(sample.quantity.doubleValue(for: .milligramsPerDeciliter)))
-                    ))
+                    )
                 }
                 }
-            }
-
-            newSamples = newSamples
                 .filter { !oldSamples.contains($0) }
                 .filter { !oldSamples.contains($0) }
 
 
-            newSamples.forEach({ sample in
-                let glucose = BloodGlucose(
+            guard newSamples.isNotEmpty else { return }
+
+            let newGlucose = newSamples.map { sample in
+                BloodGlucose(
                     _id: sample.healthKitId,
                     _id: sample.healthKitId,
                     sgv: sample.glucose,
                     sgv: sample.glucose,
                     direction: nil,
                     direction: nil,
@@ -248,8 +253,9 @@ final class BaseHealthKitManager: HealthKitManager, Injectable {
                     glucose: sample.glucose,
                     glucose: sample.glucose,
                     type: "sgv"
                     type: "sgv"
                 )
                 )
-                glucoseStorage.storeGlucose([glucose])
-            })
+            }
+
+            self.newGlucose = newGlucose
 
 
             let savingSamples = (newSamples + oldSamples)
             let savingSamples = (newSamples + oldSamples)
                 .removeDublicates()
                 .removeDublicates()
@@ -259,6 +265,15 @@ final class BaseHealthKitManager: HealthKitManager, Injectable {
         }
         }
         return query
         return query
     }
     }
+
+    func fetch() -> AnyPublisher<[BloodGlucose], Never> {
+        guard settingsManager.settings.useAppleHealth else { return Just([]).eraseToAnyPublisher() }
+
+        let copy = newGlucose
+        newGlucose = []
+
+        return Just(copy).eraseToAnyPublisher()
+    }
 }
 }
 
 
 enum HealthKitPermissionRequestStatus {
 enum HealthKitPermissionRequestStatus {