Introduction
We live in a world of data. It is believed that over 2.5 quintillion bytes are generated every day - how big is that? I’m not sure, just a ridiculously large amount.
But what’s also quite interesting is that - our bodies are functioning biological systems that generate tons of data every day. Any functionining system needs to be monitored, taken care of to be able to use it effectively. Our health care systems do pretty much that. We’ve developer a wide variety of sensors that are able to read information from our body, these give us bio-markers or data that are of concern in the field of medicine to make certain interpretations.
We still have a wide variety of hardware components and software systems that can give us accurate information - but what we also do have is something close to it in our pockets - iOS now enables us to read a subset of mobility information from our bodies that could be use in a variety of ways.
Mobility Metrics in iOS
With iOS 14 — Apple has introduced Mobility Metrics which allow us to gather mobility information that prove quite useful such as walking speed, step-length, double support time, six-minute walk distance, etc.
We’ll quickly take a look at how to gather one of the metrics thats quite interesting to look at — Walking Speed.
Mobility Metrics is baked into HealthKit and can be accessed by simply constructing and executing a HKSampleQuery
with a HKHealthStore
.
Querying Walking Speed
There are three steps to gather this information from our device:
Consent
Any health related information that we get access to on a user’s device requires consent.
This means that the first step in this process would be to request authorization from the user before getting access to their samples.
Construct a
HKSampleQuery
A
HKSampleQuery
requires 3 pieces of information to be constructed:- A Sample Type (in our case this is walkingSpeed)
- A Predicate (which indicates the period of type we’re requesting the sample from). Optional.
- Sort Descriptor (inorder to get a sorted list of samples). Also, optional.
Execute Query with a
HKHealthStore
Now that we broadly understand how this is done, let’s take a look at this code to do this:
Setup
Setup a HealthKit store.
1private let store: HKHealthStore = HKHealthStore()
Request Authorisation
1private let typesToRead: Set = [2 HKObjectType.quantityType(forIdentifier: .walkingSpeed)!3]45public func requestAuthorization() {6 store.requestAuthorization(toShare: nil, read: typesToRead) { (success, error) in7 if !success, let error = error {8 print("Authorization Failed: \(error.localizedDescription)")9 }10 }11}
Here, we’ve simply defined a Set
of types that we’re interested in, just walkingSpeed
in our case, and use it to call requestAuthorization
on our health store.
This call triggers the native alert asking for permissions from the user. Also to note is to include the corresponding Info.plist
that’s required to indicate to the user how their information is used.
Query for Walking Speed
Once we’ve got the authorisation from the user, we can proceed with building our query and executing it with the store —
1public func walkingSpeedSamples(_ completion: @escaping WalkingSpeedSamplesResult) {2 // 13 let start = Calendar.current.date(byAdding: .day, value: -30, to: .init())4 let end = Calendar.current.date(byAdding: .day, value: 60, to: .init())56 // 27 let datePredicate = HKQuery.predicateForSamples(withStart: start, end: end, options: [])89 // 310 let walkSpeedType = HKSampleType.quantityType(forIdentifier: .walkingSpeed)!11 let sortByStartDate = NSSortDescriptor(key: HKSampleSortIdentifierStartDate, ascending: true)1213 // 414 let query = HKSampleQuery(sampleType: walkSpeedType,15 predicate: datePredicate,16 limit: HKObjectQueryNoLimit,17 sortDescriptors: [sortByStartDate]) { (_, samples, error) in18 completion(.success(samples))19 }202122 // 523 store.execute(query)24}
- We start by defining the start and end dates for the period of samples we’re interested in.
- We use the defined ranges to build a predicate that indicates this range, with HealthKit we’re able to use
HKQuery.prdicateForSamples()
method to build anNSPredicate
- We then define our sample type which in our case could be buiild with the
HKSampleType.quantityType(forIdentifier:)
method that takes an enum of the metric we’re interested in. - We can now build a
HKSampleQuery
, with all of the information we have, and additionally pass a closure which gets called when the query is executed. - Execute the query using
store.execute()
Inspecting the Samples
The samples we get back using this process look something like —
1[1.61 m/s 037C636A-23C2-4A55-B2C0-F3A6514291A0 "Arvind’s iPhone" (14.3),2"iPhone13,3" (14.3) "iPhone" (2021-02-06 6:22:05 pm +0000 - 2021-02-06 6:22:31 pm +0000),31.49 m/s CD229350-FC24-4BEA-89B3-1B4R229F1A5E "Arvind’s iPhone" (14.3),4"iPhone13,3" (14.3) "iPhone" (2021-02-06 6:22:47 pm +0000 - 2021-02-06 6:23:07 pm +0000),50.94 m/s 9EFA6631-A73C-4574-9EDB-5111B4F123FB4 "Arvind’s iPhone" (14.3),]
This set of samples that are returned are of type HKSample
and are really good inputs for visualising them with charts, graphs etc. ResearchKit provides us with a number of these views that could be used for this purpose.
Hope this was useful - I’ve put this together into a Swift Package incase you’re interested — MobilityKit.