Configure Background
Setting background functions allows us to send new information as we get notified. This helps to resend that information to you through your webhook previously configured in the ROOK Portal.
Enable background sync of data for iOS
To configure background upload you need to follow the steps bellow:
- Add health kit to your project and enable background delivery.
- Add Background modes and enable Background fetch.
In the app delegate of your app add the setBackListeners
method in didFinishLaunchingWithOptions function.
#import "AppDelegate.h"
#import "RookSDK/RookSDK-Swift.h"
#import <React/RCTBundleURLProvider.h>
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.moduleName = @"RookSdkAppleHealthExample";
// You can add your custom initial props in the dictionary below.
// They will be passed down to the ViewController used by React Native.
self.initialProps = @{};
[[RookBackGroundSync shared] setBackListeners];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
#else
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
}
@end
Next, we need to enable or indicate to the SDK to stay listening for new notifications. We recommend enabling this in your dashboard to ensure that the user activates this function, as shown below.
/* eslint-disable react-hooks/exhaustive-deps */
import React, { useEffect, useState } from "react";
import { Button } from "react-native";
import { Platform, StyleSheet, Text, View } from "react-native";
import {
useRookAppleHealth,
useRookEvents,
useRookSummaries,
} from "react-native-rook-sdk";
export const Dashboard = () => {
const [syncing, setSyncing] = useState(false);
const { ready, enableBackGroundUpdates } = useRookAppleHealth();
useEffect(() => {
if (ready && Platform.OS === "ios") {
enableBackGroundUpdates();
}
}, [ready]);
return (
<View style={styles.container}>
<Text style={styles.message}>Dashboard</Text>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
paddingHorizontal: 20,
},
message: {
fontSize: 18,
marginBottom: 20,
textAlign: "center",
color: "white",
},
extra: {
marginTop: 50,
},
});
Enable Background sync of data for Android
To automatically sync health data, use the scheduleYesterdaySync
function during your app's initialization phase. We highly recommend checking and saving whether the user has explicitly given you permission to sync data automatically. In this example, we use @react-native-async-storage/async-storage
to achieve this.
First we need to request permissions, please refer to previous steps if you don't have do it already.
import React, { useEffect } from "react";
import { View } from "react-native";
import AsyncStorage from "@react-native-async-storage/async-storage";
import { useRookSyncConfiguration } from "react-native-rook-sdk";
function MyComponent() {
const { scheduleAndroidYesterdaySync } = useRookConfiguration();
useEffect(() => {
tryToEnableYesterdaySync();
}, []);
const tryToEnableYesterdaySync = async () => {
console.log("Attempting to enable yesterday sync...");
try {
const userAcceptedYesterdaySync = await AsyncStorage.getItem(
"ACCEPTED_YESTERDAY_SYNC"
);
const accepted = userAcceptedYesterdaySync === "true";
if (accepted) {
console.log("User accepted yesterday sync");
await scheduleAndroidYesterdaySync("oldest");
} else {
console.log("User did not accept yesterday sync");
}
} catch (error) {
console.error("Error retrieving data from AsyncStorage:", error);
}
};
return <View>{/* Your UI components here */}</View>;
}
export default MyComponent;
RookYesterdaySyncPermissions
scheduleYesterdaySync
Requires 2 types of permissions
- Android
- POST_NOTIFICATIONS
- FOREGROUND_SERVICE
- FOREGROUND_SERVICE_HEALTH
- ACTIVITY_RECOGNITION
- Health Connect
- SLEEP
- PHYSICAL
- BODY
To request or check both types of permissions use the you have to request permissions of health connect with useRookSyncPermissions().requestPermissions()
in order to access to the health connect data and useRookSyncPermissions().requestAndroidBackgroundPermissions()
to have access to the background services
Customizing the foreground service notification
To sync health data automatically a Foreground Service is used, this service requires a notification to be displayed until the synchronization finishes.
To use your own resources you need to reference them in the AndroidManifest.xml file:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<meta-data
android:name="io.tryrook.service.notification.SYNC_ICON"
android:resource="@drawable/my_custom_icon"/>
<meta-data
android:name="io.tryrook.service.notification.SYNC_TITLE"
android:resource="@string/my_custom_title"/>
<meta-data
android:name="io.tryrook.service.notification.SYNC_CONTENT"
android:resource="@string/my_custom_content"/>
</application>
</manifest>
Starting on Android 13 (SDK 33) this notification can be dismissed without finishing the service associated with it, then the service will be displayed in the active apps section (This may vary depending on device brand).
Launch/Stop conditions
scheduleYesterdaySync
won't start or will stop if one the following conditions are meet:
- The device battery is low
- The device storage is low
- The device is not connected to the internet
- The user hasn't granted Android Permissions (POST_NOTIFICATIONS, FOREGROUND_SERVICE, FOREGROUND_SERVICE_HEALTH)
- The device has previously exceeded the Health Connect request quota and the recovery timestamp hasn't been meet
- The user hasn't granted Health Connect Permissions (SLEEP, PHYSICAL, BODY)
- The most recent request exceeded the Health Connect request quota
- The userID hasn't been configured
- There is an error initializing the SDK
Health Connect request quota
To maintain optimal system stability and performance, Health Connect imposes rate limits on client connections to the Health Connect API.
It is important for you to understand that every data type in rook-sdk is constructed of multiple health variables like heart rate, steps count, hydration, etc. So when a Sleep Summary is extracted there are multiple calls made to the Health Connect API, and whereas in the last months our efforts have been focused on optimizing and reducing the number of API call required for each data type it's still possible for that limit to be reached, especially while doing multiple extraction in a short amount of time.
Depending on the sync type you chose you must have the following things in mind:
Request quota when syncing data manually
- Extract summaries once daily: Since summaries collect health data from a previous day, there's no need to extract them more than once per day.
- Use what you already have: If you are extracting Physical Events you don’t need to extract Heart Rate Events ( Physical) or Oxygenation Events (Physical) as these are already included in the PhysicalEvent object.
- Only sync the relevant health data for you use case: If you are not interested on individual events and only want to
sync the summary of a specific date, just use the
sync
functions inuseRookSyncSummaries
. - If you already reached the request quota avoid calling any
sync
function for the next hours so your quota can be recovered.
Request quota when syncing data automatically
scheduleYesterdaySync
already takes care of practically all issues and limitations of Health Connect. When the
quota is reached, all pending syncs are canceled, and a recovery timestamp is created. Pending syncs will not resume
until the user re-opens the app after a few hours.
Frequency of syncing
Health structure | Frequency | Historical range |
---|---|---|
Sleep Summary | Each time scheduleYesterdaySync is called | 29 days in the past until yesterday |
Body Summary | Each time scheduleYesterdaySync is called | 29 days in the past until yesterday |
Physical Summary | Each time scheduleYesterdaySync is called | 29 days in the past until yesterday |
Physical Activity | Each time scheduleYesterdaySync is called | 29 days in the past until today |
Steps | Each time scheduleYesterdaySync is called | Today |