codeman
codeman

Reputation: 9038

How to differentiate sources with HealthKit sleep query

I'm currently using the following code to query for the number of hours the user was asleep in the last 24 hours:

   func getHealthKitSleep() {
        let healthStore = HKHealthStore()
        let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierEndDate, ascending: false)

        // Get all samples from the last 24 hours
        let endDate = Date()
        let startDate = endDate.addingTimeInterval(-1.0 * 60.0 * 60.0 * 24.0)
        let predicate = HKQuery.predicateForSamples(withStart: startDate, end: endDate, options: [])

        // Sleep query
        let sleepQuery = HKSampleQuery(
            sampleType: HKObjectType.categoryType(forIdentifier: HKCategoryTypeIdentifier.sleepAnalysis)!,
            predicate: predicate,
            limit: 0,
            sortDescriptors: [sortDescriptor]){ (query, results, error) -> Void in
                if error != nil {return}
                // Sum the sleep time
                var minutesSleepAggr = 0.0
                if let result = results {
                    for item in result {
                        if let sample = item as? HKCategorySample {
                            if sample.value == HKCategoryValueSleepAnalysis.asleep.rawValue && sample.startDate >= startDate {
                                let sleepTime = sample.endDate.timeIntervalSince(sample.startDate)
                                let minutesInAnHour = 60.0
                                let minutesBetweenDates = sleepTime / minutesInAnHour
                                minutesSleepAggr += minutesBetweenDates
                            }
                        }
                    }
                    self.sleep = Double(String(format: "%.1f", minutesSleepAggr / 60))!
                    print("HOURS: \(String(describing: self.sleep))")
                }
        }
        // Execute our query
        healthStore.execute(sleepQuery)
    }

This works great if the user has only one sleep app as the source for the data. The problem is if the user is using 2 sleep apps, for example, as sources, the data will be doubled. How can I differentiate the sources? If able to differentiate the sources, I would like to either only grab data from one source, or maybe take the average of the sources.

Upvotes: 3

Views: 1495

Answers (1)

Belle B. Cooper
Belle B. Cooper

Reputation: 395

When you're looping over the samples, you can access information about the source for each. I only accept a single source, so I just keep a variable of the source name and if the current sample has a different source name I continue looping without processing the data from that sample, but you could combine the data in other ways if you wanted to.

Here's how to access the source info:

if let sample = item as? HKCategorySample {
    let name = sample.sourceRevision.source.name
    let id = sample.sourceRevision.source.bundleIdentifier
}

There's some more info on the HKSourceRevision object in the docs here.

Upvotes: 5

Related Questions