How can I get non-overlapping sleep samples from HealthKit in Swift?

I am trying to get sleep samples for last 7 days and store them and add whenever I want. I am using HKSampleQuery to fetch all the samples and storing samples which are only inBed samples but sometimes I am getting multiple samples with overlapped time intervals. How to get proper sleep data without any overlaps? I am using below code to get the data

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)

Replies

Hello, if your device contains overlapping in bed intervals from multiple source then that's what the query will return. It will be up to you to decide how you want to handle it. You could ignore certain sources if you want, for example. Or you can keep track of the intervals yourselves in some kind of data structure.