Skip to content

Commit

Permalink
feat: Know the task's state with isRunning() method (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
Rapsssito committed Feb 20, 2020
1 parent 88d3933 commit d3954dd
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 31 deletions.
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,19 @@ To use this library you need to ensure you are using the correct version of Reac
```js
import BackgroundService from 'react-native-background-actions';

// You can do anything in your task such as network requests, timers and so on,
// as long as it doesn't touch UI. Once your task completes (i.e. the promise is resolved),
// React Native will go into "paused" mode (unless there are other tasks running,
// or there is a foreground app).
const veryIntensiveTask = async (taskDataArguments) => {
// Example of an infinite loop task
const { delay } = taskDataArguments;
// You can do anything in your task such as network requests, timers and so on, as long as it doesn't touch UI.
// Once your task completes (i.e. the promise is resolved), React Native will go into "paused" mode (unless
// there are other tasks running, or there is a foreground app).
await new Promise((resolve) => {
for (let i = 0; BackgroundService.isRunning(); i++) {
console.log(i);
await sleep(delay);
}
});
};

const options = {
Expand Down
32 changes: 29 additions & 3 deletions __tests__/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ import { Platform, AppRegistry } from 'react-native';
import BackgroundActions from '../index';
import RNBackgroundActionsModule from '../RNBackgroundActionsModule';

// Flush promises
const flushPromises = () => new Promise(setImmediate);

Platform.OS = 'android';

AppRegistry.registerHeadlessTask = jest.fn((taskName, task) => task()());
AppRegistry.registerHeadlessTask = jest.fn(async (taskName, task) => task()());

const defaultOptions = {
taskName: 'Example',
Expand All @@ -20,13 +23,18 @@ const defaultOptions = {
};

test('stop-empty', async () => {
expect(BackgroundActions.isRunning()).toBe(false);
RNBackgroundActionsModule.stop.mockClear();
await BackgroundActions.stop();
expect(RNBackgroundActionsModule.stop).toHaveBeenCalledTimes(1);
expect(BackgroundActions.isRunning()).toBe(false);
});

test('start-android', async () => {
const defaultTask = jest.fn(async () => {});
let promiseFinish = () => {};
const defaultTask = jest.fn(
async () => await new Promise((resolve) => (promiseFinish = resolve))
);
Platform.OS = 'android';
AppRegistry.registerHeadlessTask.mockClear();
RNBackgroundActionsModule.start.mockClear();
Expand All @@ -35,10 +43,17 @@ test('start-android', async () => {
expect(defaultTask).toHaveBeenCalledWith(defaultOptions.parameters);
expect(AppRegistry.registerHeadlessTask).toHaveBeenCalledTimes(1);
expect(RNBackgroundActionsModule.start).toHaveBeenCalledTimes(1);
expect(BackgroundActions.isRunning()).toBe(true);
promiseFinish();
await flushPromises();
expect(BackgroundActions.isRunning()).toBe(false);
});

test('start-ios', async () => {
const defaultTask = jest.fn(async () => {});
let promiseFinish = () => {};
const defaultTask = jest.fn(
async () => await new Promise((resolve) => (promiseFinish = resolve))
);
AppRegistry.registerHeadlessTask.mockClear();
Platform.OS = 'ios';
RNBackgroundActionsModule.start.mockClear();
Expand All @@ -47,10 +62,21 @@ test('start-ios', async () => {
expect(defaultTask).toHaveBeenCalledWith(defaultOptions.parameters);
expect(AppRegistry.registerHeadlessTask).toHaveBeenCalledTimes(0);
expect(RNBackgroundActionsModule.start).toHaveBeenCalledTimes(1);
expect(BackgroundActions.isRunning()).toBe(true);
promiseFinish();
await flushPromises();
expect(BackgroundActions.isRunning()).toBe(false);
});

test('stop', async () => {
let promiseFinish = () => {};
const defaultTask = jest.fn(
async () => await new Promise((resolve) => (promiseFinish = resolve))
);
await BackgroundActions.start(defaultTask, defaultOptions);
RNBackgroundActionsModule.stop.mockClear();
await BackgroundActions.stop();
expect(RNBackgroundActionsModule.stop).toHaveBeenCalledTimes(1);
expect(BackgroundActions.isRunning()).toBe(false);
promiseFinish(); // Clear the promise
});
16 changes: 5 additions & 11 deletions examples/backgroundExample/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,10 @@ import {
} from 'react-native';
import {Header, Colors} from 'react-native/Libraries/NewAppScreen';

import EventEmitter from 'events';
import BackgroundJob from 'react-native-background-actions';

const sleep = time => new Promise(resolve => setTimeout(() => resolve(), time));

const eventEmitter = new EventEmitter();

const taskRandom = async taskData => {
if (Platform.OS === 'ios') {
console.warn(
Expand All @@ -34,12 +31,9 @@ const taskRandom = async taskData => {
);
}
await new Promise(async resolve => {
let keepRunning = true;
// We add a listener to stop running
eventEmitter.addListener('close', () => (keepRunning = false));
// For loop with a delay
const {delay} = taskData.arguments;
for (let i = 0; keepRunning; i++) {
const {delay} = taskData;
for (let i = 0; BackgroundJob.isRunning(); i++) {
console.log('Runned -> ', i);
await sleep(delay);
}
Expand All @@ -55,13 +49,13 @@ const options = {
type: 'mipmap',
},
color: '#ff00ff',
arguments: {
parameters: {
delay: 1000,
},
};

class App extends React.Component {
playing = false;
playing = BackgroundJob.isRunning();

/**
* Toggles the background task
Expand All @@ -78,7 +72,7 @@ class App extends React.Component {
}
} else {
console.log('Stop background service');
eventEmitter.emit('close');
await BackgroundJob.stop();
}
};
render() {
Expand Down
3 changes: 1 addition & 2 deletions examples/backgroundExample/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@
"pods": "cd ios && pod install"
},
"dependencies": {
"events": "^3.1.0",
"react": "16.9.0",
"react-native": "0.61.5",
"react-native-background-actions": "^1.1.0"
"react-native-background-actions": "https://github.com/Rapsssito/react-native-background-actions#feat-isRunning"
},
"devDependencies": {
"@babel/core": "^7.8.3",
Expand Down
12 changes: 3 additions & 9 deletions examples/backgroundExample/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2373,11 +2373,6 @@ eventemitter3@^3.0.0:
resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7"
integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==

events@^3.1.0:
version "3.1.0"
resolved "https://registry.npmjs.org/events/-/events-3.1.0.tgz#84279af1b34cb75aa88bf5ff291f6d0bd9b31a59"
integrity sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==

exec-sh@^0.3.2:
version "0.3.4"
resolved "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz#3a018ceb526cc6f6df2bb504b2bfe8e3a4934ec5"
Expand Down Expand Up @@ -5037,10 +5032,9 @@ react-is@^16.8.1, react-is@^16.8.4, react-is@^16.9.0:
resolved "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz#2cc0fe0fba742d97fd527c42a13bec4eeb06241c"
integrity sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==

react-native-background-actions@^1.1.0:
version "1.1.0"
resolved "https://registry.npmjs.org/react-native-background-actions/-/react-native-background-actions-1.1.0.tgz#24b543e494f12ff4320e0615799b6bc237012a83"
integrity sha512-H7cNZksbKXELvYqZXHJ0U3DUYBL6pHjB1hPyR1IWMaPcu2j+UkjK/Xwd89Cv74hqgfWIusBUjVTFAmUewalHtA==
"react-native-background-actions@https://github.com/Rapsssito/react-native-background-actions#feat-isRunning":
version "2.0.0"
resolved "https://github.com/Rapsssito/react-native-background-actions#3fd1ed62329451417387c1b38fd39f87702f5008"

react-native@0.61.5:
version "0.61.5"
Expand Down
22 changes: 19 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,22 @@ import RNBackgroundActions from './RNBackgroundActionsModule';
* color?: string,
* parameters?: any}} BackgroundTaskOptions
*/
class BackgroundTimer {
class BackgroundServer {
constructor() {
this._runnedTasks = 0;
this._stopTask = () => {};
this._isRunning = false;
}

/**
* Returns if the current background task is running.
*
* It returns `true` if `start()` has been called and the task has not finished.
*
* It returns `false` if `stop()` has been called, **even if the task has not finished**.
*/
isRunning() {
return this._isRunning;
}

/**
Expand All @@ -30,6 +42,7 @@ class BackgroundTimer {
await RNBackgroundActions.start(finalOptions);
finalTask();
}
this._isRunning = true;
}

/**
Expand All @@ -41,7 +54,7 @@ class BackgroundTimer {
return async () => {
await new Promise((resolve) => {
self._stopTask = resolve;
task(parameters).then(() => resolve());
task(parameters).then(() => self.stop());
});
};
}
Expand All @@ -62,7 +75,10 @@ class BackgroundTimer {
async stop() {
this._stopTask();
await RNBackgroundActions.stop();
this._isRunning = false;
}
}

export default new BackgroundTimer();
const backgroundServer = new BackgroundServer();

export default backgroundServer;

0 comments on commit d3954dd

Please sign in to comment.