title: HKStatisticsCollectionQuery resultsHandler and NSOperation
body: <p>In my project I am creating HKStatisticsCollectionQueries for a series of HKQuantityTypes. The resultsHandler then adds this data to an date-ordered array of objects. I want to do another operation only when the entire series of HKStatisticsCollectionQueries have been processed and the results appended to my array.</p>
  
  <p>I have tried to do this by putting the task inside of a subclass of  NSOperation, but the dependent block is fired before any of the samples are added to the array. According to the HKStatisticsCollectionQuery documentation "This method runs the query on an anonymous background queue. When the query is complete, it executes the results handler on the same background queue"</p>
  
  <p><em>Is there a way to use HKStatisticsCollectionQuery's initialResultsHandler and statisticsUpdateHandler with NSOperation?</em></p>
  
  <p>when I run this I get the following output:</p>
  
  <p>cycleOperation start<br>
  cycleOperation CompletionBlock<br>
  dependentOperation start<br>
  dependentOperation CompletionBlock<br>
  SumStatistics addSamplesToArray: cycle:  96 samples added<br>
  SumStatistics main complete: 96 samples added  </p>
  
  <pre><code>func getCycleKm(){
      let sampleType = HKSampleType.quantityTypeForIdentifier(HKQuantityTypeIdentifierDistanceCycling)
      let hkUnit = HKUnit.meterUnitWithMetricPrefix(.Kilo)
      println("cycleOperation start")
  
      let cycleOperation = SumStatistics(quantityType: sampleType, startDate: startingDate, heathDataArray: self.healthDataArray)
      cycleOperation.completionBlock = {println("cycleOperation CompletionBlock ")}
      let dependentOperation = NSBlockOperation{()-&gt;Void in println("dependentOperation start")}
      dependentOperation.completionBlock = {println("dependentOperation CompletionBlock")}
      dependentOperation.addDependency(cycleOperation)
  
      self.operationQueue.addOperation(cycleOperation)
      self.operationQueue.addOperation(dependentOperation)
  }
  
  
  class SumStatistics:NSOperation{
  
  let healthKitStore:HKHealthStore = HKHealthStore()
  
  private let quantityType:HKQuantityType
  private let startDate:NSDate
  private let endDate: NSDate
  private let statsOption: HKStatisticsOptions
  
  var healthDataArray:[HealthData]
  
  required init(quantityType:HKQuantityType, startDate:NSDate, heathDataArray:[HealthData]){
      self.quantityType = quantityType
      self.startDate = startDate
      let startOfToday = NSDate().getStartOfDate()
      self.endDate = NSCalendar.currentCalendar().dateByAddingUnit(.CalendarUnitDay, value: 1, toDate: startOfToday, options: nil)!
      self.statsOption = HKStatisticsOptions.CumulativeSum
      self.healthDataArray = heathDataArray
      super.init()
  }
  
  
  override func main() {
      getSumStatistics { (hkSamples, statsError) -&gt; Void in
          self.addSamplesToArray(hkSamples)
          println("SumStatistics main complete: \(hkSamples.count) samples added")
      }
  }
  
  func addSamplesToArray(newSamples:[HKQuantitySample]){
      var samples = newSamples
      samples.sort({$0.startDate.timeIntervalSinceNow &gt; $1.startDate.timeIntervalSinceNow})
      if samples.count == 0{
          println("SumStatistics addSamplesToArray: no samples!")
          return
      }
      var ctr = 0
      var typeString = ""
      for healthDataDate in self.healthDataArray{
  
          while healthDataDate.date.isSameDate(samples[ctr].startDate) &amp;&amp; ctr &lt; samples.count - 1{
              switch samples[ctr].quantityType.identifier {
              case HKQuantityTypeIdentifierBodyMass:
                  healthDataDate.weight = samples[ctr].quantity
                  typeString = "weight"
              case HKQuantityTypeIdentifierDietaryEnergyConsumed:
                  healthDataDate.dietCalories = samples[ctr].quantity
                  typeString = "diet"
              case HKQuantityTypeIdentifierActiveEnergyBurned:
                  healthDataDate.activeCalories = samples[ctr].quantity
                  typeString = "active"
              case HKQuantityTypeIdentifierBasalEnergyBurned:
                  healthDataDate.basalCalories = samples[ctr].quantity
                  typeString = "basal"
              case HKQuantityTypeIdentifierStepCount:
                  healthDataDate.steps = samples[ctr].quantity
                  typeString = "steps"
              case HKQuantityTypeIdentifierDistanceCycling:
                  healthDataDate.cycleKM = samples[ctr].quantity
                  typeString = "cycle"
              case HKQuantityTypeIdentifierDistanceWalkingRunning:
                  healthDataDate.runWalkKM = samples[ctr].quantity
                  typeString = "runWalk"
              default:
                  println("SumStatistics addSamplesToArray type not found -&gt; \(samples[ctr].quantityType)")
              }
              if ctr &lt; samples.count - 1{
                  ctr += 1
              }else{
                  break
              }
          }
      }
      println("SumStatistics addSamplesToArray: \(typeString):  \(newSamples.count) samples added")
  }
  
  
  
  
  func getSumStatistics(completionHandler:([HKQuantitySample], NSError!)-&gt;Void){
      let dayStart = NSCalendar.currentCalendar().startOfDayForDate(startDate)
      let addDay = NSCalendar.currentCalendar().dateByAddingUnit(.CalendarUnitDay, value: 1, toDate: endDate, options:nil)
      let dayEnd = NSCalendar.currentCalendar().startOfDayForDate(addDay!)  //add one day
      let interval = NSDateComponents()
      interval.day = 1
  
      let predicate = HKQuery.predicateForSamplesWithStartDate(startDate, endDate: endDate, options: HKQueryOptions.None)
      let newQuery = HKStatisticsCollectionQuery(quantityType: quantityType,
          quantitySamplePredicate: predicate,
          options: statsOption,
          anchorDate: dayStart,
          intervalComponents: interval)
  
      newQuery.initialResultsHandler = {
          query, statisticsCollection, error in
          var resultsArray = [HKQuantitySample]()
          if error != nil {
              println("*** An error occurred while calculating the statistics: \(error.localizedDescription) ***")
          }else{
              statisticsCollection.enumerateStatisticsFromDate(self.startDate, toDate: self.endDate, withBlock: { (statistics, stop) -&gt; Void in
                  if let statisticsQuantity = statistics.sumQuantity() {
                      let startD =    NSCalendar.currentCalendar().startOfDayForDate(statistics.startDate)
                      let endD = NSCalendar.currentCalendar().dateByAddingUnit(.CalendarUnitDay, value: 1, toDate: startD, options: nil)
  
                      let qSample = HKQuantitySample(type: self.quantityType, quantity: statisticsQuantity, startDate: startD, endDate: endD)
                      resultsArray.append(qSample)
                  }
              })
          }
          completionHandler(resultsArray,error)
      }
  
      newQuery.statisticsUpdateHandler = {
          query, statistics, statisticsCollection, error in
          println("*** updateHandler fired")
          var resultsArray = [HKQuantitySample]()
          if error != nil {
              println("*** An error occurred while calculating the statistics: \(error.localizedDescription) ***")
          }else{
              statisticsCollection.enumerateStatisticsFromDate(self.startDate, toDate: self.endDate, withBlock: { (statistics, stop) -&gt; Void in
                  if let statisticsQuantity = statistics.sumQuantity() {
                      let startD =    NSCalendar.currentCalendar().startOfDayForDate(statistics.startDate)
                      let endD = NSCalendar.currentCalendar().dateByAddingUnit(.CalendarUnitDay, value: 1, toDate: startD, options: nil)
  
                      let qSample = HKQuantitySample(type: self.quantityType, quantity: statisticsQuantity, startDate: startD, endDate: endD)
                      resultsArray.append(qSample)
                  }
              })
          }
          completionHandler(resultsArray,error)
      }
      self.healthKitStore.executeQuery(newQuery)
  }
  </code></pre>
  
  <p>}</p>