Skip to main content

Get started

Official React Native SDK for iHealth Bluetooth health devices.

@ihealth/ihealthlibrary-react-native v2 fully supports the React Native New Architecture (TurboModules) and remains compatible with the old Bridge architecture.

info

React Native device pages in this docs site still contain many legacy DeviceEventEmitter examples. For v2, please use the NativeEventEmitter pattern shown on this page. Device APIs such as startMeasure(), getOfflineData(), and disconnect() remain the same.

Requirements​

  • React Native >= 0.76.0
  • iOS 12.0+
  • Android 7.0+ (API 24+)

Installation​

npm install @ihealth/ihealthlibrary-react-native
# or
yarn add @ihealth/ihealthlibrary-react-native

iOS setup​

Install pods​

cd ios && pod install

Add Bluetooth permissions​

Add the following entries to Info.plist:

<key>NSBluetoothAlwaysUsageDescription</key>
<string>Required to connect to iHealth devices</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>Required to connect to iHealth devices</string>

Enable the New Architecture​

For React Native 0.76+, enabling the New Architecture is recommended.

Update ios/Podfile.properties.json:

{
"newArchEnabled": "true"
}

Then run pod install again.

iOS license note​

iOS does not require SDK license authentication.

Android setup​

Add Bluetooth permissions​

Add the following to android/app/src/main/AndroidManifest.xml:

<!-- Bluetooth for Android 11 and below -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

<!-- Bluetooth for Android 12+ -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

Request runtime permissions​

import { PermissionsAndroid, Platform } from 'react-native';

export async function requestBluetoothPermissions() {
if (Platform.OS !== 'android') return true;

const permissions =
Platform.Version >= 31
? [
PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN,
PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT,
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
]
: [PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION];

const result = await PermissionsAndroid.requestMultiple(permissions);
return Object.values(result).every(
value => value === PermissionsAndroid.RESULTS.GRANTED
);
}

Authenticate the SDK license​

Android requires a .pem license file from iHealth.

  1. Sign up at dev.ihealthlabs.com.
  2. Create your app and obtain the .pem file from the developer portal.
  3. Place the file under android/app/src/main/assets/.
  4. Call sdkAuthWithLicense() once during app startup.
import { iHealthDeviceManagerModule } from '@ihealth/ihealthlibrary-react-native';

iHealthDeviceManagerModule.sdkAuthWithLicense('your_license_file.pem');

Enable the New Architecture​

Update android/gradle.properties:

newArchEnabled=true

Quick start​

The example below shows a complete scan, connect, and measure flow using the BP5S blood pressure monitor.

import React, { useEffect, useState } from 'react';
import { Button, NativeEventEmitter, NativeModules, Text, View } from 'react-native';
import {
BP5SModule,
iHealthDeviceManagerModule,
} from '@ihealth/ihealthlibrary-react-native';

export default function BP5SScreen() {
const [devices, setDevices] = useState([]);
const [connectedMac, setConnectedMac] = useState(null);
const [result, setResult] = useState('');

useEffect(() => {
const managerEmitter = new NativeEventEmitter(
NativeModules.iHealthDeviceManagerModule
);

const onScan = managerEmitter.addListener(
iHealthDeviceManagerModule.Event_Scan_Device,
event => setDevices(prev => [...prev, event])
);

const onConnected = managerEmitter.addListener(
iHealthDeviceManagerModule.Event_Device_Connected,
event => setConnectedMac(event.mac)
);

const onDisconnect = managerEmitter.addListener(
iHealthDeviceManagerModule.Event_Device_Disconnect,
() => setConnectedMac(null)
);

return () => {
onScan.remove();
onConnected.remove();
onDisconnect.remove();
};
}, []);

useEffect(() => {
const bp5sEmitter = new NativeEventEmitter(NativeModules.BP5SModule);

const onData = bp5sEmitter.addListener(BP5SModule.Event_Notify, event => {
setResult(JSON.stringify(event));
});

return () => onData.remove();
}, []);

return (
<View>
<Button
title="Scan"
onPress={() => {
setDevices([]);
iHealthDeviceManagerModule.startDiscovery(iHealthDeviceManagerModule.BP5S);
}}
/>

{devices.map(device => (
<Button
key={device.mac}
title={`Connect ${device.mac}`}
onPress={() =>
iHealthDeviceManagerModule.connectDevice(
device.mac,
iHealthDeviceManagerModule.BP5S
)
}
/>
))}

{connectedMac && (
<Button
title="Start Measure"
onPress={() => BP5SModule.startMeasure(connectedMac)}
/>
)}

<Text>{result}</Text>
</View>
);
}

