Ios 如何检查HealthKit功能何时完成(Swift)

Ios 如何检查HealthKit功能何时完成(Swift),ios,swift,function,healthkit,completionhandler,Ios,Swift,Function,Healthkit,Completionhandler,好吧,标题真的说明了一切,我还没有找到一个适合我的答案,所以我转向StackOverFlow。我正在尝试获取用户步数并将该值分配给UILabel。下面是我的一些代码(请注意,该函数包含在另一个类中,因此标签不在该函数的范围内): 然后,当我在实际设备上运行应用程序时,我看到标签文本为零,我知道我今天做了一些行走:)。因此,我认为问题在于,当我试图设置labels值时,函数还没有完全执行完毕 我知道这一点,因为当我使用函数并等待两秒钟时,我最终得到一个值,但如果我不等待,那么我得到的值为零 因此,

好吧,标题真的说明了一切,我还没有找到一个适合我的答案,所以我转向StackOverFlow。我正在尝试获取用户步数并将该值分配给UILabel。下面是我的一些代码(请注意,该函数包含在另一个类中,因此标签不在该函数的范围内):

然后,当我在实际设备上运行应用程序时,我看到标签文本为零,我知道我今天做了一些行走:)。因此,我认为问题在于,当我试图设置labels值时,函数还没有完全执行完毕

我知道这一点,因为当我使用函数并等待两秒钟时,我最终得到一个值,但如果我不等待,那么我得到的值为零

因此,主要问题是:如何检查函数何时完全完成执行?

当数据可用时,将调用完成处理程序(您已经在使用)
readTodayHealthData()
将在这之前返回

您需要在完成处理程序的范围内使用数据。例如,您可以像这样重写函数:

func updateLabel() {
        var stepCount: Int = 0
        func getStepsHealthData() {
        let stepsUnit = HKUnit.countUnit()
        let sumOption = HKStatisticsOptions.CumulativeSum
        let stepsHealthDataQuery = HKStatisticsQuery(quantityType: stepsHealth, quantitySamplePredicate: predicate, options: sumOption) {
            query, results, error in
            if let sumQuantity = results?.sumQuantity() {
                dispatch_async(dispatch_get_main_queue(), {
                    stepCount = sumQuantity.doubleValueForUnit(stepsUnit) * 2
                    self.myLabel.text = "\(stepCount)"
                })
            }
        }
        healthKitStore?.executeQuery(stepsHealthDataQuery)
    }
}

这将在返回数据时更新标签。

您实际上并不是在检查函数是否已完成执行。传递给HKStatisticsQuery的块实际上不是原始函数的一部分。如果您真的想阻止
myLabel.text=
行在调用块之前执行,您可以使用,但这是解决实际问题的糟糕方法。为什么不让传递给香港的区块直接更新标签

dispatch_async(dispatch_get_main_queue(), {
                    stepCount = sumQuantity.doubleValueForUnit(stepsUnit) * 2
                    myLabel.text = "\(stepCount)"
                })

问题是,您正在使用的操作是异步的,那么您需要正确处理,这里有两个选项:

  • 更新主线程中函数
    getStepsHealthData
    内的
    completionHandler
    中的
    UILabel
    ,因为您要更新UI,如下所示:

    func getStepsHealthData() {
         var stepCount: Int = 0
         let stepsUnit = HKUnit.countUnit()
         let sumOption = HKStatisticsOptions.CumulativeSum
    
         let stepsHealthDataQuery = HKStatisticsQuery(quantityType: stepsHealth, quantitySamplePredicate: predicate, options: sumOption) {
            query, results, error in
              if let sumQuantity = results?.sumQuantity() {
                 dispatch_async(dispatch_get_main_queue(), {
                   stepCount = sumQuantity.doubleValueForUnit(stepsUnit) * 2
    
                   //Set UILabel Value
                   myLabel.text = String(stepCount)
                 })
              }
         }
         healthKitStore?.executeQuery(stepsHealthDataQuery)
    }
    
    你不需要归还任何东西

  • 如果要从函数返回步数,则需要使用闭包并按以下方式修改函数:

    func getStepsHealthData(completion: (steps: Int) -> ()) {
         var stepCount: Int = 0
         let stepsUnit = HKUnit.countUnit()
         let sumOption = HKStatisticsOptions.CumulativeSum
    
         let stepsHealthDataQuery = HKStatisticsQuery(quantityType: stepsHealth, quantitySamplePredicate: predicate, options: sumOption) {
            query, results, error in
              if let sumQuantity = results?.sumQuantity() {
                  stepCount = sumQuantity.doubleValueForUnit(stepsUnit) * 2
                  completion(stepCount)
              }
         }
         healthKitStore?.executeQuery(stepsHealthDataQuery)
    }
    
    然后你可以从外面这样称呼它:

    self.getStepsHealthData() { (steps) -> Void in
       dispatch_async(dispatch_get_main_queue(), {
           //Set UILabel Value
           myLabel.text = String(stepCount)
       })
    }
    

  • 我希望这对您有所帮助。

    好的,让我更新我的问题标签不在函数的范围内。好的,让我更新我的问题标签不在函数的范围内。无论标签的范围如何,您都需要了解块的概念,以及为什么您的函数在未设置
    stepCount
    的情况下返回。阅读本手册,您将确切了解发生这种情况的原因以及解决方法。
    self.getStepsHealthData() { (steps) -> Void in
       dispatch_async(dispatch_get_main_queue(), {
           //Set UILabel Value
           myLabel.text = String(stepCount)
       })
    }