Integrating Apple HealthKit — Swift
Apple comes with nice app on iphones called Health which collects health and fitness data from your iPhone, the built-in sensors on your Apple Watch, compatible third-party devices, and apps that use HealthKit. With this apple ships Apple Healthkit which facilitates thirdparty apps, accessing and sharing health and fitness data while maintaining the user’s privacy and control.This article guides you in integrating the apple healthkit with your ios native mobile app and writing some queries to read user’s health data.
I’ll be using Xcode 14.0.1 while implementing the sample app here.
Adding HealthKit to your app
- Openup Xcode application in your mac and create a new ios project (HealthkitIntegration) with SwiftUI.(Using SwiftUI is not mandatory you can use UIKit as well with your requirement)
- Select your project name in Xcode and click on Signing and Capabilities tab.
- Then click on + Capability.
- Now serch for healthkit in the dilog appeared and click on HealthKit from search results.
- Now you will see that healthkit has been added to your project. Next go to info tab in same screen and add NSHealthShareUsageDescription under Custom iOS Target Properties.
Here I have added message to the user that explains why the app requested permission to read samples from the HealthKit store. If you want to add write permission to apple health, you must add NSHealthUpdateUsageDescription similarly. Since I am going to write queries only to read data in this artivle I’ll add only NSHealthShareUsageDescription permission.
Request permission from apple health to access or share a by user’s thirdparty app
Open HealthkitIntegrationApp.swift file which is the entry file for our project. Write the following code there.
- Line 2 — Import HealthKit into your file.
- Line 9 to 13 — Inside the
init()
function ofHealthkitIntegrationApp
struct check whether helathkit is available in the device and if availble instantiateHKHealthStore
class.Then executerequestHealthkitPermissions()
function. - Line 17 to 21 — Inside
requestHealthkitPermissions()
function first we create the set of data types that we want to request permission. Here I have added asking permission for reading heart rate, step count and sleep analysis.There are lot of data types available with apple helath and here I have usecategotyType
andquantityType
only. For more data types refer this. ThesequantityType
can be divided into 2 other parts calleddescrete
andcumulative
types. With descrete types we can query for Average, min and max(ex — : average,min or max heart rate of the day) while with cumulative type we can query for cumulative sum(ex — : total step count within a week) - Line 23 to 25 — Requesting permission for the declared types. For read permission pass types under
read:
parameter and for save and update permission pass types undertoShare:
parameter. Since I am not going to write any data using my app to health, I passnil
fortoShare:
parameter. - Line 30 — healthStore object is added to the environment then we can use it in
ContentView
screen. - Line 35 —
HKHealthStore
must conformObservableObject
to be able to put healthStore to the environment. - If you run the application you can see the below screen with permission request.
- Note that if you deny the permission also you will get “Success” printed since this success response is not about whether user granted permission. It is about was apple health successfully promted user to give permission. For more clarification about this refer this. There is a function called
authorizationStatus
to check authorization status but ,
This method checks the authorization status for saving data.
To help prevent possible leaks of sensitive health information, your app cannot determine whether or not a user has granted permission to read data. If you are not given permission, it simply appears as if there is no data of the requested type in the HealthKit store. If your app is given share permission but not read permission, you see only the data that your app has written to the store. Data from other sources remains hidden.
— healthkit documentation
Writing queries to read data
There are lot of queries that we can use with apple healthkit but this article will cover only 3 types of queries that are used very commonly.
HKSampleQuery
The sample query returns sample objects that match the provided type and predicate. You can provide a sort order for the returned samples, or limit the number of samples returned.
Above readHeartRate()
function will print all heart rate values recorded in last 24 hours.
- Line 24 — Defining the type that we want to query
- Line 25 — Defininf in which way we want to sort the data. Here I want to sort by date in acending order.
- Line 26 to 30 — Defining the query with the relavant parameters.Since I want to get data in last 24 hrours I should create the predicate for it.
get24hPredicate()
function will return the predicate we want.Forlimit:
you can limit the number of results by passing anInt
value for this. PassingHKObjectQueryNoLimit
won’t have limit. - Line 37 — Read the value with relavant units.Heart beat will have “count/time” units.Read more about different units from here.
- Line 42 — Executing the query to retrieve data.Once the query is executed it will call the
resultsHandler
closure where we handle the result data.
HKStatisticsQuery
Statistics queries calculate common statistics over the set of matching samples. You can use statistical queries to calculate the minimum, maximum, or average value of a set of discrete quantities, or use them to calculate the sum for cumulative quantities. Keep in mind that you can use statistics queries with quantity samples only.
Above readTotalStepCount()
function will read the total step count in last 24 hours. Note that we use statistics query since we want to get cumulative sum.Similarly we can get Avg,Min and Max values for descrete types like heart rate,blood glucose etc.
Let’s go through the code and the simillar code snippets that comes from HKSampleQuery won’t be repeated.
- Line 6 to 8 — Iinitializing HKStatisticsQuery. Since we want to get the sum of steps in last 24 hours, predicate will be set for last 24hrs and
options:
will beHKStatisticsOptions.cumulativeSum
. We passHKStatisticsOptions.separateBySource
if we want to get the total step counts recorded by different sources like apple watch and iphone. - Line 9 — Read the value with count units. You can get the relavant unit by visiting the apple healthkit documentation for relavant data type.
HKStatisticsCollectionQuery
Statistics collection queries are often used to produce data for graphs and charts. For example, you might create a statistics collection query that calculates the total number of steps for each day or the average heart rate for each hour. Again, you can only use statistics collection queries with quantity samples.
Above readHourlyTotalStepCount()
function will calculate total step count for each hour in last 24 hours. Note that we get an array of total step counts for each hour.
- Line 6 to 7 — Defining the interval that we want data.Since I want total step count for each hour I am setting
interval.hour = 1
. - Line 9 to 10 — When we initialise the query we need to specify an anchor. The anchor defines a moment in time where we are to calculate our samples from. Here since I have set the
minute: 55
the hours will be like 9:55–10:55 AM, 10:55–11:55 AM etc. - Line 18 to 23 —
initialResultsHandler
will get the data after executing the query and then we have the option of enumerating through the statistics. There we’ll pass a date before 24hrs from now asfrom:
param and date now asto:
param.
P.S — Note that above queries run asynchronously by apple healthkit. We don’t need to put them inside a asynchronous block.
Find the completed code from here.