iosswifthkhealthstore

Reading Heart Rate from HealthStore


I'm trying to retrieve the Heart rate information from the Healthkit.

I have some heart rate data on my profile.

Here is my query:

private func createStreamingQuery() -> HKQuery {
    let predicate = HKQuery.predicateForSamples(withStart: NSDate() as Date, end: nil, options: [])

    let query = HKAnchoredObjectQuery(type: heartRateType, predicate: predicate, anchor: nil, limit: Int(HKObjectQueryNoLimit)) {
        (query, samples, deletedObjects, anchor, error) -> Void in

        self.formatSamples(samples: samples)

    }

    query.updateHandler = { (query, samples, deletedObjects, anchor, error) -> Void in
        self.formatSamples(samples: samples)
    }

    return query
}

And now my function format Samples:

private func formatSamples(samples: [HKSample]?) {
    guard let heartRateSamples = samples as? [HKQuantitySample] else { return }

        guard let sample = heartRateSamples.first else{return}
        let value = sample.quantity.doubleValue(for: self.heartRateUnit)

        print("HeartRate: \(value)")
}

I already debugged and I found that in the first line of code of "formatSamples", the list "samples" has a lot of values,

 guard let heartRateSamples = samples as? [HKQuantitySample] else { return } 

but when I try to get the first value of this list, suddenly my list is empty and it ends the function. Here->

guard let sample = heartRateSamples.first else{return}

I don't understand why the samples list empties by itself from one line to the next one.

The query is executed.

@IBAction func readHeartRate(_ sender: Any) {
    self.healthStore.execute(self.createStreamingQuery())
}

Can you help me?


Solution

  • The problem was my predicate who was incorrect.

    Here an example of a correct predicate that I used. It limits the results to the last seven days.

    let calendar = NSCalendar.current;
    let now = NSDate();
    let sevenDaysAgo = calendar.date(byAdding: .day, value: -7, to: now as Date);
    let startDate = calendar.startOfDay(for: sevenDaysAgo!);
    
    let predicate = HKQuery.predicateForSamples(withStart: startDate as Date, end: now as Date, options: [])