steve1951
steve1951

Reputation: 193

HKSampleQuery cannot be reused

  1. Create an HKSampleQuery for weight (but don't execute it)
  2. Create and execute an HKObserverQuery on weight
  3. In the observer query's updateHandler, execute the weight sample query

Works fine the first time the sample query is executed.

Next time the sample query is executed, I get an exception: "...'NSInvalidArgumentException', reason: 'You cannot start a query that is already active'"

If a new sample query is created every time in the observer update handler, then executed, it works fine.

Seems like I should be able to re-use the first instance of the sample query; nothing is documented to the contrary.

class HealthDemoC {
    let store = HKHealthStore()
    let wtType = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierBodyMass)!
    var wtObserverQ: HKObserverQuery! = nil
    var wtSampleQ: HKSampleQuery! = nil

    init() {
        print("init: HealthDemoC")

        // !! only instantiating the query here and then executing repeatedly in observerUpdateHandler fails
        wtSampleQ = HKSampleQuery(sampleType: wtType, predicate: nil, limit: 0, sortDescriptors: nil, resultsHandler: wtResultsHandler)

        wtObserverQ = HKObserverQuery(sampleType: wtType as HKSampleType, predicate: nil, updateHandler: observerUpdateHandler)
        store.executeQuery(wtObserverQ)
    }

    func observerUpdateHandler (query: HKObserverQuery,
        completion: HKObserverQueryCompletionHandler,
        error: NSError?) {
            print("clbk: observerUpdateHandler")

            // instantianting a new query with each call to observerUpdateHandler works
            // wtSampleQ = HKSampleQuery(sampleType: wtType, predicate: nil, limit: 0, sortDescriptors: nil, resultsHandler: wtResultsHandler)

            store.executeQuery(wtSampleQ)
            completion()
    }

    func wtResultsHandler(query: HKSampleQuery, results: [HKSample]?, error: NSError?) {
        print("clbk: wtResultsHandler - \(results!.count)) results")

        // stopping the query doesn't prevent the exception
        // store.stopQuery(query)
    }
}

Upvotes: 3

Views: 638

Answers (1)

Allan
Allan

Reputation: 7353

Although it is not in the official documentation, the exception is itself a form of documentation that explicitly tells you what that the intended behavior is. You should re-instantiate the query with the same parameters in the completion for the observer query when you need to run it again.

Upvotes: 3

Related Questions