Post

Replies

Boosts

Views

Activity

HKObserverQuery updateHandler is getting fired twice in a row
Hi, I'm trying to implement HealthKit Background delivery for my app and I'm getting a strange behavior where the HKObserverQuery updateHandler is getting fired twice. I'm running Xcode 13.4 & iOS 15.5. 2022-06-10 10:05:58.725006+0200 Cori[79737:8949689] [HealthKit] Run Background Delivery Handler 2022-06-10 10:05:58.726283+0200 Cori[79737:8949689] [HealthKit] Run Background Delivery Handler 2022-06-10 10:05:58.736475+0200 Cori[79737:8949700] [HealthKit] New data: [200 mg/dL 4680E3F5-034A-4AED-843C-9066532AD459 "Salud" (15.5), "iPhone14,2" (15.5)metadata: { 2022-06-10 10:05:58.736632+0200 Cori[79737:8949700] [HealthKit] 1 new HKQuantityTypeIdentifierBloodGlucose samples 2022-06-10 10:05:58.736926+0200 Cori[79737:8949689] [persistence] HealthKit: Start import to Core Data 2022-06-10 10:05:58.737116+0200 Cori[79737:8949700] [HealthKit] New data: [200 mg/dL 4680E3F5-034A-4AED-843C-9066532AD459 "Salud" (15.5), "iPhone14,2" (15.5)metadata: { 2022-06-10 10:05:58.737985+0200 Cori[79737:8949689] [persistence] HealthKit: 1 samples of type HKQuantityTypeIdentifierBloodGlucose not from this app! 2022-06-10 10:05:58.753583+0200 Cori[79737:8949689] [persistence] HealthKit: Start batch insert request. 2022-06-10 10:05:58.753630+0200 Cori[79737:8949700] [HealthKit] 1 new HKQuantityTypeIdentifierBloodGlucose samples 2022-06-10 10:05:58.753873+0200 Cori[79737:8949689] [persistence] HealthKit: Start import to Core Data 2022-06-10 10:05:58.754019+0200 Cori[79737:8949689] [persistence] HealthKit: 1 samples of type HKQuantityTypeIdentifierBloodGlucose not from this app! 2022-06-10 10:05:58.754076+0200 Cori[79737:8949689] [persistence] HealthKit: Start batch insert request. 2022-06-10 10:05:58.759208+0200 Cori[79737:8949701] [persistence] HealthKit: Successfully imported data. 2022-06-10 10:05:58.759669+0200 Cori[79737:8949701] [persistence] HealthKit: Successfully imported data. This is my code: App Delegate extension AppDelegate {     public func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {         if settings.syncHealthKit { HealthKit.shared.setUpBackgroundDelivery()         }         return true     } HealthKit Class class HealthKit: ObservableObject {     private let logger = Logger(subsystem: "com.ChubbyApps.Diabetes", category: "HealthKit")     private var dataController: DataController = .shared     private var ajustes: AjustesModel = .shared     public let isAvailable = HKHealthStore.isHealthDataAvailable()     private lazy var isAuthorized = false     // MARK: - Properties     private var anchor: HKQueryAnchor? {         get {             guard let data = NSUbiquitousKeyValueStore.default.object(forKey: Keys.HKAnchor) as? Data else {                 return nil             }             do {                 return try NSKeyedUnarchiver.unarchivedObject(ofClass: HKQueryAnchor.self, from: data)             } catch {                 logger.error("Unable to unarchive \(data): \(error.localizedDescription)")                 return nil             }         }         set(newAnchor) {             guard let newAnchor = newAnchor else {                 return             }             do {                 let data = try NSKeyedArchiver.archivedData(withRootObject: newAnchor, requiringSecureCoding: true)                 NSUbiquitousKeyValueStore.default.set(data, forKey: Keys.HKAnchor)             } catch {                 logger.error("Unable to archive \(newAnchor): \(error.localizedDescription)")             }         }     }     // MARK: - Initializers     static let shared = HealthKit()     // MARK: - Public Methods     public func requestAuthorization() async -> Bool {         guard isAvailable else { return false }         do {             try await HKStore.requestAuthorization(toShare: types, read: types)             self.isAuthorized = true             return true         } catch let error {             self.logger.error("An error occurred while requesting HealthKit Authorization: \(error.localizedDescription)")             return false         }     }     // MARK: - Background     func setUpBackgroundDelivery() {         let query: HKObserverQuery = HKObserverQuery(sampleType: glucose, predicate: nil, updateHandler: self.backgroundDeliveryHandler)         HKStore.execute(query)         HKStore.enableBackgroundDelivery(for: glucose, frequency: .immediate) { success, error in             if success {                 self.logger.debug("Enabled background delivery of stepcount changes")             } else {                 if let theError = error {                     self.logger.debug("Failed to enable background delivery of stepcount changes. Error: \(theError.localizedDescription)")                 }             }         }     }     func backgroundDeliveryHandler(query: HKObserverQuery!, completionHandler: HKObserverQueryCompletionHandler!, error: Error!) {         self.logger.debug("Run Background Delivery Handler")         self.anchoredQueryFor(types)          completionHandler()     }     private func anchoredQueryFor(_ tipos: Set<HKSampleType>) {         var queryDescriptors = [HKQueryDescriptor]()         for type in tipos {             queryDescriptors.append(HKQueryDescriptor(sampleType: type, predicate: nil))         }         let anchoredQuery = HKAnchoredObjectQuery(             queryDescriptors: queryDescriptors,             anchor: anchor,             limit: HKObjectQueryNoLimit) { _, newSamples, _, newAnchor, error in                 if let error = error {                     self.logger.error("HKAnchoredObjectQuery error: \(error.localizedDescription)")                     return                 }                 self.anchor = newAnchor                 guard let samples = newSamples as? [HKQuantitySample] else { return }                 guard !samples.isEmpty else { return }                 self.logger.debug("New data: \(samples.debugDescription)")                 for type in types {                     let filteredSamples = samples.filter({ $0.quantityType == type })                     if  !filteredSamples.isEmpty {                         self.logger.debug("\(filteredSamples.count) new \(type.debugDescription) samples")                         Task {                             do {                                 try await self.dataController.importHealthKitSample(filteredSamples, type: type)                             } catch {                                 self.logger.error("importHealthKitSample error: \(error.localizedDescription)")                             }                         }                     }                 }             }         HKStore.execute(anchoredQuery)     }
3
0
1.9k
Jun ’22