KML
KML

Reputation: 2322

Return values from function is empty: Why?

In QueryHK class I run a HealthKit query for steps and corresponding date.  I would like to write those data to an NSArray and return it so that I can call the function in the ViewController.

It seems to me that the query does not "write to the return".

QueryHK.swift:

import UIKit
import HealthKit

class QueryHK: NSObject {

var steps = Double()
var date = NSDate()

func performHKQuery () -> (steps: Double, date: NSDate){

    let healthKitManager = HealthKitManager.sharedInstance
    let stepsSample = HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierStepCount)
    let stepsUnit = HKUnit.countUnit()
    let sampleQuery = HKSampleQuery(
        sampleType: stepsSample,
        predicate: nil,
        limit: 0,
        sortDescriptors: nil)
        {
            (sampleQuery, samples, error) in

            for sample in samples as [HKQuantitySample]
            {

                self.steps  = sample.quantity.doubleValueForUnit(stepsUnit)
                self.date  = sample.startDate

                println("Query HealthKit steps: \(self.steps)")
                println("Query HealthKit date: \(self.date)")

            }
    }
    healthKitManager.healthStore.executeQuery(sampleQuery)
    return (steps, date)
}
}

ViewController.swift:

import UIKit

class ViewController: UIViewController {

    var query = QueryHK()

    override func viewDidLoad() {
        super.viewDidLoad()

        printStepsAndDate()
    }


    func printStepsAndDate() {

    println(query.performHKQuery().date)
    println(query.performHKQuery().steps)

    }
}

Upvotes: 1

Views: 652

Answers (1)

Jernej Strasner
Jernej Strasner

Reputation: 4620

The reason is that HKSampleQuery is processed asynchronously - it returns right away and does it's work in the background. So your method finishes executing right away instead of handling the response in the results handler block. You would need to update your method to take a completion block instead of returning values.

QueryHK.swift:

import UIKit
import HealthKit

struct Sample {
    let step: Double
    let date: NSDate
}

class QueryHK: NSObject {

func performHKQuery(completion: (samples: [Sample]) -> Void) {

    let healthKitManager = HealthKitManager.sharedInstance
    let stepsSample = HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierStepCount)
    let stepsUnit = HKUnit.countUnit()
    let sampleQuery = HKSampleQuery(
        sampleType: stepsSample,
        predicate: nil,
        limit: 0,
        sortDescriptors: nil)
        {
            (sampleQuery, samples, error) in

            var processedSamples = [Sample]()
            for sample in samples as [HKQuantitySample]
            {
                processedSamples.append(Sample(step: sample.quantity.doubleValueForUnit(stepsUnit), date: sample.startDate))

                println("Query HealthKit steps: \(processedSamples.last?.step)")
                println("Query HealthKit date: \(processedSamples.last?.date)")
            }
            // Call the completion handler with the results here
            completion(samples: processedSamples)
    }
    healthKitManager.healthStore.executeQuery(sampleQuery)
}
}

ViewController.swift:

import UIKit

class ViewController: UIViewController {

    var query = QueryHK()

    override func viewDidLoad() {
        super.viewDidLoad()

        printStepsAndDate()
    }


    func printStepsAndDate() {
        query.performHKQuery() { steps in
            println(steps)
        }
    }
}

Upvotes: 1

Related Questions