Search code examples
swiftapple-watchhealthkitwatchosheartrate

Problems returning heart rate values using `HKAnchoredObjectQuery` on Series 5 Watch and Watch OS6


I am using HKAnchoredObjectQuery to query for heart rates as I would prefer not to use the WorkoutBuilder API for this app. This query has always returned heart rates during a workout at normal sample rates (per second etc) but I noticed that while testing on a Series 5 Watch OS 6.1 I am only seeing very sporadic samples e.g. 5 heart rates taken in an hour. There is nothing in the documentation for HKAnchoredObjectQuery that it is being deprecated. Any idea why this method of heart rate collection is no longer working?

    func startHeartRateQuery(from startDate: Date, updateHandler: @escaping ([HKQuantitySample]) -> Void) {
        let typeIdentifier = HKQuantityTypeIdentifier.heartRate
        startQuery(ofType: typeIdentifier, from: startDate) { _, samples, _, _, error in
            guard let quantitySamples = samples as? [HKQuantitySample] else {
                print("Heart rate query failed with error: \(String(describing: error))")
                return
            }
            updateHandler(quantitySamples)

        }
    }


   //Generic helper function 
    private func startQuery(ofType type: HKQuantityTypeIdentifier, from startDate: Date, handler: @escaping
        (HKAnchoredObjectQuery, [HKSample]?, [HKDeletedObject]?, HKQueryAnchor?, Error?) -> Void) {
        let datePredicate = HKQuery.predicateForSamples(withStart: startDate, end: nil, options: .strictStartDate)
        let devicePredicate = HKQuery.predicateForObjects(from: [HKDevice.local()])
        let queryPredicate = NSCompoundPredicate(andPredicateWithSubpredicates:[datePredicate, devicePredicate])

        let quantityType = HKObjectType.quantityType(forIdentifier: type)!

        let query = HKAnchoredObjectQuery(type: quantityType, predicate: queryPredicate, anchor: nil,
                                          limit: HKObjectQueryNoLimit, resultsHandler: handler)
        query.updateHandler = handler
        healthStore.execute(query)

        activeDataQueries.append(query)
    }

Solution

  • Strange but it turns out I had Workout Power Saving Mode set to on in the Watch App's settings. Unless I set by accident it was set to on when I installed Watch OS 6? After turning it off the heart rate queries are returning normally again.