如何在后台刷新的并发症上显示 HealthKit 数据?
Posted
技术标签:
【中文标题】如何在后台刷新的并发症上显示 HealthKit 数据?【英文标题】:How can you display HealthKit data on a complication that is refreshed in the background? 【发布时间】:2016-01-06 13:54:09 【问题描述】:我正在尝试构建一个 watchOS 2 复杂功能来显示用户的健康数据,例如步数(但理论上它应该能够显示用户授予应用查看权限的任何健康数据)。当并发症首次启动时,我可以查询 Healthkit 并获取我想要的所有数据,因为第一次启动被认为是在前台。但是,当有新的健康数据可用时,我无法在后台检索 HealthKit 数据。我可以从两个地方获取这些数据,手表和 iPhone。
当复杂功能的后台刷新从getNextRequestedUpdateDateWithHandler 中设置的日期触发时,我尝试从手表本身获取数据。但是,当我调用 HKHealthStore 的 execute 方法时,如果应用程序(或者在本例中为并发症)正在后台运行,它不会返回任何查询结果。我还尝试设置一个 HKAnchoredObject 查询,该查询应在进程恢复时立即返回我的结果,但这似乎也不会返回任何结果,除非我在手表上手动启动应用程序扩展。这是我的手表代码,在请求健康包权限后从我的 ExtensionDelegate 的 init 方法调用:
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)
我还尝试使用 HKObserverQuery 从 iPhone 获取数据。我有一个可以每小时唤醒一次 iPhone 的观察者查询(步骤数据的最长时间)。但是,如果在观察者完成处理程序执行我的步骤查询时 iPhone 被锁定,HKHealthStore 的执行方法也拒绝返回任何查询结果。我认为这在这里是有道理的,并且可能没有办法解决这个问题,因为Apple's docs 提到当设备被锁定并且您无法从存储中读取(仅写入)时,Health Store 是加密的。但是在手表的情况下,当它戴在某人的手腕上时,它没有被锁定,屏幕只是关闭了。
有谁知道如何让 HealthKit 更新在后台发生刷新时显示在并发症上,无论是在 ios 还是在 watchOS 2 上?
【问题讨论】:
您在手表上进行复杂功能更新时尝试使用的速率是多少? 这似乎无关紧要。我尝试了 30 分钟和 1 小时,没有使用 HealthKit 查询,这两个都很好。 【参考方案1】:经过大量测试,我确定目前这是不可能的。在 watchOS 2 上,当扩展程序或复杂功能在后台运行时,Apple 似乎完全禁止 HealthKit 查询返回结果。这包括从远程通知、Watch Connectivity 以及从复杂计划刷新中执行。如果屏幕关闭并且设备设置了密码,则 iPhone 的 HealthKit 查询会失败。查询失败,因为在设备锁定时对健康数据存储进行了加密。即使启用了观察者查询和后台传递,查询也会失败。您可以收到更改的通知,但在 iPhone 解锁之前无法查询更改(因为数据再次被加密)。
通过直接查询计步器 (CMPedometer) 来显示 Healthkit 相关数据(例如步数和步行+跑步距离)的其他应用程序可以在这些后台模式下访问其数据。
对于没有在设备上设置密码的 iPhone 用户,可能会在后台专门进行更新,但这似乎是一个糟糕的推广想法。
【讨论】:
以上是关于如何在后台刷新的并发症上显示 HealthKit 数据?的主要内容,如果未能解决你的问题,请参考以下文章