如何仅查询 HealthKit 以获取给定日期的总“在床上”时间?

Posted

技术标签:

【中文标题】如何仅查询 HealthKit 以获取给定日期的总“在床上”时间?【英文标题】:How to only query HealthKit for Total "In Bed" time for a given day? 【发布时间】:2020-12-23 00:10:47 【问题描述】:

互联网上没有用于查询睡眠数据的完整示例代码。下面的代码将返回给定日期的所有睡眠样本,如果您查看 Apple Health App,其中包括来自 Apple Watch 的“睡眠”样本,它们是睡眠间隔,但也有来自 iPhone 的“床上”样本,其中包含从上床到下床的总范围。如何仅查询 HealthKit 中的这个 In Bed 样本?

func sleepTime() 
        let healthStore = HKHealthStore()
        // startDate and endDate are NSDate objects
        // first, we define the object type we want
        if let sleepType = HKObjectType.categoryType(forIdentifier: HKCategoryTypeIdentifier.sleepAnalysis) 
            // You may want to use a predicate to filter the data... startDate and endDate are NSDate objects corresponding to the time range that you want to retrieve
            //let predicate = HKQuery.predicateForSamplesWithStartDate(startDate,endDate: endDate ,options: .None)
            // Get the recent data first
            let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierEndDate, ascending: false)
            // the block completion to execute
            let query = HKSampleQuery(sampleType: sleepType, predicate: nil, limit: 100000, sortDescriptors: [sortDescriptor])  (query, tmpResult, error) -> Void in
                if error != nil 
                    // Handle the error in your app gracefully
                    return
                
                if let result = tmpResult 
                   for item in result 
                        if let sample = item as? HKCategorySample 
                               let startDate = sample.startDate
                               let endDate = sample.endDate
                               print()
                             let sleepTimeForOneDay = sample.endDate.timeIntervalSince(sample.startDate)
                        
                    
                
          
    

【问题讨论】:

【参考方案1】:

HKCategorySample 包含 Int 类型的 value,它是样本的枚举值。 它具有三个值:

0 -> 在床上

1 -> 睡着了

2 -> 清醒

因此,如果您只需要 inBed 数据,建议的更改是:

if let result = tmpResult 
                for item in result 
                    if let sample = item as? HKCategorySample 
                        if sample.value == 0 
                            let startDate = sample.startDate
                            let endDate = sample.endDate
                            print()
                            let sleepTimeForOneDay = sample.endDate.timeIntervalSince(sample.startDate)
                            
                        
                    
                
            

更好的方法是使用 switch 案例。

if let result = tmpResult 
                for item in result 
                    if let sample = item as? HKCategorySample 
                        switch sample.value 
                        case 0:
                            // inBed, write logic here
                            print("inBed")
                        case 1:
                            // asleep, write logic here
                            print("asleep")
                        default:
                            // awake, write logic here
                            print("awake")
                        
                    
                
            

【讨论】:

以上是关于如何仅查询 HealthKit 以获取给定日期的总“在床上”时间?的主要内容,如果未能解决你的问题,请参考以下文章

获取 HealthKit 中每个日期的总步数

如何创建查询以显示本周 sql 的每个日期的总销售额 [关闭]

如何获取以前日期的 HealthKit 总步数

如何获取以前日期的 HealthKit 总步数

如何在时间戳字段中仅使用日期来选择记录?

如何使用 HealthKit 从特定日期准确获取 24 小时的睡眠数据?