Dunfey · Hotel WWDC as data, est. 1983
Front desk everything
Years
Topics

2021 Health & Fitness

WWDC21 · 21 min · Health & Fitness

Measure health with motion

Discover how you can take your app’s health monitoring to the next level with motion data. Meet Walking Steadiness for iPhone and the six-minute-walk metric for Apple Watch: Walking Steadiness can help your app interpret someone’s quality of walking and risk of falling, while the six-minute-walk metric — along with the HealthKit estimate recalibration API — can track changes to walking endurance following acute events like surgery. We’ll show you how you can support these metrics and help provide actionable health data to people who use your app, helping improve patient care and clinical trials, especially as more services must be delivered remotely.

Watch at developer.apple.com ↗

Transcript all transcripts

Code shown on screen · 8 snippets

Grab authorization to read and share sixMinuteWalkTestDistance type swift · at 0:01 ↗
// Grab authorization to read and share sixMinuteWalkTestDistance type

let healthStore = HKHealthStore()
let types: Set = [
    HKObjectType.quantityType(forIdentifier: .sixMinuteWalkTestDistance)!
]

healthStore.requestAuthorization(toShare: types, read: types) { _, _ in }
Recalibrate Six-Minute Walk estimates swift · at 0:02 ↗
// Recalibrate estimate

let healthStore = HKHealthStore()
let sixMinuteWalkType = HKSampleType.quantityType(forIdentifier: .sixMinuteWalkTestDistance)!

if sixMinuteWalkType.allowsRecalibrationForEstimates {

    healthStore.recalibrateEstimates(sampleType: sixMinuteWalkType, date: surgeryDate) { 
        (success, error) in
        // Handle error
    }

}
Get authorized for walkingSteadiness type swift · at 0:03 ↗
// Get authorized

let types: Set = [
    HKObjectType.quantityType(forIdentifier: .walkingSteadiness)!
]

healthKitStore.requestAuthorization(toShare: nil, read: types) { _, _ in }
Construct a query for most recent walkingSteadiness score swift · at 0:04 ↗
// Construct a query for most recent walkingSteadiness score

let steadinessType = HKObjectType.quantityType(forIdentifier: .walkingSteadiness)
let sortByEndDate = NSSortDescriptor(key: HKSampleSortIdentifierEndDate, ascending: false)

let query = HKSampleQuery(sampleType: steadinessType,
                          predicate: nil,
                          limit: 1,
                          sortDescriptors: [sortByEndDate]) { (query, samples, error) in

    if let sample = samples?.first as? HKQuantitySample{

        let recentScore = sample.quantity.doubleValue(forUnit: .percentUnit)

        updateStatus(score: recentScore)
    }
}

self.healthStore.execute(query)
Construct a query for most recent walkingSteadiness classification swift · at 0:05 ↗
// Construct a query for most recent walkingSteadiness classification

let steadinessType = HKObjectType.quantityType(forIdentifier: .walkingSteadiness)

let query = HKSampleQuery(sampleType: steadinessType,
                          predicate: nil,
                          limit: 1,
                          sortDescriptors: nil) { (query, samples, error) in

    if let sample = samples?.first as? HKQuantitySample{
        
        let recentScore = sample.quantity.doubleValue(forUnit: .percentUnit)

        // Use HealthKit API to classify a value as OK, Low, or Very Low
        let recentClassification = HKAppleWalkingSteadinessClassification(for: walkingSteadiness.quantity)

        updateStatus(classification: recentClassification, score: recentScore)
    }
}

self.healthStore.execute(query)
Get authorized .walkingSteadinessEvent swift · at 0:06 ↗
// Get authorized

let types: Set = [
    HKObjectType.categoryType(forIdentifier: .walkingSteadinessEvent)!
]

healthKitStore.requestAuthorization(toShare: nil, read: types) { _, _ in }
Watch for walkingSteadiness notifications swift · at 0:07 ↗
// Watch for walkingSteadiness notifications

let notificationType = HKCategoryType.categoryType(forIdentifier: .appleWalkingSteadinessEvent)!

let query = HKObserverQuery(sampleType: notificationType, predicate: nil) { 
    (query, completionHandler, errorOrNil) in
    
    if let error = errorOrNil {
        // Properly handle the error.
        return
    }

    promptCheckupForNotification()

    completionHandler()
}

self.healthStore.execute(query)
Query walking steadiness in the past 6 weeks swift · at 0:08 ↗
// Query samples from HealthKit

// Look back 6 weeks
let end = Date()
let start = Calendar.current.date(byAdding: .week, value: -6, to: end)

let datePredicate = HKQuery.predicateForSamples(withStart: start, end: end, options: [])

// Query walking steadiness
let steadinessType = HKObjectType.quantityType(forIdentifier: .walkingSteadiness)
let sortByEndDate = NSSortDescriptor(key: HKSampleSortIdentifierEndDate, ascending: false)

let query = HKSampleQuery(sampleType: steadinessType,
                          predicate: sortByEndDate,
                          limit: nil,
                          sortDescriptors:[sortByEndDate]) { (_, samples, _) in

    detectTrends(samples)
}
self.healthStore.execute(query)

Resources