Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] Gathering/observing data in the background and foreground #65

Open
JulianKingman opened this issue Nov 21, 2018 · 3 comments
Open

Comments

@JulianKingman
Copy link

JulianKingman commented Nov 21, 2018

This feature will add background observers for an arbitrary number of types of data. Below are my notes and ideas for how to implement this. Your comments and ideas are welcome.

I propose the following:

  1. The app can be initialized with an additional option: observe
    E.g:
let options = {
  permissions: {
    read: ["Height", "Weight", "StepCount", "DateOfBirth", "BodyMassIndex"],
    write: ["Weight", "StepCount", "BodyMassIndex"],
  },
  observers: [
    { type: "StepCount" },
    { type: "Weight" }
  ]
};
AppleHealthKit.initHealthKit(options);
  1. Observers (HKObserverQuery) run in the background, saving data to AsyncStorage, perhaps to the RNAppleHealthkit key. To retrieve it later you could run:
const healthKitData = await AsyncStorage.getItem('RNAppleHealthkit');
const steps = healthKitData.StepCount;
// `steps` might contains something like:
// [
//    { date: '1 1 2019', value: 10000}
// ]
  1. To make use of this most effectively, use react-native-background-fetch
BackgroundFetch.configure({
  minimumFetchInterval: 15, // <-- minutes (15 is minimum allowed)
}, () => {

  // Retrieve data
  const healthKitData = await AsyncStorage.getItem('RNAppleHealthkit');

  // Stop if there isn't any
  if (!healthKitData)  {
    BackgroundFetch.finish(BackgroundFetch.FETCH_RESULT_NO_DATA);
  }

  // Get steps
  const steps = healthKitData.StepCount;

  // Upload them
  await fetch('http://placetouploadsteps.com/steps', { method: 'POST', body: JSON.stringify({ steps });

  // No need to waste storage
  AsyncStorage.removeItem('RNAppleHealthkit');

  // Finish
  BackgroundFetch.finish(BackgroundFetch.FETCH_RESULT_NEW_DATA);

}, (error) => {
  console.log("[js] RNBackgroundFetch failed to start");
});
  1. Event triggers still work, if your app is in the foreground (but with a simpler API)
    Per https://github.com/terrillo/rn-apple-healthkit/blob/master/docs/initStepCountObserver().md
import { EventEmitter } from 'rn-apple-healthkit';
EventEmitter.addListener(
  'change:StepCount',
  (evt) => {
    const steps = evt.data;
  }
);
@JulianKingman JulianKingman changed the title [RFC] Gathering data in the background [RFC] Gathering/observing data in the background and foreground Nov 21, 2018
@EJohnF
Copy link
Contributor

EJohnF commented Nov 22, 2018

I don't have time to find related page in healthKit docs, but I remember that it isn't possible to use react-native-background-fetch to get healthKit data while app in Background. We have to use a built-in HK mechanism for it.

@JulianKingman
Copy link
Author

JulianKingman commented Nov 22, 2018

Yes, that’s true of getting the data. That’s why in step 2 it retrieves the data in the background (using healthkit’s HKOvserverQuery, the built-in mechanism) and stores it to AsyncStorage, because (I’m pretty sure) AsyncStorage is available with background fetch.

@adcuz
Copy link

adcuz commented Dec 17, 2018

AFAIK background fetch doesn't run if the device is locked.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants