我正试图获得过去7天的睡眠样本,并存储它们,并随时添加我想要的。我使用HKSampleQuery来获取所有的样本,并存储仅在床上的样本,但有时我会得到多个时间间隔重叠的样本。如何在没有任何重叠的情况下获得正确的睡眠数据?我使用下面的代码来获取数据
func readSleep(from startDate: Date?, to endDate: Date?,Id:Int, Completion: @escaping (Double,Date,Date,Int,String)->Void) {
var sleepingHoursCount = 0.0
let healthStore = HKHealthStore()
guard let sleepType = HKObjectType.categoryType(forIdentifier: .sleepAnalysis) else {
return
}
let predicate = HKQuery.predicateForSamples(withStart: startDate, end: endDate, options: .strictEndDate)
let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierEndDate, ascending: false)
let query = HKSampleQuery(sampleType: sleepType, predicate: predicate, limit: HKObjectQueryNoLimit, sortDescriptors: [sortDescriptor]) { (query, result, error) in
if error != nil {
return
}
guard let result = result else{
Completion(sleepingHoursCount,startDate!,endDate!,Id,"")
return
}
// do{
if let sleepSamples = result as? [HKCategorySample] {
for sample in sleepSamples {
guard let sleepValue = HKCategoryValueSleepAnalysis(rawValue: sample.value) else {
return
}
let isInBed = sleepValue == .inBed
if(isInBed){
let diffSeconds = sample.endDate.timeIntervalSinceReferenceDate - sample.startDate.timeIntervalSinceReferenceDate
sleepingHoursCount += diffSeconds
Completion(diffSeconds/3600,sample.startDate,sample.endDate,Id,source)
}
}
}
}
healthStore.execute(query)
}
2条答案
按热度按时间xtupzzrd1#
这个Swift函数从HealthKit商店读取睡眠数据,HealthKit商店是苹果HealthKit框架的一部分,为iPhone和Apple Watch上的健康和健身数据提供了一个中央存储库。
函数
readSleep(from:to:id:completion:)
有四个参数:startDate: Date?
和endDate: Date?
是可选的日期,指示提取睡眠数据的开始和结束日期。id: Int
似乎是通过完成处理程序传递回调用者的某种标识符。completion: @escaping (Double, Date, Date, Int, String) -> Void
是一个completion handler闭包。当获取睡眠数据时调用该函数,闭包接收总睡眠时间(以秒为单位)(Double
)、开始和结束日期(Date
)、传递的标识符(Int
)和一个字符串参数。该函数从HealthKit存储读取睡眠数据,计算总睡眠持续时间(以秒为单位),并使用此数据调用完成处理程序。
但是,此功能中有一些方面可以改进:
1.错误处理未完成。当执行
HKSampleQuery
时发生错误时,它只是从函数返回。更合适的做法是同时调用完成处理程序并向调用方给予有关错误的信息。1.该函数对
completion
闭包中的startDate和endDate使用强制展开。在Swift中,通常不鼓励强制解包,因为如果解包的值是nil
,则可能导致运行时错误。最好安全地打开这些可选值。1.函数似乎使用了一个未在函数范围内定义的变量源。下面是该函数的一个改进版本,它解决了这些问题:
pbossiut2#
我尝试了这个解决方案https://stackoverflow.com/a/63600255/13882733,它采用重叠或不重叠时间间隔的不同样本,并跳过重叠的样本。我觉得挺好的。