为啥我的 iPhone 无法从 Apple Watch 获取心率数据,但手表扩展程序却可以?
Posted
技术标签:
【中文标题】为啥我的 iPhone 无法从 Apple Watch 获取心率数据,但手表扩展程序却可以?【英文标题】:Why can't my iPhone get heartRate data from an Apple Watch, but the watch extension can?为什么我的 iPhone 无法从 Apple Watch 获取心率数据,但手表扩展程序却可以? 【发布时间】:2016-09-28 06:32:37 【问题描述】:我可以通过watchkit
应用扩展中的锻炼会话和HKAnchoredObjectQuery
获取数据。而且我还想获取 heartRate 并在我的 iPhone 上显示数据。所以我使用HKSampleQuery
通过模拟器(手表和iPhone)获取。但是当我使用iPhone 和手表进行测试时。我的 iPhone 只能获得一次 heartRate。
//代码
override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
guard let sampleType = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeartRate) else return
// 1. Build the Predicate
let past = NSDate.distantPast() as NSDate
let now = NSDate()
let mostRecentPredicate = HKQuery.predicateForSamplesWithStartDate(past, endDate:now, options: .None)
// 2. Build the sort descriptor to return the samples in descending order
let sortDescriptor = NSSortDescriptor(key:HKSampleSortIdentifierStartDate, ascending: false)
// 3. we want to limit the number of samples returned by the query to just 1 (the most recent)
// 4. Build samples query
let sampleQuery = HKSampleQuery(sampleType: sampleType, predicate: mostRecentPredicate, limit: Int(HKObjectQueryNoLimit), sortDescriptors: [sortDescriptor])
(sampleQuery, HKSample, error ) -> Void in
// Get the samples
guard let heartRateSamples = HKSample as? [HKQuantitySample] else return
if(heartRateSamples.count > 0)
let count : Double = Double(heartRateSamples.count)
var sum = 0.0;
for quantitySample in heartRateSamples
let value = quantitySample.quantity.doubleValueForUnit(self.heartRateUnit);
sum += value;
let avg = sum/count;
self.HeartRateSum.text = String(sum)
self.Count.text = String(count)
self.SilentHeartRate.text = String(avg)
// 5. Execute the Query
self.healthStore.executeQuery(sampleQuery)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
sleep(15)
while(true)
self.getRecentHeartRate()
);
func getRecentHeartRate() ->Void
guard let sampleType = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeartRate) else return
let past = NSDate.distantPast() as NSDate
let now = NSDate()
let limit = 1
let mostRecentPredicate = HKQuery.predicateForSamplesWithStartDate(past, endDate:now, options: .None)
// 2. Build the sort descriptor to return the samples in descending order
let sortDescriptor = NSSortDescriptor(key:HKSampleSortIdentifierStartDate, ascending: false)
let sampleQuery = HKSampleQuery(sampleType: sampleType, predicate: mostRecentPredicate, limit: limit, sortDescriptors: [sortDescriptor])
(sampleQuery, HKSample, error ) -> Void in
// Get the samples
guard let heartRateSample = HKSample as? [HKQuantitySample] else return
guard let recentHeartRate = heartRateSample.first elsereturn
let value = recentHeartRate.quantity.doubleValueForUnit(self.heartRateUnit)
dispatch_async(dispatch_get_main_queue())
self.heartRate.text = String(UInt16(value))
self.healthStore.executeQuery(sampleQuery)
【问题讨论】:
【参考方案1】:你可以试试这个来获取心率
func readHeartRate()
let nowDate = NSDate()
let calendar = NSCalendar.autoupdatingCurrentCalendar()
let yearMonthDay: NSCalendarUnit = [NSCalendarUnit.Year, NSCalendarUnit.Month, NSCalendarUnit.Day]
let components: NSDateComponents = calendar.components(yearMonthDay , fromDate: nowDate)
let beginOfDay: NSDate = calendar.dateFromComponents(components)!
readHRbyDate(HKObjectQueryNoLimit, startDate: beginOfDay, endDate: nowDate) (hrData, error) in
print("heart Rate")
// print(hrData)
func readHRbyDate(latestXSamples: Int, startDate: NSDate, endDate: NSDate, completion: (((String, CGFloat), NSError!) -> Void)!)
let sampleType = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeartRate)
let predicate = HKQuery.predicateForSamplesWithStartDate(startDate, endDate: endDate, options: HKQueryOptions.None)
let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierStartDate, ascending: true)
var HRdata:(String,CGFloat) = ("N/A",0)
var bpm: Int = 0
var totalBPMforDay = [Int]()
var BPMCount: Int = 0
var sumBPM: Int = 0
let query = HKSampleQuery(sampleType: sampleType!, predicate: predicate, limit: latestXSamples, sortDescriptors: [sortDescriptor])
(query, results, error) in
if let queryError = error
print("Problem fetching HR data")
completion(("nil",0.0),queryError)
return
else
for result in results!
bpm = Int(((result.valueForKeyPath("_quantity._value"))?.floatValue)! * 60.0)
totalBPMforDay += [Int(((result.valueForKeyPath("_quantity._value"))?.floatValue)! * 60.0)]
BPMCount = Int(totalBPMforDay.count)
sumBPM += Int(((result.valueForKeyPath("_quantity._value"))?.floatValue)! * 60.0)
let HRAvg = sumBPM / BPMCount
//HRdata = (self.getDayOfWeek(result.startDate),CGFloat(HRAvg))
let dateFormatter = MyAPIClient.sharedClient.apiClientDateFormatter() // create your date formatter
HRdata = (dateFormatter.stringFromDate(result.startDate),CGFloat(HRAvg))
print(HRdata, bpm)
if completion != nil
completion(HRdata,nil)
executeQuery(query)
【讨论】:
非常感谢。我想更新最近的心脏以显示在 Iphone 上。收集heartRate的统计数据是稳定的。但我不知道为什么程序在模拟器上运行良好,但在 Iphone 上运行良好。 当然。当我进入程序时,我可以得到一次hearRate。我想在程序运行时更新用户的 heartRate 并显示数据。现在我在每次获取数据后测试我的代码 sleep(1) 。现在可以了。但它仍然不稳定。我认为原因是我的代码太糟糕了。有内存泄漏或其他问题。 我现在拿到数据了,但是速度太慢了,性能受不了了。所以我使用watch来获取健康数据并通过wcsession与ios通信。以上是关于为啥我的 iPhone 无法从 Apple Watch 获取心率数据,但手表扩展程序却可以?的主要内容,如果未能解决你的问题,请参考以下文章
如果 iPhone App 处于非活动状态,是不是可以响应通过 Apple Watch 传输的文件?
为啥 React Native 0.30 无法从 iPhone 设备上的开发服务器获取更改?