Sagar Snehi Sagar Snehi - 4 months ago 11
Swift Question

Execute a function after completing all background process in swift

I am using GCD in swift
like this :

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {

//all background task

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


In this code second function is getting called before completing all background task that's why I am not able to take some data which I am using in second function. I want to second method after completing all background task. Can anyone tell me how to achieve this task?

***************In background I am taking healthkit data like******

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

}


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





I am not able to take value of step count, It get executed after calling second(method) called, plz suggest me what to do?

Answer

You can create a separate function to execute your task on other thread

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

And then you can call this method like so:

override func viewDidLoad() {

      someFunction( { (finalCompletion) in

         if finalCompletion == true {
         self.second()
         }

      })

}