ios - 在快速完成所有后台进程后执行功能

标签 ios swift xcode multithreading background-process

我正在快速使用 GCD 像这样:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {

    //all background task

    dispatch_async(dispatch_get_main_queue()) {  
        self.second()
    }
}

在这段代码中,第二个函数在完成所有后台任务之前被调用,这就是为什么我无法获取我在第二个函数中使用的一些数据的原因。我想在完成所有后台任务后使用第二种方法。谁能告诉我如何完成这项任务?

***************在后台我正在获取 healthkit 数据,比如******

let healthKitTypesToRead = 
Set(
        arrayLiteral: HKObjectType.characteristicTypeForIdentifier(HKCharacteristicTypeIdentifierDateOfBirth)!,
        HKObjectType.characteristicTypeForIdentifier(HKCharacteristicTypeIdentifierBiologicalSex)!,
        HKObjectType.workoutType()
        )

let newCompletion: ((Bool, NSError?) -> Void) = {
        (success, error) -> Void in

        if !success {
            print("You didn't allow HealthKit to access these write data types.\nThe error was:\n \(error!.description).")

            return
        }
        else
      {
       let stepCount = HKSampleType.quantityTypeForIdentifier(HKQuantityTypeIdentifierStepCount)

                    // Our search predicate which will fetch data from now until a day ago
                    // (Note, 1.day comes from an extension
                    // You'll want to change that to your own NSDate

                    //let date = NSDate()
                    //let predicate = HKQuery.predicateForSamplesWithStartDate(date, endDate: NSDate(), options: .None)

                    // The actual HealthKit Query which will fetch all of the steps and sub them up for us.
                    let stepCountQuery = HKSampleQuery(sampleType: stepCount!, predicate:.None, limit: 0, sortDescriptors: nil) { query, results, error in
                        var steps: Double = 0

                        if results?.count > 0
                        {
                            for result in results as! [HKQuantitySample]
                            {
                                steps += result.quantity.doubleValueForUnit(HKUnit.countUnit())
                            }
                            testClass.HK_stepCount = String(steps)
                        }

                        //completion(steps, error)
                    }

                    self.healthKitStore.executeQuery(stepCountQuery)
             //EDIT.....
          let tHeartRate = HKSampleType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeartRate)
            let tHeartRateQuery = HKSampleQuery(sampleType: tHeartRate!, predicate:.None, limit: 0, sortDescriptors: nil) { query, results, error in
                if results?.count > 0
                {
                    var string:String = ""
                    for result in results as! [HKQuantitySample]
                    {
                        let HeartRate = result.quantity
                        string = "\(HeartRate)"
                        print(string)
                    }
                    testClass.HK_HeartRate = string
                      finalCompletion(Success: true)

                }

            }
                 self.healthKitStore.executeQuery(tHeartRateQuery)
      }

    }


healthKitStore.requestAuthorizationToShareTypes(healthKitTypesToWrite, readTypes: healthKitTypesToRead, completion: newCompletion)

我无法获取步数的值,它在调用第二个(方法)后执行,请建议我该怎么做?

最佳答案

您可以创建一个单独的函数来在其他线程上执行您的任务

func someFunction(finalCompletion: (Success: Bool)->()) {
let healthKitTypesToRead = 
Set(
        arrayLiteral: HKObjectType.characteristicTypeForIdentifier(HKCharacteristicTypeIdentifierDateOfBirth)!,
        HKObjectType.characteristicTypeForIdentifier(HKCharacteristicTypeIdentifierBiologicalSex)!,
        HKObjectType.workoutType()
        )

let newCompletion: ((Bool, NSError?) -> Void) = {
        (success, error) -> Void in

        if !success {
            print("You didn't allow HealthKit to access these write data types.\nThe error was:\n \(error!.description).")

            return
        }
        else
      {
       let stepCount = HKSampleType.quantityTypeForIdentifier(HKQuantityTypeIdentifierStepCount)

                    // Our search predicate which will fetch data from now until a day ago
                    // (Note, 1.day comes from an extension
                    // You'll want to change that to your own NSDate

                    //let date = NSDate()
                    //let predicate = HKQuery.predicateForSamplesWithStartDate(date, endDate: NSDate(), options: .None)

                    // The actual HealthKit Query which will fetch all of the steps and sub them up for us.
                    let stepCountQuery = HKSampleQuery(sampleType: stepCount!, predicate:.None, limit: 0, sortDescriptors: nil) { query, results, error in
                        var steps: Double = 0

                        if results?.count > 0
                        {

                           // Edit--  
                            for result in results as! [HKQuantitySample]
                            {
                                steps += result.quantity.doubleValueForUnit(HKUnit.countUnit())
                             //   heartBeat += ....
                            }
                            testClass.HK_stepCount = String(steps)
                            finalCompletion(Success: true)

                        }

                        //completion(steps, error)
                    }

                    self.healthKitStore.executeQuery(stepCountQuery)
      }

    }


healthKitStore.requestAuthorizationToShareTypes(healthKitTypesToWrite, readTypes: healthKitTypesToRead, completion: newCompletion)
}

另一个功能?

我会稍后编辑这个答案,告诉你一个更好的技术来处理异步请求。通常,您应该为此类后台任务创建一个单独的单例类。 (RESTful API 服务类..但现在您可以使用以下方法)

func getHeartBeatInfo(finalCompletionHeart: (Success: Bool)->()) {

 let tHeartRate = HKSampleType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeartRate)
        let tHeartRateQuery = HKSampleQuery(sampleType: tHeartRate!, predicate:.None, limit: 0, sortDescriptors: nil) { query, results, error in
            if results?.count > 0
            {
                var string:String = ""
                for result in results as! [HKQuantitySample]
                {
                    let HeartRate = result.quantity

                    string = "\(HeartRate)"
                    print(string)
                }
                testClass.HK_HeartRate = string
                  finalCompletionHeart(Success: true)

            }

        }
             self.healthKitStore.executeQuery(tHeartRateQuery)
   }

然后你可以像这样调用这个方法:

override func viewDidLoad() {

      someFunction( { (finalCompletion) in

         if finalCompletion == true {

            getHeartBeatInfo( { finalCompletionHeart in

                if finalCompletionHeart == true {

                      self.second()
                }

            })
         }
      })
}

关于ios - 在快速完成所有后台进程后执行功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38325389/

相关文章:

c++ - 在 objective-c ++ 文件中包含 c++ 库时的级联 objective-c 语法错误

iphone - 更改设备时 iOS 模拟器无法正确运行应用程序

iOS bundle 显示名称 - en-GB 和 en-US

全国 iOS 离线 map (OSM)

ios - 如何在 Swift 中为 View 集合中的每个单元格添加弹出窗口

ios - 如何让 MFMailComposeViewController 不显示状态栏?

ios - 我可以为 iOS 应用程序和网站使用一个解析数据库吗? - 使用 swift

iOS 无法在谷歌上使用 Books API

ios - Facebook FBSDKLoginManager/logInWithReadPermissions Swift 示例不使用 Parse

ios - 无法将 Firebase 连接到我的 Xcode swift 应用程序?