swifthealthkitnstimeinterval

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)
    }

Solution

  • I tried this solution https://stackoverflow.com/a/63600255/13882733 which takes different samples with overlapping or non overlapping time intervals and skip the ones that overlap. it's working fine for me.