❤ī¸HealthKit

HealthKit is currently in beta testing, so if you find any issues, let us know in the support chat.

General Info

HealthKit is a framework developed by Apple that allows health and wellness data to be collected, analyzed, and shared across different applications.

By taking advantage of the HealthKit framework, you can create a more robust and effective health and wellness app that meets the needs of today’s mobile-savvy users.

HealthKit integration can improve the user experience of your health and wellness app, provide more accurate data and insights, increase user engagement, and enhance data security and privacy. By taking advantage of the HealthKit framework, you can create a more robust and effective health and wellness app that meets the needs of today’s mobile-savvy users.

HealthKit is a huge framework, but Natively has access to several values (for now). Quantity, characteristics, and category.

  1. Each of these types needs to be requested permission to read them.

  2. Quantity Values are calculated with a default Apple's HKStatisticsCollection

  3. All Quantity Values have different values to work with (e.g. milliseconds, count/s, count/min, etc.)

Quantity Values:

  • HRV (Heart Rate Variability SDNN)

    The standard deviation of heartbeat intervals, measured in milliseconds

  • RHR (Resting Heart Rate)

    User’s resting heart rate, measured in count/s

  • BMI (Body Mass Index) User’s body mass index, measured in count

  • HEIGHT User’s height, measured in centimeters

  • BODY_MASS - User's body mass User's body mass, measured in kilograms

  • STEPS User's steps, measured in count

  • HEART_RATE User's heart rate, measured in count/min

  • ACTIVE_ENERGY User's burned active energy, measured in kilocalories

  • BLOOD_OXYGEN User's blood oxygen, measured in percent

Characteristics Values:

  • DATE_OF_BIRTH User's age, measured in years (e.g. 67)

  • BLOOD_TYPE User's blood type (e.g. AB- / AB+ / A- / B+ / B- / B+ / O- / O+ / NOT_SET)

  • SEX User's biological sex - (e.g. MEN / WOMAN / OTHER / NOT_SET)

  • SKIN_TYPE User's skin type - (e.g. I / II / III / IV / V / VI / NOT_SET)

  • WHEELCHAIR A value indicating the user’s wheelchair use - (e.g. YES / NO / NOT_SET)

Category Values:

  • SLEEP_ANALYSIS

    Has a few different types:

    • IN_BED

    • AWAKE

    • ASLEEP - available only in iOS 16+ (only with Apple Watch)

    • ASLEEP_REM - available only in iOS 16+ (only with Apple Watch)

    • ASLEEP_DEEP - available only in iOS 16+ (only with Apple Watch)

    • ASLEEP_UNSPECIFIED

    • UNKNOWN

More details about each Sleep Analysis value can be found here

  • ACTIVITY_SUMMARY Main fields:

    • Active Energy Burned (.activeBurned) - kilocalories

    • Active Energy Goal (.activeGoal) - kilocalories

    • Exercise Time (.exerciseTime) - time interval in minutes

    • Exercise Goal (.exerciseGoal) - time interval in minutes

    • Move Time (.moveTime) - time interval in minutes (available only in iOS 14+)

    • Move Goal (.moveGoal) - time interval in minutes (available only in iOS 14+)

    • Stand Hours (.standHours) - count

    • Stand Goal (.standGoal) - count

More details about each Activity Summary value can be found here

  • WORKOUTS (JS SDK >= 2.13.0) Main fields:

    • Total Energy Burned - kilocalories

    • Basal Energy Burned - kilocalories (>iOS 16)

    • Active Energy Burned - kilocalories (>iOS 16)

    • Workout Name - string, more details here

    • Heart Rate - count/min

    • Start Date - date

    • End Date - date

    • Duration - seconds

To implement HealthKit correctly you need to:

  1. Turn on DEBUG mode for a development purpose

  2. Check if HealthKit is available on a device. (iPads are not supported)

  3. Request permissions for specific Values (e.g. SKIN_TYPE, HEART_RATE, SLEEP_ANALYSIS, WORKOUTS)

  4. We're highly recommending writing a good Permission Description that explains to the user why you need such permission (otherwise, you will be rejected by Apple, or the User will not give access to specific data)

  5. Request the data and receive it

  6. All values requests are taking some time (except characteristics values). The calculation happens on a device, so if you're requesting a lot of data for an extended period (3-12 months), it might take 5-30 seconds to return it.

Bubble.io Web Apps

HealthKit can be integrated with our Bubble.io plugin. More details about it can be found here.

Plugin contains 3 elements: Natively - HealthKit BASE, Natively - HealthKit SLEEP & Natively - HealthKit ACTIVITY

The first is used for general purposes like requesting permissions and getting characteristics and quantity values. The second is specifically for Category Value Sleep Analysis. And the third is for the Activity Summary.

1. Natively - HealthKit BASE

Actions:

  • Get Health Availability - Checking if HealthKit is available on a device

  • Request Permissions

    • read (e.g. HRV, RHR, SLEEP_ANALYSIS, BMI, etc.)

  • Get Permission Status - Checking if you've requested permission before (After requesting permission once, it might return YES every time, it doesn't guarantee that the user has provided access to their data cause of privacy reasons by Apple)

    • type (e.g. HRV, RHR, SLEEP_ANALYSIS, BMI, etc.)

  • Get All Characteristic Values

  • Get Statistic Quantity Values

    • data_type (Quantity Values only!) (e.g. HRV, RHR, BMI, etc.)

    • interval (DAY / WEEK / MONTH / YEAR) - means how HealthKit will return a data Daily, Weekly ... and so on.

    • start_date - The start date from which HealthKit will search and return a data

    • end_date - End date till which HealthKit will search and return a data

