title: Swift 4. Wait for async result of HealthKit HKQuery before continuing execution
body: <p>Problem is how to wait for an async query on HealthKit to return a result BEFORE allowing execution to move on. The returned data is critical for further execution.</p>
  
  <p>I know this has been asked/solved many times and I have read many of the posts, however I have tried completion handlers, Dispatch sync and Dispatch Groups and have not been able to come up with an implementation that works.</p>
  
  <p><strong>Using completion handler</strong>
  per <a href="https://stackoverflow.com/questions/42255446/wait-for-completion-handler-to-finish-swift">Wait for completion handler to finish - Swift</a></p>
  
  <p>This calls a method to run a HealthKit Query:</p>
  
  <pre><code>func readHK() {
  
      var block: Bool = false
  
      hk.findLastBloodGlucoseInHealthKit(completion: { (result) -&gt; Void in
          block = true
  
          if !(result) {
              print("Problem with HK data")
          }
  
          else {
              print ("Got HK data OK")
          }
  
      })
  
      while !(block) {
      }
  
      // now move on to the next thing ...
  
  }
  </code></pre>
  
  <p>This does work. Using "block" variable to hold execution pending the callback in concept seems not that different from blocking semaphores, but it's really ugly and asking for trouble if the completion doesn't return for whatever reason. Is there a better way?</p>
  
  <p><strong>Using Dispatch Groups</strong></p>
  
  <p>If I put Dispatch Group at the calling function level:</p>
  
  <p>Calling function:</p>
  
  <pre><code>func readHK() {
  
      var block: Bool = false
      dispatchGroup.enter()
  
      hk.findLastBloodGlucoseInHealthKit(dg: dispatchGroup)
      print ("Back from readHK")
  
      dispatchGroup.notify(queue: .main) {
          print("Function complete")
          block = true
      }
  
      while !(block){   
      }
  }
  </code></pre>
  
  <p>Receiving function:</p>
  
  <pre><code>func findLastBloodGlucoseInHealthKit(dg: DispatchGroup) {
  
          print ("Read last HK glucose")
  
          let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierEndDate, ascending: false)
          let query = HKSampleQuery(sampleType: glucoseQuantity!, predicate: nil, limit: 10, sortDescriptors: [sortDescriptor]) { (query, results, error) in
              // .... other stuff
              dg.leave()
  </code></pre>
  
  <p>The completion executes OK, but the .notify method is never called, so the block variable is never updated, program hangs and never exits from the while statement.</p>
  
  <p>Put Dispatch Group in target function but leave .notify at calling level:</p>
  
  <pre><code>func readHK() {
  
      var done: Bool = false
  
      hk.findLastBloodGlucoseInHealthKit()
      print ("Back from readHK")
  
      hk.dispatchGroup.notify(queue: .main) {
          print("done function")
          done = true
      }
  
      while !(done) {
      }
  
  }
  </code></pre>
  
  <p>Same issue.</p>
  
  <p><strong>Using Dispatch</strong></p>
  
  <p>Documentation and other S.O posts say: “If you want to wait for the block to complete use the sync() method instead.”</p>
  
  <p>But what does “complete” mean? It seems that it does not mean complete the function AND get the later async completion. For example, the below does not hold execution until the completion returns:</p>
  
  <pre><code>func readHK() {
  
      DispatchQueue.global(qos: .background).sync {
          hk.findLastBloodGlucoseInHealthKit()
      }
  
      print ("Back from readHK")
  
  }
  </code></pre>
  
  <p>Thank you for any help.</p>