2016-08-02 28 views
10

Aufbau einer HealthKit/WatchKit App basierend auf WWDC 2015 - Session 203.Wie `AddQuantitiesFromSamples` in HealthKit?

Es gibt keinen Quellcode, also schreibe ich ihn im laufenden Betrieb. Es gibt eine Methode, mit der ich Schwierigkeiten habe, da sie nicht diskutiert wird.

Zum Glück ist es die gleiche addQuantitiesFromSamples Methode für alle Trainingsarten, die Probenmengen zur Trainingseinheit hinzufügen.

Natürlich habe ich diesen Fehler, weil diese Methode nicht in meinem Code existiert.

Wert vom Typ ‚HKQuantity‘ hat kein Mitglied ‚addQuantitiesFromSamples‘

Ich bin nicht sicher, wie ein Verfahren zu schreiben, die Probenmengen hinzufügt. Die Methode muss relativ einfach sein, da sie in allen drei Beispielabfragen im Projekt verwendet wird.

Die sumDistanceSamples Funktion ist, wo das Geheimnis addQuantitiesFromSamples Methode aufgerufen wird.

Dies ist einer der drei Blöcke, die den gleichen Fehler enthalten, also muss ich nur eine Lösung für einen von ihnen finden.

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!) 
    } 

} 

Antwort

6

Ich bin mir nicht sicher, ob dies ist, was Sie suchen, aber dies scheint Ihr fehlt Methode von jemand anders zu sein, die die gleiche WWDC Video angesehen:

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 
    } 
} 

Quelle: Calories and Distance data from query

+0

Es ist schon komisch. Diesen Thread habe ich natürlich auch gefunden, da ich überall gesucht habe. Aber ich wusste nicht, dass die Erweiterung funktionieren könnte. Lass es mich versuchen und komme zu dir zurück. Vielen Dank. – tymac

+0

@tymac sollte am Ende der Swift-Datei außerhalb der Klasse platziert werden. Ist Ihre Klasse privat oder intern? Haben Sie versucht, die Erweiterung öffentlich zu machen? Verwenden Sie mehrere Module in Ihrer Anwendung? – JAL

+0

Oh warte eine Sekunde! Ich denke ich verstehe jetzt. 2 der 3 Summierungsblöcke scheinen in Ordnung zu sein. Die Methoden addDistanceSamples und addActiveEnergySamples scheinen die Erweiterung zu akzeptieren. Aber die Herzfrequenzsummierung mag die Verlängerung nicht, weil die Herzfrequenz nicht summiert. Es aktualisiert gerade richtig? Kann ich dieselbe Erweiterung verwenden, um eine separate Methode für die Herzfrequenz zu erstellen? Wie arbeite ich mit 'updateHeartRateSamples'? – tymac