为啥我的 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 设备上的开发服务器获取更改?

如何从 Apple Watch 中的手表扩展发送短信

为啥编译我的 XCode 项目可以使用 Apple-(B)uild 并且无法使用 Apple-(U)nit 测试编译?

为啥我的 iPhone 应用程序被列为 iPad 兼容?

为啥通过 Apple Watch 向 iPhone 发送消息时 print() 不起作用?