1

At WWDC 2017 Apple announced the addition of vo2Max as new quantity sample. What variables must be in place in order to return vo2Max samples? Per the Health App under Vo2Max "Apple Watch Records your predicted vo2Max when you do a rigorous outdoor walk or run in the Workout app for at least 20 minutes with a persistent heart rate measurement." Which sounds as though it is not available to 3rd party apps, however this clip at WWDC 2017 at 3:20 makes it sounds as though it should be available?

The below code during a .running outdoor workout returns and empty array even after 20 minutes:

func startVO2MaxQuery(from startDate: Date, updateHandler: @escaping ([HKQuantitySample]) -> Void) {
        let typeIdentifier = HKQuantityTypeIdentifier.vo2Max
        startQuery(ofType: typeIdentifier, from: startDate) { _, samples, _, _, error in
            guard let quantitySamples = samples as? [HKQuantitySample] else {
                print("Heart rate query failed with error: \(String(describing: error))")
                return
            }
            print("VO2Max samples = \(quantitySamples)")
            updateHandler(quantitySamples)

        }
    }



 private func startQuery(ofType type: HKQuantityTypeIdentifier, from startDate: Date, handler: @escaping
        (HKAnchoredObjectQuery, [HKSample]?, [HKDeletedObject]?, HKQueryAnchor?, Error?) -> Void) {
        let datePredicate = HKQuery.predicateForSamples(withStart: startDate, end: nil, options: .strictStartDate)
        let devicePredicate = HKQuery.predicateForObjects(from: [HKDevice.local()])
        let queryPredicate = NSCompoundPredicate(andPredicateWithSubpredicates:[datePredicate, devicePredicate])

        let quantityType = HKObjectType.quantityType(forIdentifier: type)!

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

        activeDataQueries.append(query)
    }

permissions

 private func requestAccessToHealthKit() {
let healthStore = HKHealthStore()

let allTypes = Set([HKObjectType.workoutType(),
                    HKSeriesType.workoutRoute(),
                    HKObjectType.quantityType(forIdentifier: .activeEnergyBurned)!,
                    HKObjectType.quantityType(forIdentifier: .heartRate)!,
                    HKObjectType.quantityType(forIdentifier: .vo2Max)!,
                    HKObjectType.quantityType(forIdentifier: .stepCount)!,
                    HKObjectType.quantityType(forIdentifier: .distanceWalkingRunning)!])

healthStore.requestAuthorization(toShare: allTypes, read: allTypes) { (success, error) in
    if !success {
        print("failed HealthKit Authorization from iPhone \(String(describing: error?.localizedDescription))")
    }

    print("Successful HealthKit Authorization directly from the watch")
}

}

Is there anything else I need to do? Apple's documentation is pretty sparse.

GarySabo
  • 5,806
  • 5
  • 49
  • 124
  • HealthKit access granted? – Dharmesh Kheni Dec 16 '17 at 06:06
  • Yes should have said that, edited my question to post my permissions – GarySabo Dec 16 '17 at 15:07
  • Might be a stupid question, but are you sure there are VO2Max samples in HealthKit to get with your query? – Allan Dec 18 '17 at 16:55
  • @Allan not a stupid question at all but given the sparseness of the documentation I really have no idea what's available. I would think it would be measurable during a running workout because if it wasn't when would it be? – GarySabo Dec 18 '17 at 20:24
  • Are we sure that the Apple Watch has sensors that can calculate vo2Max? Some of their HKQuantityTypeIdentifiers, such as dietaryFiber, for example, definitely don't have built in readings from the Apple Watch, so I'm wondering if that's the case with vo2Max. They provide some of these identifiers so that hardware developers can make instruments that can write to Health Kit. – joshuakcockrell Dec 18 '17 at 21:05
  • @joshuakcockrell see here at 3:20 https://developer.apple.com/videos/play/wwdc2017/221/ she seems to imply it's a readable value – GarySabo Dec 18 '17 at 21:40
  • @GarySabo Yeah you're right she is pretty clear that WatchOS 4 measures this! Let me know if you find out more. – joshuakcockrell Dec 18 '17 at 21:48
  • @GarySabo the values for this type can be calculated automatically by an Apple Watch. You can navigate to VO2Max in the Health app (under Activity) to see what values you can expect to get back from your query. – Allan Dec 18 '17 at 22:27
  • @Allan but why can I not get them back through my query? – GarySabo Dec 19 '17 at 00:17
  • @GarySabo What VO2Max samples are listed in Health? What are the dates associated with them? It's possible your query predicates are too restrictive – Allan Dec 19 '17 at 02:00
  • @GarySabo I went ahead and tested out vo2Max readings this morning. I have an app that correctly measures heart rate, steps, calories burned, etc. I was NOT able to get back ANY vo2Max readings on the simulator or on the actual device. Yes auth was working. This was a similar setup to yours with .running .outside workout session and using an HKAnchoredObjectQuery. The update handler was just never called for the vo2Max HKQuantityTypeIdentifier :/ Note this has nothing to do with converting the samples into the correct double format (that happens later once I get samples) – joshuakcockrell Dec 21 '17 at 16:41
  • damn thanks for that @joshuakcockrell maybe they haven't turned the switch on yet – GarySabo Dec 21 '17 at 17:55
  • @GarySabo Now that I read your post again, it looks like they want 20+ minutes of persistent heart rate measurement. I only ran the code for maybe 2 minutes so I will try a more in depth test and let you know! – joshuakcockrell Dec 21 '17 at 23:24
  • @joshuakcockrell oh, yeah I thought you had read that. I also added height and weight data in the health app in case that’s a requirement as well. Thanks again for the help! – GarySabo Dec 22 '17 at 00:25

0 Answers0