Using Apple Health in the React Native Wrapper

React Native ==> Apple Health module

The React Native Inform SDK Wrapper offers modules which you can implement into your mobile project to power data syncing with the Apple Health health data aggregation platform.

The React Native Inform SDK Wrapper supports Healthkit for iOS and iPadOS. This document lays out the installation and use of the Apple Health integration.

Apple Health allows health and fitness apps to store and share the same on-device data within a unified ecosystem. It also offers a single place for users to control which apps can read and write health and fitness data.

Apple Health combines data from a variety of fitness and health apps along with data captured by Apple Watches (watchOS).


Installation

Apple Health has its own module in the React Native Wrapper, therefore the following modules are required to use the Apple Health integration:

  • Session (core)
  • Apple Health (healthkit)

Installation instructions are detailed in Installation.


Session

A valid session is required in order to use the Apple Health integration in the Validic Inform SDK. See Session for more information.

Record types

The record types used in the Validic Inform Mobile SDK are described in Record Types.

Record Identifiers

More information on record identifiers can be found in Record Identifiers.

Listening for InformRecord Upload

More information on record events can be found in Record Events.

Apple Health


This project integrates Apple Health with the React Native Inform SDK Wrapper to passively collect data on behalf of an end user. Validic ensures that our Mobile SDK makes use of the minimal scopes needed for our supported data types.

Availability

Not all iOS devices support HealthKit (e.g. iPads running iOS 16 or lower and other platforms such as Android). To check if HealthKit is available, Apple provides an API: [HKHealthStore isHealthDataAvailable]. For convenience, Validic provides a React Native method to check this value: ValidicHealthKit.isHealthDataAvailable(). It returns a Promise that resolves to the value returned [HKHealthStore isHealthDataAvailable] and false for every other platform.

ValidicHealthKit.isHealthDataAvailable()
  .then(healthDataIsAvailable => {
    if (healthDataIsAvailable) {
      console.log('HealthKit is available!');
    }
    else {
      console.log('HealthKit is not available :(');
    }
  });

// async/await
try {
  const available = await ValidicHealthKit.isHealthDataAvailable();
  console.log("HealthKit is available:" + available);
} catch(error) {
  console.error(error);
}

Subscriptions

To subscribe to HealthKit sample types:

Current Subscriptions

To retrieve the list of Sample Types currently being observed

ValidicHealthKit.getCurrentSubscriptions()
  .then(subscriptions => {
    console.log(JSON.strigify(subscriptions)); // ["HKQuantityTypeIdentifierStepCount"]
  })
  .catch(error => console.error(error));

// async/await
try {
  const subscriptions = await ValidicHealthKit.getCurrentSubscriptions();
  console.log(JSON.stringify(subscriptions)); // ["HKQuantityTypeIdentifierStepCount"]
} catch (e) {
  console.error(e);
}

Set Subscriptions

Calling ValidicHealthKit.setSubscriptions(subscriptions) will replace any existing subscriptions, so it is important to always pass all of the subscriptions desired each time the method is called. The function accepts an array of strings mapping to HealthKit sample type identifiers (e.g. "HKQuantityTypeIdentifierStepCount") and returns a Promise that resolves after permissions have been granted by the end user and the subscriptions have been set up.

To get a list of the currently subscribed data types use the method described in Current Subscriptions.

ValidicHealthKit.setSubscriptions([ValidicHealthKit.SampleTypes.HKQuantityTypeIdentifierStepCount])
  .then(() => {
    console.log("Subscribed to Steps");
  })
  .catch(error => console.error(error));

// async/await
try{
  await ValidicHealthKit.setSubscriptions([ValidicHealthKit.SampleTypes.HKQuantityTypeIdentifierStepCount]);
  console.log("Subscribed to steps");
} catch (e) {
  console.error(e);
}

Fetching Historical Data

To fetch historical Summary data use the fetchHistory function. The maximum amount of data that can be fetched is 180 days in the past.

  let start = new Date()
  let end = new Date()
  start.setDate(end.getDate()-29)
  ValidicHealthKit.fetchHistory({
    historicalSets: [ValidicHealthKit.HistoricalSets.HistoricalSetRoutine],
    from: start.toISOString(),
    to: end.toISOString()
  })
  .then(summary => {
    console.log(JSON.stringify(summary));
  })
  .catch(error => {
    console.error(error);
  });

  // async/await
  try {
    const summary = await ValidicHealthKit.fetchHistory({
      historicalSets: [ValidicHealthKit.HistoricalSets.HistoricalSetRoutine],
      from: start.toISOString(),
      to: end.toISOString()
    });
    console.log(JSON.stringify(summary));
  } catch (e) {
    console.error(e);
  }


Apple Health Events

An event will be passed to ValidicHealthKitEvents every time HealthKit processes new records. The event contains a summary of the number of records collected per SummaryType.

ValidicHealthKitEvents.addListener('validic:healthkit:onrecords', (summary) => {
    console.log(JSON.stringify(summary)); // {"biometrics":1, "summary":1}
});

Listeners should be removed as soon as they are no longer needed, or when the component observing them will be unmounted.

componentWillUnmount() {
    ValidicHealthKitEvents.removeAllListeners('validic:healthkit:onrecords');
}