2016-08-13 3 views
13

Ich kann keine Kalorien/activeEnergyBurned in meiner App angezeigt werden, und weiß nicht warum?Kalorien werden nicht für HealthKit Watch App aufgezeichnet

WorkoutInterfaceController:

private func totalCalories() -> Double { 
    return totalEnergyBurned.doubleValue(for: HKUnit.kilocalorie()) 
} 

private func setTotalCalories(calories: Double) { 
    totalEnergyBurned = HKQuantity(unit: HKUnit.kilocalorie(), doubleValue: calories) 
} 

func startQuery(quantityTypeIdentifier: HKQuantityTypeIdentifier) { 
    let datePredicate = HKQuery.predicateForSamples(withStart: workoutStartDate, end: nil, options: .strictStartDate) 
    let devicePredicate = HKQuery.predicateForObjects(from: [HKDevice.local()]) 
    let queryPredicate = NSCompoundPredicate(andPredicateWithSubpredicates:[datePredicate, devicePredicate]) 

    let updateHandler: ((HKAnchoredObjectQuery, [HKSample]?, [HKDeletedObject]?, HKQueryAnchor?, Error?) -> Void) = { query, samples, deletedObjects, queryAnchor, error in 
     self.process(samples: samples, quantityTypeIdentifier: quantityTypeIdentifier) 
    } 

    let query = HKAnchoredObjectQuery(type: HKObjectType.quantityType(forIdentifier: quantityTypeIdentifier)!, 
             predicate: queryPredicate, 
             anchor: nil, 
             limit: HKObjectQueryNoLimit, 
             resultsHandler: updateHandler) 
    query.updateHandler = updateHandler 
    healthStore.execute(query) 

    activeDataQueries.append(query) 
} 

func process(samples: [HKSample]?, quantityTypeIdentifier: HKQuantityTypeIdentifier) { 
    DispatchQueue.main.async { [weak self] in 
     guard let strongSelf = self, !strongSelf.isPaused else { return } 

     if let quantitySamples = samples as? [HKQuantitySample] { 
      for sample in quantitySamples { 
       if quantityTypeIdentifier == HKQuantityTypeIdentifier.activeEnergyBurned { 
        let newKCal = sample.quantity.doubleValue(for: HKUnit.kilocalorie()) 
        strongSelf.setTotalCalories(calories: strongSelf.totalCalories() + newKCal) 
        print("NewKCal: \(newKCal)") 
        print("TotalCalories: \(strongSelf.totalCalories())") 
       } 
      } 

      strongSelf.updateLabels() 
     } 
    } 
} 

Die Protokoll druckt '0', egal wie lange ich die App laufen.

Ich habe auf dem Simulator und auf dem Gerät getestet.

Per Frage, hier ist der Code für Trainingsdaten Speichern:

private func saveWorkout() { 
    // Create and save a workout sample 
    let configuration = workoutSession!.workoutConfiguration 
    let isIndoor = (configuration.locationType == .indoor) as NSNumber 
    print("locationType: \(configuration)") 

    let workout = HKWorkout(activityType: configuration.activityType, 
          start: workoutStartDate!, 
          end: workoutEndDate!, 
          workoutEvents: workoutEvents, 
          totalEnergyBurned: totalEnergyBurned, 
          totalDistance: nil, 
          metadata: [HKMetadataKeyIndoorWorkout:isIndoor]); 

    healthStore.save(workout) { success, _ in 
     if success { 
      self.addSamples(toWorkout: workout) 
     } 
    } 

    // Pass the workout to Summary Interface Controller 
    WKInterfaceController.reloadRootControllers(withNames: ["SummaryInterfaceController"], contexts: [workout]) 
} 

private func addSamples(toWorkout workout: HKWorkout) { 
    // Create energy and distance samples 
    let totalEnergyBurnedSample = HKQuantitySample(type: HKQuantityType.activeEnergyBurned(), 
                quantity: totalEnergyBurned, 
                start: workoutStartDate!, 
                end: workoutEndDate!) 


    // Add samples to workout 
    healthStore.add([totalEnergyBurnedSample], to: workout) { (success: Bool, error: Error?) in 
     if success { 
      // Samples have been added 
      print("Samples have been added") 
     } 
    } 
} 
+0

