Integrating Apple HealthKit — Swift

Krishan Madushanka
6 min readJan 1, 2023

--

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 of HealthkitIntegrationApp struct check whether helathkit is available in the device and if availble instantiate HKHealthStore class.Then execute requestHealthkitPermissions() 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 use categotyType and quantityType only. For more data types refer this. These quantityType can be divided into 2 other parts called descrete and cumulative 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 under toShare: parameter. Since I am not going to write any data using my app to health, I pass nil for toShare: parameter.
  • Line 30 — healthStore object is added to the environment then we can use it in ContentView screen.
  • Line 35 — HKHealthStore must conform ObservableObject 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.For limit: you can limit the number of results by passing an Int value for this. Passing HKObjectQueryNoLimit 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 be HKStatisticsOptions.cumulativeSum . We pass HKStatisticsOptions.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: 55the 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 as from: param and date now as to: 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.

--

--

Krishan Madushanka
Krishan Madushanka

Written by Krishan Madushanka

Software Engineer | Android | iOS | Flutter | React Native | IoT | aws certified

Responses (1)