想使用swift中的healthkit同步获取睡眠数据吗

想使用swift中的healthkit同步获取睡眠数据吗,swift,nsoperationqueue,healthkit,Swift,Nsoperationqueue,Healthkit,我试图从healthkit获取7天睡眠数据,并在图表中显示。但在这里我遇到了一些挑战 当我在这个函数中传递开始日期和结束日期时,我得到了所有的值,但是这些值的顺序不正确。意味着我正在异步获取值 异步调用我在操作队列中添加了它们。但我还是犯了一个错误 我得到了不同的回应。因此,图表也没有正确显示。我还必须通过调用Api将最后一天的数据发送到服务器。但我最后的数据是不正确的 我在循环中调用sleep函数。在循环中获得单个日期后,我调用函数并将其添加到操作队列中 所以我的图表没有正确显示 获取

我试图从healthkit获取7天睡眠数据,并在图表中显示。但在这里我遇到了一些挑战

  • 当我在这个函数中传递开始日期和结束日期时,我得到了所有的值,但是这些值的顺序不正确。意味着我正在异步获取值

  • 异步调用我在操作队列中添加了它们。但我还是犯了一个错误

  • 我得到了不同的回应。因此,图表也没有正确显示。我还必须通过调用Api将最后一天的数据发送到服务器。但我最后的数据是不正确的

  • 我在循环中调用sleep函数。在循环中获得单个日期后,我调用函数并将其添加到操作队列中

  • 所以我的图表没有正确显示

    获取睡眠数据的代码-

    
      class func getSleepHours(from startDate: Date?, to endDate: Date?, completion: @escaping(_ result: [HKSample])-> Void)  {
            
            let typestoRead = Set([
                HKObjectType.categoryType(forIdentifier: HKCategoryTypeIdentifier.sleepAnalysis)!
            ])
            
            let typestoShare = Set([
                HKObjectType.categoryType(forIdentifier: HKCategoryTypeIdentifier.sleepAnalysis)!
            ])
            
            HKHealthStore().requestAuthorization(toShare: typestoShare, read: typestoRead) { (success, error) -> Void in
                if success == false {
                    NSLog(" Display not allowed")
                }
                
                if let sleepType = HKObjectType.categoryType(forIdentifier: HKCategoryTypeIdentifier.sleepAnalysis) {
                    
                    let formatter = DateFormatter()
                    formatter.dateFormat = "yyyy/MM/dd HH:mm"
                    
                    let predciate = HKQuery.predicateForSamples(withStart: startDate, end: endDate, options: .strictEndDate)
                    
                    let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierEndDate, ascending: false)
                    
                    DispatchQueue.main.async {
                     
                    let query = HKSampleQuery(sampleType: sleepType, predicate: predciate, limit: 1, sortDescriptors: [sortDescriptor]) { (query, tmpResult, error) -> Void in
                        
                        if let result = tmpResult {
                            completion(tmpResult!)
                            
                        }else{
                            print(error?.localizedDescription)
                        }
                    }
                    
                    HKHealthStore().execute(query)
                }
                }
            }
        }
    
    func getRecordSleepCountActivity(){
            var sleepBar = [(String, Double)]()
            sleepDataDictionaryArray.removeAll()
            arrayToBeUploadedToServer.removeAll()
            sleepBar.removeAll()
            let currentDateStr = Common.instance.getDateStringFromDate()
            let lastSevenDays = Date.getPerticularDates(forLastNDays: 6)
            let queue = OperationQueue()
            queue.qualityOfService = .userInitiated
            queue.maxConcurrentOperationCount = 1
            
            let serialQueue = DispatchQueue(label: "queuename")
            
            for i in lastSevenDays{
                
                var calendar = Calendar.current
                calendar.timeZone = NSTimeZone(abbreviation: "UTC")! as TimeZone
                let newStartTime = calendar.startOfDay(for: i)
                print("Start Time is \(newStartTime)")
                let newEndTime = calendar.date(bySettingHour: 23, minute: 59, second: 59, of: i)
                print("end Time is \(newEndTime)")
                
                queue.addOperation {
                    
                    ProfileDataStore.getSleepHours(from: newStartTime, to: newEndTime) { [self] (data) in
                        self.totalSleepHourFromHealthKit = 0
                        print("sleep data count is \(data.count) for \(i)")
                        for item in data {
                            if let sample = item as? HKCategorySample {
                                
                                let sleepTimeForOneDay = sample.endDate.timeIntervalSince(sample.startDate)
                                let sleepTimeForOneDayInHour = sleepTimeForOneDay / 60
                                self.sleepValue =  String(describing: sleepTimeForOneDayInHour)
                                let StartTime =  self.getNewDateAndTimeFormat(sampleDateString:sample.startDate.description, format: "MM/dd/yyyy HH:mm:ss a")
                                let endTime = self.getNewDateAndTimeFormat(sampleDateString:sample.endDate.description, format: "MM/dd/yyyy HH:mm:ss a")
                                let newSleepDict = [ "StartTime": StartTime,
                                                     "EndTime":endTime,
                                                     "Hours":self.sleepValue]
                                print("newSleepDict is \(newSleepDict)")
                                self.totalSleepHourFromHealthKit += Int(sleepTimeForOneDayInHour)
                                sleepDataDictionaryArray.append(newSleepDict)
                                print("sleepDataDictionaryArray is \(sleepDataDictionaryArray)")
                                
                            }
                        }
                        
                        print("sleep bars are \(sleepBar)")
                        self.sleepMax = 24
                        self.sleepMin = 2
                        let dateFormatterGet = DateFormatter()
                        dateFormatterGet.dateFormat = "MM/dd/yyyy HH:mm:ss a"
                        let dateFormatterPrint = DateFormatter()
                        dateFormatterPrint.dateFormat = "EE"
                        
                        let sleepDate = (dateFormatterPrint.string(from: i))
                        sleepValues = (sleepDate,Double(self.totalSleepHourFromHealthKit))
                        //                            let value = (sleepDate,sleepTimeForOneDayInHour)
                        print("sleep values are \(sleepValues)")
                        //                            sleepBar.append(value)
                        sleepBar.append(sleepValues)
                    }
                }
                
            }
            
             queue.addOperation {
                
                DispatchQueue.main.async {
                    //                print("sleep values are \(sleepValues)")
                    let chartConfig = BarsChartConfig(
                        valsAxisConfig: ChartAxisConfig(from: 0, to: Double(self.sleepMax), by: 2)
                    )
                    let frame = CGRect(x: 0, y: 0, width: self.sleepViewBar.frame.size.width, height: self.sleepViewBar.frame.size.height - 10)
                    let sleepChart = BarsChart(
                        frame: frame,
                        chartConfig: chartConfig,
                        xTitle: "",
                        yTitle: "Sleep hour",
                        bars: sleepBar,
                        color: UIColor.red,
                        barWidth: 10
                    )
                    sleepChart.view.reloadInputViews()
                    self.sleepViewBar.addSubview(sleepChart.view)
                    self.sleepViewChart = sleepChart
                    self.sleepViewChart.update()
                }
                
            }
            }
    
        I am getting response like -
    
            sleep values are ("Sun", 0.0)
    sleep values are ("Mon", 0.0)
    sleep values are ("Wed", 105.0)
    sleep values are ("Thu", 161.0)
    sleep values are ("Tue", 221.0)
    sleep values are ("Fri", 2901.0)
    sleep values are ("Sat", 0.0)
    
    
      class func getSleepHours(from startDate: Date?, to endDate: Date?, completion: @escaping(_ result: [HKSample])-> Void)  {
            
            let typestoRead = Set([
                HKObjectType.categoryType(forIdentifier: HKCategoryTypeIdentifier.sleepAnalysis)!
            ])
            
            let typestoShare = Set([
                HKObjectType.categoryType(forIdentifier: HKCategoryTypeIdentifier.sleepAnalysis)!
            ])
            
            HKHealthStore().requestAuthorization(toShare: typestoShare, read: typestoRead) { (success, error) -> Void in
                if success == false {
                    NSLog(" Display not allowed")
                }
                
                if let sleepType = HKObjectType.categoryType(forIdentifier: HKCategoryTypeIdentifier.sleepAnalysis) {
                    
                    let formatter = DateFormatter()
                    formatter.dateFormat = "yyyy/MM/dd HH:mm"
                    
                    let predciate = HKQuery.predicateForSamples(withStart: startDate, end: endDate, options: .strictEndDate)
                    
                    let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierEndDate, ascending: false)
                    
                    DispatchQueue.main.async {
                     
                    let query = HKSampleQuery(sampleType: sleepType, predicate: predciate, limit: 1, sortDescriptors: [sortDescriptor]) { (query, tmpResult, error) -> Void in
                        
                        if let result = tmpResult {
                            completion(tmpResult!)
                            
                        }else{
                            print(error?.localizedDescription)
                        }
                    }
                    
                    HKHealthStore().execute(query)
                }
                }
            }
        }