Wo du sie retten? – Sandeep

+0

@Sandeep Ich habe den obigen Code für die Speicherung der Daten hinzugefügt. Lass es mich wissen, wenn du irgendwelche Gedanken hast oder dass ich etwas anderes hinzufügen soll! – SRMR

Antwort

3

Sie es ohne Prädikat eine andere Art und Weise tun.

weak var delegate: WorkoutSessionManagerDelegate? 
let healthStore: HKHealthStore 
var workoutSession: HKWorkoutSession 
var workoutStartDate: NSDate? 
var workoutEndDate: NSDate? 
var queries: [HKQuery] = [] 
var activeEnergySamples: [HKQuantitySample] = [] 
var distanceSamples: [HKQuantitySample] = [] 
var heartRateSamples: [HKQuantitySample] = [] 
let energyUnit = HKUnit.calorieUnit() 
let distanceUnit = HKUnit.meterUnit() 
let countPerMinuteUnit = HKUnit(fromString: "count/min") 
var anchor = HKQueryAnchor(fromValue: Int(HKAnchoredObjectQueryNoAnchor)) 
let activeEnergyType = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierActiveEnergyBurned)! 
let heartRateType = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeartRate)! // 1/3 

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? 

init(context: WorkoutSessionContext) { 
    self.healthStore = context.healthStore 
    self.workoutSession = HKWorkoutSession(activityType: context.activityType, locationType: context.locationType) 
    self.currentActiveEnergyQuantity = HKQuantity(unit: self.energyUnit, doubleValue: 0.0) 
    self.currentDistanceQuantity = HKQuantity(unit: self.distanceUnit, doubleValue: 0.0) 

    super.init() 
    self.workoutSession.delegate = self 
} 

// MARK: Active Energy Burned Streaming 
func createActiveEnergyStreamingQuery(workoutStartDate: NSDate) -> HKQuery? { 

    print("Active energy query started") 

    // ** Creating a match samples predicate to sum the data is no longer the convention ** 

    // Sum the new quantities with the current active energy quantity. 
    guard let quantityType = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierActiveEnergyBurned) else {return nil} 

    // Instantiate a HKAnchoredObjectQuery object with a results handler that calls our sumEnergyBurnedSamples function 
    let activeEnergyQuery = 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.addActiveEnergySamples(samples) 
    } 

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


func addActiveEnergySamples(samples: [HKSample]?) { 

    print("Updating calorie samples") 

    guard let activeEnergyBurnedSamples = samples as? [HKQuantitySample] else { return } 

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

     // Adds the new active energy sample to the running total 
     self.currentActiveEnergyQuantity = self.currentActiveEnergyQuantity.addQuantitiesFromSamples(activeEnergyBurnedSamples, unit: self.energyUnit) 

     // Adds that sample to an array of samples accumulated over the workout 
     self.activeEnergySamples += activeEnergyBurnedSamples 

     // Whenever new samples become available, call the corresponding delegate method. This updates the UI with new samples. 
     self.delegate?.workoutSessionManager(self, didUpdateActiveEnergyQuantity: self.currentActiveEnergyQuantity) 

     // Print checks 
     guard let sample = activeEnergyBurnedSamples.first else{return} 
     let value = sample.quantity.doubleValueForUnit(self.energyUnit) 
     print(value) 
    } 
} 

enter image description here

+0

Yup sehe meine Bearbeitung. – tymac

+0

Yup. Ich empfehle, das Video, das ich gerade angesehen habe, anzusehen, um zu sehen, wie die Hauptklasse mit der Initialisierung fertig war. Beginnt um die 29-Minuten-Marke. https://developer.apple.com/videos/play/wwdc2015/203/. Er verwendet das Prädikat, aber Sie können es einfach durch den Abfrageblock ersetzen. Es gibt auch viel Code in meinen eigenen Fragen. Ich habe meine Antwort zu meiner Antwort hinzugefügt. – tymac

+0

Hast du das Video 2016 gesehen? Wäre die Art, wie sie es im Video 2016 machen, nicht aktualisierter oder nicht? – SRMR

Verwandte Themen