The edited code still has the problem of not lining up with the health app
private func fetchSleepData(for date: Date) {
let sleepType = HKObjectType.categoryType(forIdentifier: .sleepAnalysis)!
let endOfPeriod = date
let startOfPeriod = Calendar.current.date(byAdding: .day, value: -1, to: endOfPeriod)!
let predicate = HKQuery.predicateForSamples(withStart: startOfPeriod, end: endOfPeriod, options: [.strictStartDate, .strictEndDate])
let query = HKSampleQuery(sampleType: sleepType, predicate: predicate, limit: HKObjectQueryNoLimit, sortDescriptors: nil) { query, samples, error in
guard let samples = samples as? [HKCategorySample], !samples.isEmpty else {
DispatchQueue.main.async {
self.inBedTime = 0
self.coreTime = 0
self.deepTime = 0
self.remTime = 0
self.isSleepDataAvailable = false
}
print("No sleep data available for date: \(date)")
return
}
print("Fetched \(samples.count) sleep samples for date: \(date)")
var inBedTime = 0.0
var asleepTime = 0.0
var deepTime = 0.0
var remTime = 0.0
for sample in samples {
print("Sample value: \(sample.value)")
let duration = sample.endDate.timeIntervalSince(sample.startDate) / 60 // convert to minutes
switch sample.value {
case HKCategoryValueSleepAnalysis.inBed.rawValue:
inBedTime += duration
case HKCategoryValueSleepAnalysis.asleepCore.rawValue:
coreTime += duration
case HKCategoryValueSleepAnalysis.asleepDeep.rawValue:
deepTime += duration
case HKCategoryValueSleepAnalysis.asleepREM.rawValue:
remTime += duration
default:
break
}
}
DispatchQueue.main.async {
self.inBedTime = inBedTime
self.coreTime = coreTime
self.deepTime = deepTime
self.remTime = remTime
self.isSleepDataAvailable = true
}
}
healthStore?.execute(query)
}