So basically, if you wanna get the daily steps to count for the current month you will need to select DAY interval with start_date=startofmonth & end_date=today

Events:

  • Get Permission Value Updated - Get called once the state updated

  • Get Health Availability Value Updated - Get called once the state updated

  • Request Permission Value Updated - Get called once the state updated

  • Get All Characteristics Updated - Get called once the state updated

  • Get Quantity Updated - Get called once the state updated

States:

  • Latest Get Health Availability Result

  • Latest Get Permission Result - After requesting permission once, it might return YES every time. It doesn't guarantee that the user has provided access to their data cause of privacy reasons by Apple

  • Latest Request Permission Result

  • Latest All Characteristics (CharacteristicObject)

    • Age - number

    • Sex - text (e.g. MEN / WOMAN / OTHER / NOT_SET)

    • Blood - text (e.g. AB- / AB+ / A- / B+ / B- / B+ / O- / O+ / NOT_SET)

    • Skin - text (e.g. I / II / III / IV / V / VI / NOT_SET)

    • Wheelchair - text (e.g. YES / NO / NOT_SET)

  • Latest Get Quantity Response - (QuantityStatisticsObject)

IMPORTANT! Set QuantityStatisticsObject & CharacteristicObject type from a list in the element field. No need to create a new type for this. It's already defined.

Here is a small example of setup:

2. Natively - HealthKit SLEEP

SLEEP element is used in combination with BASE. So basically, you need the BASE element to request permissions and SLEEP for requesting sleep analysis data.

Actions:

  • Get Daily Sleep Analysis

    • limit (e.g. 100) - related to a count of data that will be fetched from HealthKit and calculated. You can use any value that works best for you. To remove a limit, set a value to 0.

    • end_date - End date till which HealthKit will search and return a data

    • start_date - The start date from which HealthKit will search and return a data

Events:

  • Get Daily Sleep Analysis Updated

States:

  • Latest Get Sleep Analysis Response - (SleepAnalysisObject)

IMPORTANT! Set SleepAnalysisObject type from a list in the element field. No need to create a new type for this. It's already defined.

Here is a small example of setup:

3. Natively - HealthKit ACTIVITY

ACTIVITY element is used in combination with BASE. So basically, you need the BASE element to request permissions and ACTIVITY for requesting sleep analysis data.

Actions:

  • Get Activity Summary

    • end_date - End date till which HealthKit will search and return a data

    • start_date - The start date from which HealthKit will search and return a data

Events:

  • Get Activity Summary Updated - Get called once the state updated

States:

  • Latest Get Activity Summary Response - (ActivitySummaryObject)

IMPORTANT! Set ActivitySummaryObject type from a list in the element field. No need to create a new type for this. It's already defined.

Here is a small example of setup:

4. Natively - HealthKit WORKOUT

WORKOUT element is used in combination with BASE. So basically, you need the BASE element to request permissions and WORKOUT for requesting workouts data.

Actions:

  • Get Workouts

    • limit (e.g. 100) - related to a count of data that will be fetched from HealthKit and calculated. You can use any value that works best for you. To remove a limit, set a value to 0.

    • end_date - End date till which HealthKit will search and return a data

    • start_date - The start date from which HealthKit will search and return a data

Events:

  • Get Workout Updated

States:

  • Latest Get Workout Response - (WorkoutObject)

IMPORTANT! Set WorkoutObject type from a list in the element field. No need to create a new type for this. It's already defined.

Here is a small example of setup:

Other websites

Refer for types, and values on Bubble Doc ^

For methods, name-check the NativelyHealth object interface by following this URL

'Get Workouts' Example (SDK >=2.13.0)

// 4. Natively HealthKit Workout
const health = NativelyHealth()
// 1. Check HealthKit availability
health.available((res, err) => {
    if (err) {
        alert(err)
        return;
    }
    if (res.status) {
        // 2. Request permission
        health.requestAuthorization([], ["WORKOUTS"], (res, err) => {
            if (err) {
                alert(err)
                return;
            }
            if (res.status) { // true/false
                const today = new Date();
                const weekAgo = new Date();
                weekAgo.setDate(today.getDate() - 7);
                
                // 3. Get workouts in date range
                health.getWorkouts(today, weekAgo, (res, err) = {
                    if (err) {
                        alert(err)
                        return;
                    }
                    const result = res.result;
                    console.log(result);
                    /*
                    {
                      "endDate": 1676945111,
                      "duration": 3000, // seconds
                      "startDate": 1676945291,
                      "workoutName": "workoutName", // https://stackoverflow.com/a/71454827
                      "activeBurned": 0, // kilocal >=iOS 16
                      "basalBurned": 0, // kilocal >=iOS 16
                      "totalBurned": 0, // kilocal
                      "heartRate": 0 // count/min >=iOS 16
                    }
                    */
                })
            }
        })
    }
})

Last updated