Event listening in v2​

Required listener pattern​

v2.0.0 is a breaking change for event subscriptions: use NativeEventEmitter, not DeviceEventEmitter.

import { NativeEventEmitter, NativeModules } from 'react-native';
import { BP5SModule } from '@ihealth/ihealthlibrary-react-native';

useEffect(() => {
const emitter = new NativeEventEmitter(NativeModules.BP5SModule);

const listener = emitter.addListener(BP5SModule.Event_Notify, event => {
console.log(event);
});

return () => listener.remove();
}, []);

Common mistakes​

  • Do not use DeviceEventEmitter.
  • Do not create the emitter at module top level.
  • Create the emitter after the app is mounted, usually inside useEffect.
  • Always remove listeners on unmount.

NativeModules mapping​

Use the matching native module when creating the emitter:

  • iHealthDeviceManagerModule -> NativeModules.iHealthDeviceManagerModule
  • BP5SModule -> NativeModules.BP5SModule
  • PO3Module -> NativeModules.PO3Module
  • HS2SModule -> NativeModules.HS2SModule
  • BG5SModule -> NativeModules.BG5SModule
  • AM6Module -> NativeModules.AM6Module
  • BTMModule -> NativeModules.BTMModule

Device management​

Scan for devices​

import { iHealthDeviceManagerModule } from '@ihealth/ihealthlibrary-react-native';

iHealthDeviceManagerModule.startDiscovery(iHealthDeviceManagerModule.BP5S);
iHealthDeviceManagerModule.stopDiscovery();

Common device type constants include:

  • iHealthDeviceManagerModule.BP5
  • iHealthDeviceManagerModule.BP5S
  • iHealthDeviceManagerModule.BP7
  • iHealthDeviceManagerModule.BP7S
  • iHealthDeviceManagerModule.BP3L
  • iHealthDeviceManagerModule.KN550
  • iHealthDeviceManagerModule.PO3
  • iHealthDeviceManagerModule.PO1
  • iHealthDeviceManagerModule.HS2S
  • iHealthDeviceManagerModule.BG5S
  • iHealthDeviceManagerModule.BG1A
  • iHealthDeviceManagerModule.BG1S
  • iHealthDeviceManagerModule.AM3S
  • iHealthDeviceManagerModule.AM4
  • iHealthDeviceManagerModule.AM5
  • iHealthDeviceManagerModule.AM6
  • iHealthDeviceManagerModule.BTM
  • iHealthDeviceManagerModule.NT13B
  • iHealthDeviceManagerModule.TS28B
  • iHealthDeviceManagerModule.PT3SBT

Connect and disconnect​

iHealthDeviceManagerModule.connectDevice(mac, iHealthDeviceManagerModule.BP5S);
iHealthDeviceManagerModule.disconnectDevice(mac, iHealthDeviceManagerModule.BP5S);

Device manager events​

Listen on NativeModules.iHealthDeviceManagerModule for:

  • Event_Scan_Device
  • Event_Scan_Finish
  • Event_Device_Connected
  • Event_Device_Connect_Failed
  • Event_Device_Disconnect
  • Event_Authenticate_Result on Android only

Supported devices​

React Native v2 supports the following device families:

  • Blood pressure: BP5, BP5S, BP3L, BP7, BP7S, KN-550BT
  • Blood oxygen: PO3, PO1
  • Scales: HS2S, HS2S Pro, HS4S, HS6
  • Blood glucose: BG5S, BG5, BG1, BG1A, BG1S
  • Activity trackers: AM3S, AM4, AM5, AM6
  • Thermometers: BTM, TS28B, NT13B, PT3SBT

See the left sidebar for per-device API details.

Migration from v1.x​

If you are upgrading from React Native SDK v1.x, the main code change is the event listener migration:

// v1.x
import { DeviceEventEmitter } from 'react-native';
DeviceEventEmitter.addListener(BP5SModule.Event_Notify, handler);

// v2.x
import { NativeEventEmitter, NativeModules } from 'react-native';
const emitter = new NativeEventEmitter(NativeModules.BP5SModule);
emitter.addListener(BP5SModule.Event_Notify, handler);

Your device API calls generally do not need to change.

FAQ​

I can scan and connect, but I never receive measurement data​

Make sure the NativeEventEmitter is created inside useEffect rather than at module top level or too early in component initialization.

Android calls have no effect​

Check that:

  • the .pem file is present in android/app/src/main/assets/
  • sdkAuthWithLicense() is called once on app startup
  • Bluetooth runtime permissions were granted