How can you display HealthKit data about complications that are updated in the background?

I am trying to create watchOS 2 complexity that displays user health data, such as steps (but theoretically it should be able to display any health information provided to the user to view the application). When the first running complication, I can query Healthkit and get all the necessary data, because the first run is considered to be in the foreground. However, I am having problems retrieving HealthKit data in the background when new health data is available. There are two places where I could get this data, a watch and an iPhone.

I tried to get the data from the watch itself when the complication background update starts from the date set to getNextRequestedUpdateDateWithHandler . However, when I call the HKHealthStore execution method, it does not return the query results if the application (or in this case complication) works with the background. I also tried to set up an HKAnchoredObject request, which should immediately return my results when the process resumes, but it also does not seem to return any results if I did not manually launch the application extension on the clock. Here is my clock code, called from my ExtensionDelegate initialization method after health set permissions were requested:

func setupComplicationDataCache() {
    let now = NSDate()
    var startDate: NSDate? = nil
    var interval: NSTimeInterval = 0

    self.calendar.rangeOfUnit(NSCalendarUnit.Day, startDate: &startDate, interval: &interval, forDate: now)
    let stepSampleType = HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierStepCount)!

    // Match samples with a start date after the workout start
    let predicate = HKQuery.predicateForSamplesWithStartDate(startDate, endDate: nil, options: .None)
    let query = HKAnchoredObjectQuery(type: stepSampleType, predicate: predicate, anchor: nil, limit: 0) { (query, samples, deletedObjects, anchor, error) -> Void in
        // Handle when the query first returns results
        self.handleStepResults(query, samples: samples, deletedObjects: deletedObjects, anchor: anchor, error: error)
    }

    query.updateHandler = { (query, samples, deletedObjects, anchor, error) -> Void in
        // Handle update notifications after the query has initially run
        self.handleStepResults(query, samples: samples, deletedObjects: deletedObjects, anchor: anchor, error: error)
    }

    self.healthStore.executeQuery(query);
}

func handleStepResults(query: HKAnchoredObjectQuery, samples: [HKSample]?, deletedObjects: [HKDeletedObject]?, anchor: HKQueryAnchor?, error: NSError?) {
    if error != nil {
        self.timelineModel.currentEntry = TimelineEntryModel(value: NSNumber(int: -1), endDate: NSDate())
    } else if samples == nil || samples?.count == 0 {
        self.timelineModel.currentEntry = TimelineEntryModel(value: NSNumber(int: 0), endDate: NSDate())
    } else {
        let newStepSamples = samples as! [HKQuantitySample]
        var stepCount = self.timelineModel.currentEntry.value.doubleValue
        var currentDate = self.timelineModel.currentEntry.endDate

        // Add the current entry to the collection of past entries
        self.timelineModel.pastEntries.append(self.timelineModel.currentEntry)

        // Add all new entries to the collection of past entries
        for result in newStepSamples {
            stepCount += result.quantity.doubleValueForUnit(self.countUnit)
            currentDate = result.endDate
            self.timelineModel.pastEntries.append(TimelineEntryModel(value: NSNumber(double: stepCount), endDate: currentDate))
        }

        // Retrieve the latest sample as the current item
        self.timelineModel.currentEntry = self.timelineModel.pastEntries.popLast()
        if self.timelineModel.currentEntry == nil {
            self.timelineModel.currentEntry = TimelineEntryModel(value: NSNumber(int: -3), endDate: NSDate())
        }
    }

    // Reload the complication
    let complicationServer = CLKComplicationServer.sharedInstance()
    for complication in complicationServer.activeComplications {
        complicationServer.reloadTimelineForComplication(complication)
    }
}

iPhone HKObserverQuery. , iPhone ( ). , iPhone , , HKHealthStore . , , , , , Apple docs , Health Store , ( ). , - , , .

- , HealthKit , , iOS, watchOS 2?

+4
1

, . watchOS 2 Apple, , HealthKit , . , Watch Connectivity . iPhone HealthKit , , . , , . , . , - , , iPhone ( ).

, , healthkit, , + , , (CMPedometer), .

, iPhone, , , .

+7

Source: https://habr.com/ru/post/1623098/


All Articles