Open sohilpandya opened 6 years ago
Today we'll be building a simple app that will let us access users HealthKit data. We'll be starting out with a trying to find out the total number of steps taken over a given period of time by the user.
HealthKit is a framework built by Apple that will allow us to access health and fitness information from a user's device, whether it be an iPhone or an Apple Watch. The data is stored securely in a HealthKit Data Store, we'll be requiring access to this data store and then querying it to give us specific samples. i.e. the number of steps taken by the user.
Let's start out by creating a new project. I've called it healthkit-steps
Next in order for us to be able to access healthkit data we need to take the following two steps:
turn on the capability to access healthkit framework
Very Important After iOS10 we will have to add description keys to our info.plist file to access or update HealthKit Data. The app will crash if we do not have these descriptions keys in place.
In order to access a user's HealthKit data we need to ask for permission from the user, we can do this by adding a button on the storyboard and linking it to a function that will ask for user permissions.
import HealthKit // import this at the top of the file
class ViewController: UIViewController {
let healthStore = HKHealthStore()
// Rest of your code
@IBAction func authoriseHealthKitAccess(_ sender: Any) {
let healthKitTypes: Set = [
// access step count
HKObjectType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount)!
]
healthStore.requestAuthorization(toShare: healthKitTypes, read: healthKitTypes) { (_, _) in
print("authrised???")
}
healthStore.requestAuthorization(toShare: healthKitTypes, read: healthKitTypes) { (bool, error) in
if let e = error {
print("oops something went wrong during authorisation \(e.localizedDescription)")
} else {
print("User has completed the authorization flow")
}
}
}
// Rest of your code
}
Here is what is happening in the above block of code:
requestAuthorization
method from the healthStore which will ask the user for read/write access to the given identifiers. A set
has to be provided as the argument even if we are just requesting access to one type of data. If we run the app in the simulator and select the button, we'll be taken to the authorization screen.
You can also see that the description we provided in the info.plist
is used as the description when asking for permission.
Turn on the access for our app and select Allow, we now have access to read and write to the step count data provided by HealthKit! 🎉
Now that we can access the user's data, let's try to get the number of steps the user may have taken over a given period of time. For this, we need to add a button and a label so that we can ask and then display the data in the app.
func getTodaysSteps(completion: @escaping (Double) -> Void) {
let stepsQuantityType = HKQuantityType.quantityType(forIdentifier: .stepCount)!
let now = Date()
let startOfDay = Calendar.current.startOfDay(for: now)
let predicate = HKQuery.predicateForSamples(withStart: startOfDay, end: now, options: .strictStartDate)
let query = HKStatisticsQuery(quantityType: stepsQuantityType, quantitySamplePredicate: predicate, options: .cumulativeSum) { (_, result, error) in
var resultCount = 0.0
guard let result = result else {
print("Failed to fetch steps rate")
completion(resultCount)
return
}
if let sum = result.sumQuantity() {
resultCount = sum.doubleValue(for: HKUnit.count())
}
DispatchQueue.main.async {
completion(resultCount)
}
}
healthStore.execute(query)
}
@IBOutlet weak var totalSteps: UILabel!
@IBAction func getTotalSteps(_ sender: Any) {
getTodaysSteps { (result) in
print("\(result)")
DispatchQueue.main.async {
self.totalSteps.text = "\(result)"
}
}
}
Here is what is happening in the above block of code:
getTotalSteps
button, which in turn runs the function that will return the total number of steps. getTodaysSteps
we are creating a HKquery by which we will be able to access the HealthKit Data. HKStatisticsQuery
will perform statistical calculations for the given data and return matching samples, it can calculate minimum, maximum and average values for the quantities. This is perfect for our need as it will return the sumQuantity for the total number of steps.
If we build and run this code on the simulator we'll notice that the total number of steps is unfortunately equal to 0.0, this is because the simulator does not have any data. If we try to run the app on our iPhone and see the total number of steps, it should show a real number. 🎉 (don't forget to authorise the app before pressing the get count button)
Great. Thanks a ton
Is the method to read entire workouts similar? As in, I would like my app to retrieve all the data associated with a users workouts i.e. Heart rate, speed, longitude, latitude.
Is it possible to save the steps value to a global variable to use elsewhere in the project?
Thank you so much
I followed your code but not getting any value for result.sumQuantity().
@beherasusanta it would be great if you could share the code so I could read through it. :)
I've looked at it https://developer.apple.com/documentation/healthkit/hkstatistics/1615680-sumquantity and the method hasn't changed :)
Thanks you so much, Hope you do more <3
How does a 3rd party app access Healthkit Data such as a user's steps or heart rate.
We'll take the user through a simple tutorial where they'll be able to:
It's a simple starting app which will familiarise the user to the healthkit framework.
Related to #35