2016-08-13 10 views
13

Nie mogę uzyskać żadnych kalorii/aktywnychEnergyBurned, które pojawią się w mojej aplikacji i nie wiem, dlaczego?Kalorie nie są rejestrowane w aplikacji HealthKit Watch

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

drukuje spośród dziennika '0' bez względu na to jak długo mogę uruchomić aplikację dla.

Testowałem na symulatorze i na urządzeniu.

Na pytanie, tutaj jest kod do zapisywania danych treningu:

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

Gdzie można go zapisać? – Sandeep

+0

@Sandeep Dodałem kod powyżej, aby zapisać dane. Daj mi znać, jeśli masz jakieś myśli lub potrzebujesz, aby dodać coś jeszcze! – SRMR

Odpowiedz

3

Można to zrobić inny sposób bez użycia predykatu.

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 zobacz moją edycję. – tymac

+0

Yup. Zalecam obejrzenie filmu, który oglądałem, aby zobaczyć, jak główna klasa została wykonana przy inicjalizacji. Rozpoczyna się około 29 minut. https://developer.apple.com/videos/play/wwdc2015/203/. Używa predykatu, ale możesz po prostu zastąpić go blokiem zapytania. W moich własnych pytaniach jest także dużo kodu. Dodałem mój init do mojej odpowiedzi. – tymac

+0

Czy obejrzałeś film z 2016 roku? Czy sposób, w jaki to robią w filmie z 2016 r., Nie byłby bardziej aktualny? – SRMR

Powiązane problemy