1
1
# react-native-background-task
2
2
3
- ** WORK IN PROGRESS / NOT YET READY FOR PRODUCTION USE**
3
+ [ ![ npm version] ( https://img.shields.io/npm/v/react-native-background-task.svg )] ( https://www.npmjs.com/package/react-native-background-task )
4
+ [ ![ license] ( https://img.shields.io/github/license/jamesisaac/react-native-background-task.svg )] ( https://opensource.org/licenses/MIT )
5
+ [ ![ npm downloads] ( https://img.shields.io/npm/dm/react-native-background-task.svg )] ( https://www.npmjs.com/package/react-native-background-task )
4
6
5
- Periodic background tasks for React Native apps, cross-platform (iOS and Android), which run even when the app is closed.
7
+ Periodic background tasks for React Native apps, cross-platform (iOS and
8
+ Android), which run even when the app is closed.
6
9
7
- This builds on top of the native modules provided by the following two libraries:
10
+ This library allows the scheduling of a single periodic task, which executes
11
+ when the app is in the background or closed, no more frequently than every 15
12
+ minutes. Network, AsyncStorage etc can be used (anything except UI), so
13
+ perfect for things like a background data sync for offline support.
8
14
9
- - ** iOS** : [ react-native-background-fetch] ( https://github.com/transistorsoft/react-native-background-fetch ) , which uses the iOS-specific ` Background Fetch ` technique.
10
- - ** Android** : [ react-native-background-job] ( https://github.com/vikeri/react-native-background-job ) , which provides a job scheduler on RN's built-in [ Headless JS] ( https://facebook.github.io/react-native/docs/headless-js-android.html ) (Android only).
15
+ Behind the scenes, this library takes a different approach with each platform:
11
16
12
- To achieve a unified API, this package exposes the lowest common denominator (e.g. only support for a single task, even though Android can support multiple).
17
+ - ** Android** : A native implementation, which provides scheduling on top of
18
+ RN's built-in [ Headless JS] ( https://facebook.github.io/react-native/docs/headless-js-android.html )
19
+ (Android only).
20
+ - Min API level: 16 (Android 4.1).
21
+ - ** iOS** : [ react-native-background-fetch] ( https://github.com/transistorsoft/react-native-background-fetch ) ,
22
+ which uses the iOS-specific ` Background Fetch ` technique.
13
23
14
- For more per-platform flexibility, those libraries should be used individually.
24
+ To achieve a unified API, this library exposes the lowest common denominator
25
+ (e.g. only support for a single task, even though Android can support multiple).
26
+
27
+ For more per-platform flexibility, there are other platform-specific libraries
28
+ with more granular customisation.
15
29
16
30
## Installation
17
31
18
32
``` bash
19
- $ npm install --save react-native-background-task
33
+ $ npm install react-native-background-task --save
20
34
```
35
+
36
+ ### Android
37
+
38
+ 1 . The linking of the library can be done automatically by running:
39
+
40
+ ``` bash
41
+ $ react-native link react-native-background-task
42
+ ```
43
+
44
+ 2 . One manual step is still needed - in your project file
45
+ ` android/app/src/main/java/myapp/MainApplication.java ` , add the following to
46
+ the end of the ` onCreate() ` method:
47
+
48
+ ``` java
49
+ BackgroundTaskPackage . useContext(this );
50
+ ```
51
+
52
+ ### iOS
21
53
22
- * ** iOS** : Follow native iOS module installation instructions from
23
- [ react-native-background-fetch] ( https://github.com/transistorsoft/react-native-background-fetch )
24
- * ** Android** : Follow native Android module installation instructions from
25
- [ react-native-background-job] ( https://github.com/vikeri/react-native-background-job )
26
- * Recommended version: v1.1.0 (API has changed as of v1.1.3)
54
+ For iOS support, this library relies on version 2.0.x of
55
+ [ react-native-background-fetch] ( https://github.com/transistorsoft/react-native-background-fetch )
56
+ which can be installed as follows:
57
+
58
+ ``` bash
59
+ $ npm install
[email protected] --save
60
+ $ react-native link react-native-background-fetch
61
+ ```
62
+
63
+ This library will behave correctly on iOS as long as ` react-native-background-fetch `
64
+ is installed alongside it, and has been linked with your project.
27
65
28
66
## API
29
67
30
- ### ` register (task, options )`
68
+ ### ` define (task)`
31
69
32
- Define the task that this module should be executing.
70
+ Define the JS code that this module should be executing.
33
71
34
- - Will overwrite any previously registered task.
35
- - Should be called at the root of your main app entrypoint file.
36
- - Should ` console.error ` if it can't register the task
72
+ - Should be called at the top level of your JS, ** not** inside a component.
73
+ This is because in headless mode no components are mounted, but the code
74
+ still needs to be accessible.
75
+ - Will overwrite any previously defined task.
37
76
38
77
Parameters:
39
78
40
- * ** ` task ` ** : ** required** ` () => void ` - Function to be executed in the background
41
- * ** ` options ` ** : ` ?object ` - Any configuration you want to be set with
79
+ - ** ` task ` ** : ** required** ` () => void ` - Function to be executed in the background
80
+
81
+ ### ` schedule(options) `
82
+
83
+ Specify the scheduling options for the task, and register it with the
84
+ platform's scheduler.
85
+
86
+ - Should be called from inside a component (e.g. your App's
87
+ ` componentDidMount ` ). This is to avoid double-scheduling when the task
88
+ launches in headless mode.
89
+ - Will ` console.warn ` if the device is task was unable to be scheduled.
90
+
91
+ Parameters:
92
+
93
+ - ** ` options? ` ** : ` Object ` - Any configuration you want to be set with
42
94
the task. Note that most of these will only work on one platform.
43
95
44
- * ** ` period ` ** ` number ` - (Android only) Desired number of seconds between each
96
+ - ** ` period? ` ** ` number ` - (Android only) Desired number of seconds between each
45
97
execution of the task. Even on Android, the OS will only take this as a
46
- recommendation, and will likely enforce a minimum of 15 minutes (similar to
47
- iOS). Default is 900 (15 minutes)
48
- * ** ` timeout ` ** ` number ` - (Android only) Number of seconds the task will have
98
+ recommendation, and will enforce a minimum of 15 minutes (similar to iOS).
99
+ Default is 900 (15 minutes)
100
+ - ** ` timeout? ` ** ` number ` - (Android only) Number of seconds the task will have
49
101
to execute. iOS has a hardcoded limit of 30 seconds. Default 30 seconds.
50
102
103
+ ### ` finish() `
104
+
105
+ ** Must be called at the end of your task** to indicate to the OS that it's
106
+ finished. (Only required on iOS, no-op on Android).
107
+
51
108
### ` cancel() `
52
109
53
- Cancels any currently registered task.
110
+ Cancels any currently scheduled task.
54
111
55
- ### ` finish() `
112
+ ### ` statusAsync() `
113
+
114
+ Query the status of background tasks within this app. Returns a Promise with
115
+ an object of the following shape:
116
+
117
+ - ** ` available ` ** ` boolean ` - Whether background tasks are available to the app.
118
+ On Android this will always be true, but on iOS background tasks could be
119
+ blocked (see [ UIBackgroundRefreshStatus] ( https://developer.apple.com/documentation/uikit/uibackgroundrefreshstatus ) ).
120
+ - ** ` unavailableReason? ` ** ` string ` - If unavailable, gives the reason:
121
+ - ** ` BackgroundTask.UNAVAILABLE_DENIED ` ** - The user explicitly disabled
122
+ background behavior for this app or for the whole system.
123
+ - ** ` BackgroundTask.UNAVAILABLE_RESTRICTED ` ** - Background updates
124
+ unavailable and can't be enabled by the user (e.g. parental controls).
125
+
126
+ ## Caveats
127
+
128
+ - The exact timings of tasks are unpredictable (depends on device sleep state
129
+ etc.), and cannot be more frequent than every 15 minutes. This library
130
+ should only be used for tasks that can have inexact timing, such as the
131
+ periodic background syncing of data.
132
+
133
+ Android:
134
+
135
+ - Tasks will not run while the app is in the foreground, and scheduling can be
136
+ made even more imprecise when the app goes in/out of the foreground (as tasks
137
+ are rescheduled as soon as the app goes into the background).
138
+
139
+ iOS:
140
+
141
+ - iOS Background Fetch does not work in the simulator. It must be tested on a
142
+ real device.
143
+ - The user can disable Background App Refresh for your app from their Settings
144
+ (use ` statusAsync() ` to check for this).
56
145
57
- Must be called at the end of your task to indicate to the OS that it's
58
- finished. (Only required on iOS, no-op on Android).
59
146
60
- ## Example
147
+ ## Examples
61
148
62
149
### Simple
63
150
@@ -66,12 +153,16 @@ import React from 'react'
66
153
import { Text } from ' react-native'
67
154
import BackgroundTask from ' react-native-background-task'
68
155
69
- BackgroundTask .register (() => {
156
+ BackgroundTask .define (() => {
70
157
console .log (' Hello from a background task' )
71
158
BackgroundTask .finish ()
72
159
})
73
160
74
161
class MyApp extends React .Component {
162
+ componentDidMount () {
163
+ BackgroundTask .schedule ()
164
+ }
165
+
75
166
render () {
76
167
return < Text > Hello world< / Text >
77
168
}
@@ -82,10 +173,10 @@ class MyApp extends React.Component {
82
173
83
174
``` js
84
175
import React from ' react'
85
- import { AsyncStorage , Button , Text } from ' react-native'
176
+ import { Alert , AsyncStorage , Button } from ' react-native'
86
177
import BackgroundTask from ' react-native-background-task'
87
178
88
- BackgroundTask .register (async () => {
179
+ BackgroundTask .define (async () => {
89
180
// Fetch some data over the network which we want the user to have an up-to-
90
181
// date copy of, even if they have no network when using the app
91
182
const response = await fetch (' http://feeds.bbci.co.uk/news/rss.xml' )
@@ -96,11 +187,34 @@ BackgroundTask.register(async () => {
96
187
97
188
// Remember to call finish()
98
189
BackgroundTask .finish ()
99
- }, {
100
- period: 1800 , // Aim to run every 30 mins - more conservative on battery
101
190
})
102
191
103
192
class MyApp extends React .Component {
193
+ componentDidMount () {
194
+ BackgroundTask .schedule ({
195
+ period: 1800 , // Aim to run every 30 mins - more conservative on battery
196
+ })
197
+
198
+ // Optional: Check if the device is blocking background tasks or not
199
+ this .checkStatus ()
200
+ }
201
+
202
+ async checkStatus () {
203
+ const status = await BackgroundTask .statusAsync ()
204
+
205
+ if (status .available ) {
206
+ // Everything's fine
207
+ return
208
+ }
209
+
210
+ const reason = status .unavailableReason
211
+ if (reason === BackgroundTask .UNAVAILABLE_DENIED ) {
212
+ Alert .alert (' Denied' , ' Please enable background "Background App Refresh" for this app' )
213
+ } else if (reason === BackgroundTask .UNAVAILABLE_RESTRICTED ) {
214
+ Alert .alert (' Restricted' , ' Background tasks are restricted on your device' )
215
+ }
216
+ }
217
+
104
218
render () {
105
219
return (
106
220
< View>
0 commit comments