Saving HealthKit Data & Closures

iOS 8 HealthKit Santiapps Marcio Valenzuela
iOS 8 HealthKit

This code bit saves:

  healthKitStore.saveObject(bmiSample, withCompletion: { (success, error) -> Void in
    if( error != nil ) {
      println("Error saving BMI sample: \(error.localizedDescription)")
    } else {
      println("BMI sample saved successfully!")
    }
  })

The method signature is:

saveObject(object: HKObject!, withCompletion completion: ((Bool, NSError!) -> Void)!)

This method takes an HKObject which is bmiSample

and it takes a completion closure which itself takes a bool & error and returns void.

So in our method call, we pass in the bmiSample as the HKObject and for the success and error completion block we say:

if error is NOT nil then log that error’s description,

else log that the bmiSample was saved successfully.

 

 

This code bit reads:

// 2. Call the method to read the most recent weight sample
self.healthManager?.readMostRecentSample(sampleType, completion: { (mostRecentWeight, error) -> Void in
 
  if( error != nil )
  {
    println("Error reading weight from HealthKit Store: \(error.localizedDescription)")
    return;
  }
 
  var weightLocalizedString = self.kUnknownString;
  // 3. Format the weight to display it on the screen
  self.weight = mostRecentWeight as? HKQuantitySample;
  if let kilograms = self.weight?.quantity.doubleValueForUnit(HKUnit.gramUnitWithMetricPrefix(.Kilo)) {
    let weightFormatter = NSMassFormatter()
    weightFormatter.forPersonMassUse = true;
    weightLocalizedString = weightFormatter.stringFromKilograms(kilograms)
  }
 
  // 4. Update UI in the main thread
  dispatch_async(dispatch_get_main_queue(), { () -> Void in
    self.weightLabel.text = weightLocalizedString
    self.updateBMI()
 
  });
});

Here we are calling the .readMostRecentSample method which has this signature:

func readMostRecentSample(sampleType:HKSampleType , completion: ((HKSample!, NSError!) -> Void)!)

This method takes an HKSampleType which is sampleType

and it takes a completion closure which itself takes an HKSample & error and returns void.

So in our method call, we pass in the sampleType as the HKSample and for the success and error completion block we say:

if error is NOT nil then log that error’s description,

else get that mostRecentWeight as self.weight, format it and set it as the label’s text.

How does this method get the actual value from the HKHealthStore?  Inside itself, it executes an HKQuery which itself says this:

let sampleQuery = HKSampleQuery(sampleType: sampleType, predicate: mostRecentPredicate, limit: limit, sortDescriptors: [sortDescriptor])
    { (sampleQuery, results, error ) -> Void in
 
      if let queryError = error {
        completion(nil,error)
        return;
      }
 
      // Get the first sample
      let mostRecentSample = results.first as? HKQuantitySample
 
      // Execute the completion closure
      if completion != nil {
        completion(mostRecentSample,nil)
      }
  }
  // 5. Execute the Query
  self.healthKitStore.executeQuery(sampleQuery)

Give me:

a.  sampleType

b.  a predicate, limit, sortDescriptors

c. and a completion closure which takes a sampleQuery, results & error

such that;

if error it NOT nil, set the readMostRecentSample method’s completion closure to nil,error

otherwise set the completion closure with the results and no error.

Advertisements

One thought on “Saving HealthKit Data & Closures

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s