HKAnchoredObjectQuery not returning reliably in ba

2019-09-08 05:48发布

I'm trying to make my app synchronize HealthKit data with our database whenever new data input is observed. Despite some ambiguity in the logic I believe I've managed to enable background delivery for the sample types and have the observers react when needed.

However, in the observer's updatehandler I need to create an HKAnchoredObjectQuery for fetching the most recent results from HealthKit, but these queries don't return reliably when my app is running in the background. Often when I add sample points in HealthKit, the anchored queries just get executed, but they return only when I bring the app back in the foreground.

Other times they return immediately without me having to activate the app. One possible issue is that all of my observer queries fire their updatehandlers, thus creating multiple AnchoredObjectQueries that may or may not return. I've explained that further in the linked thread, because it may be unrelated.

Here's an example of the function I'm calling from HKObserverQuery's updatehandler:

func synchronizeRecentData(sampleType: HKSampleType, observerQuery: HKObserverQuery) {

    let completionHandler: (HKAnchoredObjectQuery, [HKSample]?, Int, NSError?) -> Void = {
        [unowned self] query, results, newAnchor, error in

        if error != nil {
            abort()
        }

        // Update queryAnchor
        self.queryAnchors[sampleType] = newAnchor

        guard let receivedNewSamples = results as? [HKQuantitySample] else {
            abort()
        }

        // Handle received samples here
    }

    let query = HKAnchoredObjectQuery(type: sampleType,
                                      predicate: nil,
                                      anchor: self.queryAnchors[sampleType]!,
                                      limit: HKObjectQueryNoLimit,
                                      completionHandler: completionHandler)
    healthKitStore.executeQuery(query)
}

2条回答
我想做一个坏孩纸
2楼-- · 2019-09-08 06:19

I believe this is because when your app gets woken up in the background you have very limited time to execute before the app gets suspended again. If you use UIBackgroundTaskIdentifier you should be able to ensure that your app runs long enough to finish getting the results of the HKAnchoredObjectQuery.

查看更多
我想做一个坏孩纸
3楼-- · 2019-09-08 06:28

According to the HealthKit docs:

Unlike the observer query, these updates include a list of items that have been added or removed; however, anchored object queries cannot be registered for background delivery. For more information, see HKAnchoredObjectQuery.

The only query that can register for background delivery is the HKObserverQuery

查看更多
登录 后发表回答