2016-02-23 4 views
0

Я пытаюсь просто отобразить последний записанный сердечный ритм от Apple Watch. Ниже то, что я пытаюсь, но results переменной в обработчике завершения работы updateHeartRate получить миллионы записей и убивает приложение (почти кажется, что коррумпированные данные или делать что-то неправильно):Как правильно получить частоту сердечных сокращений от WatchKit?

class InterfaceController: WKInterfaceController { 

    @IBOutlet var heartLabel: WKInterfaceLabel! 

    let heartRateUnit = HKUnit.countUnit().unitDividedByUnit(HKUnit.minuteUnit()) 
    let heartRateQuantityType = HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeartRate) 

    override func awakeWithContext(context: AnyObject?) { 
     super.awakeWithContext(context) 
    } 

    override func willActivate() { 
     super.willActivate() 

     guard HKHealthStore.isHealthDataAvailable() else { 
      heartLabel.setText("Not available") 
      return 
     } 

     requestHealthKitAuthorization() 
     queryHeartRateSample() 
    } 

    @IBAction func workoutMenuTapped() { 

    } 
} 

private extension InterfaceController { 

    func requestHealthKitAuthorization() { 
     guard let heartRateQuantityType = heartRateQuantityType else { 
      displayNotAllowed() 
      return 
     } 

     let dataTypes = Set(arrayLiteral: heartRateQuantityType) 

     HKHealthStore.sharedInstance?.requestAuthorizationToShareTypes(nil, readTypes: dataTypes) { 
      [unowned self] success, error in 

      guard success else { 
       self.displayNotAllowed() 
       return 
      } 

      self.queryHeartRateSample() 
     } 
    } 

    func displayNotAllowed() { 
     heartLabel.setText("Not allowed") 
    } 

    func queryHeartRateSample() { 
     guard let heartRateQuery = getHeartRateQuery() else { return } 
     HKHealthStore.sharedInstance?.executeQuery(heartRateQuery) 
    } 

    func updateHeartRate(samples: [HKSample]?) { 
     guard let heartRateSamples = samples as? [HKQuantitySample] else { return } 

     dispatch_async(dispatch_get_main_queue()) { 
      guard let sample = heartRateSamples.first else { return } 
      let value = sample.quantity.doubleValueForUnit(self.heartRateUnit) 
      self.heartLabel.setText(String(UInt16(value))) 
     } 
    } 

    func getHeartRateQuery() -> HKQuery? { 
     guard let heartRateQuantityType = heartRateQuantityType else { 
      displayNotAllowed() 
      return nil 
     } 

     let heartRateQuery = HKSampleQuery(sampleType: heartRateQuantityType, 
      predicate: nil, 
      limit: 100, 
      sortDescriptors: nil) { 
       [unowned self] query, results, error in 
       guard let results = results as? [HKQuantitySample] else { return } 
       self.updateHeartRate(results) 
     } 

     return heartRateQuery 
    } 

} 

@available(iOS 8.0, *) 
public extension HKHealthStore { 

    class var sharedInstance: HKHealthStore? { 
     if !HKHealthStore.isHealthDataAvailable() { 
      return nil 
     } 

     struct Singleton { 
      static let instance = HKHealthStore() 
     } 

     return Singleton.instance 
    } 

} 

Это правильно спросить меня предоставить разрешения, но все равно обновление никогда не запускается. Я делаю что-то неправильно?

ответ

1

Я предпочитаю использовать HKAnchoredObjectQuery искать только новые данные добавлены в HealthKit это избежать запроса всех данных, так что вы можете получить последние значения частоты сердечных сокращений следующим образом, как только вы предоставили разрешения:

private let healthStore = HKHealthStore() 

private let heartRateType = HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeartRate)! 
private let heartRateUnit = HKUnit(fromString: "count/min") 

/** 
Start to measure the heart rate. 
*/ 
func startToMeasure() { 
    self.healthStore.executeQuery(self.createStreamingQuery()!) 
} 


/** 
Create a query to receive new heart rate data from the HealthKit store. 

- returns: The created query 
*/ 
private func createStreamingQuery() -> HKQuery { 
    let predicate = HKQuery.predicateForSamplesWithStartDate(NSDate(), endDate: nil, options: .None) 

    let query = HKAnchoredObjectQuery(type: heartRateType, predicate: predicate, anchor: nil, limit: Int(HKObjectQueryNoLimit)) { 
     (query, samples, deletedObjects, anchor, error) -> Void in 
     self.formatSamples(samples) 
    } 

    query.updateHandler = { (query, samples, deletedObjects, anchor, error) -> Void in 
     self.formatSamples(samples) 
    } 

    return query 
} 

/** 
Format the samples received from HealthKit. 

- parameter samples: Some samples 
*/ 
private func formatSamples(samples: [HKSample]?) { 
    guard let samples = samples as? [HKQuantitySample] else { return } 
    guard let quantity = samples.last?.quantity else { return } 

    let value = Int(quantity.doubleValueForUnit(heartRateUnit)) 
    print("HeartRate: \(value)") 
} 

Вышеприведенный код необходимо интегрировать в какой-либо класс или UIViewController у вас есть. Я использовал в приведенном выше коде предикат для фильтрации по дате, вы можете удалить его, если он не будет релевантным.

Я надеюсь, что это поможет вам.

+0

в симуляторе Запустите этот код и получите сердечный ритм на нем? –

 Смежные вопросы

  • Нет связанных вопросов^_^