2016-08-02 4 views
10

Создание приложения HealthKit/WatchKit на основе WWDC 2015 - Session 203.Как «addQuantitiesFromSamples» в HealthKit?

Исходный код отсутствует, поэтому я пишу его на лету. Есть метод, с которым я испытываю трудности, поскольку они не обсуждают его.

К счастью, это тот же метод addQuantitiesFromSamples для всех типов тренировки, которые добавляют количество образцов в сеанс тренировки.

Конечно, у меня есть эта ошибка, потому что этот метод не существует в моем коде.

Значение «HKQuantity» типа имеет ни один из членов «addQuantitiesFromSamples»

Я не знаю, как написать метод, который добавляет примеры величин. Метод должен быть относительно базовым, поскольку он используется во всех трех примерах запросов в проекте.

Функция sumDistanceSamples - это функция, которая называется метод загадки addQuantitiesFromSamples.

Это один из трех блоков, содержащих одну и ту же ошибку, поэтому мне просто нужно найти решение для одного из них.

WorkoutSessionManager.swift

class WorkoutSessionManager: NSObject, HKWorkoutSessionDelegate { 

var activeEnergySamples: [HKQuantitySample] = [] 
var distanceSamples: [HKQuantitySample] = [] 
var heartRateSamples: [HKQuantitySample] = [] 

// ... code 

var distanceType: HKQuantityType { 
    if self.workoutSession.activityType == .Cycling { 
     return HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierDistanceCycling)! 
    } else { 
     return HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierDistanceWalkingRunning)! 
    } 
} 

var currentActiveEnergyQuantity: HKQuantity 
var currentDistanceQuantity: HKQuantity 
var currentHeartRateSample: HKQuantitySample? 

// ... code 


// MARK: Data queries 

// Create streaming query helper method. 
func createStreamingDistanceQuery(workoutStartDate: NSDate) -> HKQuery? { 
    guard let quantityType = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierDistanceWalkingRunning) else {return nil} 

    // Instantiate a HKAnchoredObjectQuery object with a results handler. 
    let distanceQuery = HKAnchoredObjectQuery(type: quantityType, predicate: nil, anchor: anchor, limit: Int(HKObjectQueryNoLimit)) { (query, samples, deletedObjects, newAnchor, error) -> Void in 
     guard let newAnchor = newAnchor else {return} 
     self.anchor = newAnchor 
     self.sumDistanceSamples(samples) 
    } 

    // Results handler that calls sumDistanceSamples function. 
    distanceQuery.updateHandler = {(query, samples, deletedObjects, newAnchor, error) -> Void in 
     self.anchor = newAnchor! 
     self.sumDistanceSamples(samples) 
    } 

    return distanceQuery 
} 

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

    dispatch_async(dispatch_get_main_queue()) { 

     // Error point - "no member 'addQuantitiesFromSamples'" 
     self.currentDistanceQuantity = self.currentDistanceQuantity.addQuantitiesFromSamples(currentDistanceSamples, unit: self.distanceUnit) 

     // Add sample to array of samples accumulated over the workout. 
     self.distanceSamples += currentDistanceSamples 

     self.delegate?.workoutSessionManager(self, didUpdateDistanceQuantity: self.currentDistanceQuantity) 

    } 
} 

// MARK: HEART RATE STREAMING 
func createHearRateStreamingQuery(workoutStartDate: NSDate) -> HKQuery? { 

    // alternative method to creating a match samples predicate 

    // Append the new quantities with the current heart rate quantity. 
    guard let quantityType = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeartRate) else {return nil} 

    // Instantiate a HKAnchoredObjectQuery object with a results handler that calls our sumHeartRateSamples function 
    let heartRateQuery = HKAnchoredObjectQuery(type: quantityType, predicate: nil, anchor: anchor, limit: Int(HKObjectQueryNoLimit)) { (query, samples, deletedObjectts, newAnchor, error) -> Void in 
     guard let newAnchor = newAnchor else {return} 
     self.anchor = newAnchor 
     self.updateHeartRateSamples(samples) 
    } 

    // Results handler that calls our addActiveEnergySamples function 
    heartRateQuery.updateHandler = {(query, samples, deletedObjects, newAnchor, error) -> Void in 
     self.anchor = newAnchor! 
     self.updateHeartRateSamples(samples) 
    } 

    return heartRateQuery 
} 

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

    // updateHeartRateSamples method dispatches back to the main queue. 
    dispatch_async(dispatch_get_main_queue()) { 

     // Error: Value of type 'HKQuantitySample?' has no member 'addQuantitiesFromSamples 
     self.currentHeartRateSample = self.currentHeartRateSample.addQuantitiesFromSamples(heartRateCountSamples, unit: self.countPerMinuteUnit) 

     // appends/updates that sample to an array of samples accumulated over the workout. 
     self.heartRateSamples += heartRateCountSamples 

     self.delegate?.workoutSessionManager(self, didUpdateHeartRateSample: self.currentHeartRateSample!) 
    } 

} 

ответ

6

Я не уверен, если это то, что вы ищете, но это, кажется, ваш отсутствующий метод от кого-то, кто смотрел тот же WWDC видео:

extension HKQuantity { 
    func addQuantitiesFromSamples(samples : [HKQuantitySample], unit: HKUnit) -> HKQuantity { 

     var currentValue = doubleValueForUnit(unit) 

     for sample in samples { 
      let value = sample.quantity.doubleValueForUnit(unit) 
      currentValue += value 
     } 
     let result = HKQuantity(unit: unit, doubleValue: currentValue) 
     return result 
    } 
} 

Источник: Calories and Distance data from query

+0

Это забавно. Я, очевидно, нашел эту нить, так как я искал везде. Но я не понимал, что расширение может работать. Позвольте мне попробовать и вернуться к вам. Благодарю. – tymac

+0

@tymac, размещающий его в конце вашего файла Swift за пределами класса, должен работать. Является ли ваш класс частным или внутренним? Вы пытались сделать публикацию расширения? Используете ли вы несколько модулей в своем приложении? – JAL

+0

Ой, подождите секунду! Думаю, теперь я понимаю. 2 из 3 суммирующих блоков выглядят нормально. Метод 'addDistanceSamples' и' addActiveEnergySamples', как представляется, принимают расширение. Но суммирование сердечного ритма не нравится расширение, потому что сердечный ритм не суммируется. Он просто обновляется? Могу ли я использовать дубликат одного и того же расширения для создания отдельного метода для частоты сердечных сокращений? Как я могу работать с 'updateHeartRateSamples'? – tymac