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)!
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
self.handleStepResults(query, samples: samples, deletedObjects: deletedObjects, anchor: anchor, error: error)
}
query.updateHandler = { (query, samples, deletedObjects, anchor, error) -> Void in
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
self.timelineModel.pastEntries.append(self.timelineModel.currentEntry)
for result in newStepSamples {
stepCount += result.quantity.doubleValueForUnit(self.countUnit)
currentDate = result.endDate
self.timelineModel.pastEntries.append(TimelineEntryModel(value: NSNumber(double: stepCount), endDate: currentDate))
}
self.timelineModel.currentEntry = self.timelineModel.pastEntries.popLast()
if self.timelineModel.currentEntry == nil {
self.timelineModel.currentEntry = TimelineEntryModel(value: NSNumber(int: -3), endDate: NSDate())
}
}
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?