在swift中完成所有后台进程后执行一个函数

时间:2016-07-12 09:49:11

标签: ios swift xcode multithreading background-process

我在swift中使用GCD 像这样:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {

    //all background task

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

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

***************在后台我正在使用像******这样的健康套件数据

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)

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

1 个答案:

答案 0 :(得分:1)

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

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

            })
         }
      })
}