expo-background-task 1.0.7 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/android/build.gradle +2 -2
- package/build/BackgroundTask.d.ts +11 -0
- package/build/BackgroundTask.d.ts.map +1 -1
- package/build/BackgroundTask.js +15 -0
- package/build/BackgroundTask.js.map +1 -1
- package/build/ExpoBackgroundTaskModule.d.ts +4 -1
- package/build/ExpoBackgroundTaskModule.d.ts.map +1 -1
- package/build/ExpoBackgroundTaskModule.js.map +1 -1
- package/expo-module.config.json +1 -1
- package/ios/BackgroundTaskAppDelegate.swift +19 -10
- package/ios/BackgroundTaskModule.swift +29 -3
- package/ios/BackgroundTaskScheduler.swift +49 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/{1.0.7/expo.modules.backgroundtask-1.0.7.module → 1.0.8/expo.modules.backgroundtask-1.0.8.module} +7 -7
- package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/1.0.8/expo.modules.backgroundtask-1.0.8.module.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/1.0.8/expo.modules.backgroundtask-1.0.8.module.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/1.0.8/expo.modules.backgroundtask-1.0.8.module.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/1.0.8/expo.modules.backgroundtask-1.0.8.module.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/{1.0.7/expo.modules.backgroundtask-1.0.7.pom → 1.0.8/expo.modules.backgroundtask-1.0.8.pom} +1 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/1.0.8/expo.modules.backgroundtask-1.0.8.pom.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/1.0.8/expo.modules.backgroundtask-1.0.8.pom.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/1.0.8/expo.modules.backgroundtask-1.0.8.pom.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/1.0.8/expo.modules.backgroundtask-1.0.8.pom.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/maven-metadata.xml +4 -4
- package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/maven-metadata.xml.md5 +1 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/maven-metadata.xml.sha1 +1 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/maven-metadata.xml.sha256 +1 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/maven-metadata.xml.sha512 +1 -1
- package/package.json +2 -2
- package/src/BackgroundTask.ts +16 -0
- package/src/ExpoBackgroundTaskModule.ts +5 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/1.0.7/expo.modules.backgroundtask-1.0.7.module.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/1.0.7/expo.modules.backgroundtask-1.0.7.module.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/1.0.7/expo.modules.backgroundtask-1.0.7.module.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/1.0.7/expo.modules.backgroundtask-1.0.7.module.sha512 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/1.0.7/expo.modules.backgroundtask-1.0.7.pom.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/1.0.7/expo.modules.backgroundtask-1.0.7.pom.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/1.0.7/expo.modules.backgroundtask-1.0.7.pom.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/1.0.7/expo.modules.backgroundtask-1.0.7.pom.sha512 +0 -1
- /package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/{1.0.7/expo.modules.backgroundtask-1.0.7-sources.jar → 1.0.8/expo.modules.backgroundtask-1.0.8-sources.jar} +0 -0
- /package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/{1.0.7/expo.modules.backgroundtask-1.0.7-sources.jar.md5 → 1.0.8/expo.modules.backgroundtask-1.0.8-sources.jar.md5} +0 -0
- /package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/{1.0.7/expo.modules.backgroundtask-1.0.7-sources.jar.sha1 → 1.0.8/expo.modules.backgroundtask-1.0.8-sources.jar.sha1} +0 -0
- /package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/{1.0.7/expo.modules.backgroundtask-1.0.7-sources.jar.sha256 → 1.0.8/expo.modules.backgroundtask-1.0.8-sources.jar.sha256} +0 -0
- /package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/{1.0.7/expo.modules.backgroundtask-1.0.7-sources.jar.sha512 → 1.0.8/expo.modules.backgroundtask-1.0.8-sources.jar.sha512} +0 -0
- /package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/{1.0.7/expo.modules.backgroundtask-1.0.7.aar → 1.0.8/expo.modules.backgroundtask-1.0.8.aar} +0 -0
- /package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/{1.0.7/expo.modules.backgroundtask-1.0.7.aar.md5 → 1.0.8/expo.modules.backgroundtask-1.0.8.aar.md5} +0 -0
- /package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/{1.0.7/expo.modules.backgroundtask-1.0.7.aar.sha1 → 1.0.8/expo.modules.backgroundtask-1.0.8.aar.sha1} +0 -0
- /package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/{1.0.7/expo.modules.backgroundtask-1.0.7.aar.sha256 → 1.0.8/expo.modules.backgroundtask-1.0.8.aar.sha256} +0 -0
- /package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/{1.0.7/expo.modules.backgroundtask-1.0.7.aar.sha512 → 1.0.8/expo.modules.backgroundtask-1.0.8.aar.sha512} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,16 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 1.0.8 — 2025-09-18
|
|
14
|
+
|
|
15
|
+
### 🎉 New features
|
|
16
|
+
|
|
17
|
+
- [iOS] Added support for task expiration handler on iOS. ([#39773](https://github.com/expo/expo/pull/39773) by [@chrfalch](https://github.com/chrfalch))
|
|
18
|
+
|
|
19
|
+
### 🐛 Bug fixes
|
|
20
|
+
|
|
21
|
+
- [iOS] Fixed timing issue where background task iOS handler was not registered when we try to schedule a task. ([#39769](https://github.com/expo/expo/pull/39769) by [@chrfalch](https://github.com/chrfalch))
|
|
22
|
+
|
|
13
23
|
## 1.0.7 — 2025-09-11
|
|
14
24
|
|
|
15
25
|
_This version does not introduce any user-facing changes._
|
package/android/build.gradle
CHANGED
|
@@ -4,7 +4,7 @@ plugins {
|
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
group = 'host.exp.exponent'
|
|
7
|
-
version = '1.0.
|
|
7
|
+
version = '1.0.8'
|
|
8
8
|
|
|
9
9
|
dependencies {
|
|
10
10
|
implementation 'androidx.work:work-runtime-ktx:2.9.1'
|
|
@@ -15,7 +15,7 @@ android {
|
|
|
15
15
|
namespace "expo.modules.backgroundtask"
|
|
16
16
|
defaultConfig {
|
|
17
17
|
versionCode 23
|
|
18
|
-
versionName "1.0.
|
|
18
|
+
versionName "1.0.8"
|
|
19
19
|
consumerProguardFiles("proguard-rules.pro")
|
|
20
20
|
}
|
|
21
21
|
}
|
|
@@ -48,5 +48,16 @@ export declare function unregisterTaskAsync(taskName: string): Promise<void>;
|
|
|
48
48
|
* @returns A promise which fulfils when the task is triggered.
|
|
49
49
|
*/
|
|
50
50
|
export declare function triggerTaskWorkerForTestingAsync(): Promise<boolean>;
|
|
51
|
+
/**
|
|
52
|
+
* Adds a listener that is called when the background executor expires. On iOS, tasks can run
|
|
53
|
+
* for minutes, but the system can interrupt the process at any time. This listener is called
|
|
54
|
+
* when the system decides to stop the background tasks and should be used to clean up resources
|
|
55
|
+
* or save state. When the expiry handler is called, the main task runner is rescheduled automatically.
|
|
56
|
+
* @platform ios
|
|
57
|
+
* @return An object with a `remove` method to unsubscribe the listener.
|
|
58
|
+
*/
|
|
59
|
+
export declare function addExpirationListener(listener: () => void): {
|
|
60
|
+
remove: () => void;
|
|
61
|
+
};
|
|
51
62
|
export { BackgroundTaskStatus, BackgroundTaskResult, BackgroundTaskOptions, } from './BackgroundTask.types';
|
|
52
63
|
//# sourceMappingURL=BackgroundTask.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BackgroundTask.d.ts","sourceRoot":"","sources":["../src/BackgroundTask.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAwBrF;;;;;GAKG;AACH,eAAO,MAAM,cAAc,QAAa,OAAO,CAAC,oBAAoB,CAQnE,CAAC;AAGF;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,IAAI,CAAC,CA0Bf;AAGD;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CASzE;AAGD;;;;;GAKG;AACH,wBAAsB,gCAAgC,IAAI,OAAO,CAAC,OAAO,CAAC,CAUzE;AAGD,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"BackgroundTask.d.ts","sourceRoot":"","sources":["../src/BackgroundTask.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAwBrF;;;;;GAKG;AACH,eAAO,MAAM,cAAc,QAAa,OAAO,CAAC,oBAAoB,CAQnE,CAAC;AAGF;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,IAAI,CAAC,CA0Bf;AAGD;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CASzE;AAGD;;;;;GAKG;AACH,wBAAsB,gCAAgC,IAAI,OAAO,CAAC,OAAO,CAAC,CAUzE;AAGD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG;IAAE,MAAM,EAAE,MAAM,IAAI,CAAA;CAAE,CAKlF;AAGD,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC"}
|
package/build/BackgroundTask.js
CHANGED
|
@@ -121,6 +121,21 @@ export async function triggerTaskWorkerForTestingAsync() {
|
|
|
121
121
|
return Promise.resolve(false);
|
|
122
122
|
}
|
|
123
123
|
}
|
|
124
|
+
// @needsAudit
|
|
125
|
+
/**
|
|
126
|
+
* Adds a listener that is called when the background executor expires. On iOS, tasks can run
|
|
127
|
+
* for minutes, but the system can interrupt the process at any time. This listener is called
|
|
128
|
+
* when the system decides to stop the background tasks and should be used to clean up resources
|
|
129
|
+
* or save state. When the expiry handler is called, the main task runner is rescheduled automatically.
|
|
130
|
+
* @platform ios
|
|
131
|
+
* @return An object with a `remove` method to unsubscribe the listener.
|
|
132
|
+
*/
|
|
133
|
+
export function addExpirationListener(listener) {
|
|
134
|
+
if (!ExpoBackgroundTaskModule.addListener) {
|
|
135
|
+
throw new UnavailabilityError('BackgroundTask', 'addListener');
|
|
136
|
+
}
|
|
137
|
+
return ExpoBackgroundTaskModule.addListener('onTasksExpired', listener);
|
|
138
|
+
}
|
|
124
139
|
// Export types
|
|
125
140
|
export { BackgroundTaskStatus, BackgroundTaskResult, } from './BackgroundTask.types';
|
|
126
141
|
//# sourceMappingURL=BackgroundTask.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BackgroundTask.js","sourceRoot":"","sources":["../src/BackgroundTask.ts"],"names":[],"mappings":"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","sourcesContent":["import { isRunningInExpoGo } from 'expo';\nimport { Platform, UnavailabilityError } from 'expo-modules-core';\nimport * as TaskManager from 'expo-task-manager';\n\nimport { BackgroundTaskOptions, BackgroundTaskStatus } from './BackgroundTask.types';\nimport ExpoBackgroundTaskModule from './ExpoBackgroundTaskModule';\n\n// Flag to warn about running on Apple simulator\nlet warnAboutRunningOniOSSimulator = false;\n\nlet warnedAboutExpoGo = false;\n\nfunction _validate(taskName: unknown) {\n if (isRunningInExpoGo()) {\n if (!warnedAboutExpoGo) {\n const message =\n '`Background Task` functionality is not available in Expo Go:\\n' +\n 'You can use this API and any others in a development build. Learn more: https://expo.fyi/dev-client.';\n console.warn(message);\n warnedAboutExpoGo = true;\n }\n }\n if (!taskName || typeof taskName !== 'string') {\n throw new TypeError('`taskName` must be a non-empty string.');\n }\n}\n\n// @needsAudit\n/**\n * Returns the status for the Background Task API. On web, it always returns `BackgroundTaskStatus.Restricted`,\n * while on native platforms it returns `BackgroundTaskStatus.Available`.\n *\n * @returns A BackgroundTaskStatus enum value or `null` if not available.\n */\nexport const getStatusAsync = async (): Promise<BackgroundTaskStatus> => {\n if (!ExpoBackgroundTaskModule.getStatusAsync) {\n throw new UnavailabilityError('BackgroundTask', 'getStatusAsync');\n }\n\n return isRunningInExpoGo()\n ? BackgroundTaskStatus.Restricted\n : ExpoBackgroundTaskModule.getStatusAsync();\n};\n\n// @needsAudit\n/**\n * Registers a background task with the given name. Registered tasks are saved in persistent storage and restored once the app is initialized.\n * @param taskName Name of the task to register. The task needs to be defined first - see [`TaskManager.defineTask`](task-manager/#taskmanagerdefinetasktaskname-taskexecutor)\n * for more details.\n * @param options An object containing the background task options.\n *\n * @example\n * ```ts\n * import * as TaskManager from 'expo-task-manager';\n *\n * // Register the task outside of the component\n * TaskManager.defineTask(BACKGROUND_TASK_IDENTIFIER, () => {\n * try {\n * await AsyncStorage.setItem(LAST_TASK_DATE_KEY, Date.now().toString());\n * } catch (error) {\n * console.error('Failed to save the last fetch date', error);\n * return BackgroundTaskResult.Failed;\n * }\n * return BackgroundTaskResult.Success;\n * });\n * ```\n *\n * You can now use the `registerTaskAsync` function to register the task:\n *\n * ```ts\n * BackgroundTask.registerTaskAsync(BACKGROUND_TASK_IDENTIFIER, {});\n * ```\n */\nexport async function registerTaskAsync(\n taskName: string,\n options: BackgroundTaskOptions = {}\n): Promise<void> {\n if (!ExpoBackgroundTaskModule.registerTaskAsync) {\n throw new UnavailabilityError('BackgroundTask', 'registerTaskAsync');\n }\n if (!TaskManager.isTaskDefined(taskName)) {\n throw new Error(\n `Task '${taskName}' is not defined. You must define a task using TaskManager.defineTask before registering.`\n );\n }\n\n if ((await ExpoBackgroundTaskModule.getStatusAsync()) === BackgroundTaskStatus.Restricted) {\n if (!warnAboutRunningOniOSSimulator) {\n const message =\n Platform.OS === 'ios'\n ? `Background tasks are not supported on iOS simulators. Skipped registering task: ${taskName}.`\n : `Background tasks are not available in the current environment. Skipped registering task: ${taskName}.`;\n console.warn(message);\n warnAboutRunningOniOSSimulator = true;\n }\n return;\n }\n _validate(taskName);\n if (await TaskManager.isTaskRegisteredAsync(taskName)) {\n return;\n }\n await ExpoBackgroundTaskModule.registerTaskAsync(taskName, options);\n}\n\n// @needsAudit\n/**\n * Unregisters a background task, so the application will no longer be executing this task.\n * @param taskName Name of the task to unregister.\n * @return A promise which fulfils when the task is fully unregistered.\n */\nexport async function unregisterTaskAsync(taskName: string): Promise<void> {\n if (!ExpoBackgroundTaskModule.unregisterTaskAsync) {\n throw new UnavailabilityError('BackgroundTask', 'unregisterTaskAsync');\n }\n _validate(taskName);\n if (!(await TaskManager.isTaskRegisteredAsync(taskName))) {\n return;\n }\n await ExpoBackgroundTaskModule.unregisterTaskAsync(taskName);\n}\n\n// @needsAudit\n/**\n * When in debug mode this function will trigger running the background tasks.\n * This function will only work for apps built in debug mode.\n * This method is only available in development mode. It will not work in production builds.\n * @returns A promise which fulfils when the task is triggered.\n */\nexport async function triggerTaskWorkerForTestingAsync(): Promise<boolean> {\n if (__DEV__) {\n if (!ExpoBackgroundTaskModule.triggerTaskWorkerForTestingAsync) {\n throw new UnavailabilityError('BackgroundTask', 'triggerTaskWorkerForTestingAsync');\n }\n console.log('Calling triggerTaskWorkerForTestingAsync');\n return await ExpoBackgroundTaskModule.triggerTaskWorkerForTestingAsync();\n } else {\n return Promise.resolve(false);\n }\n}\n\n// Export types\nexport {\n BackgroundTaskStatus,\n BackgroundTaskResult,\n BackgroundTaskOptions,\n} from './BackgroundTask.types';\n"]}
|
|
1
|
+
{"version":3,"file":"BackgroundTask.js","sourceRoot":"","sources":["../src/BackgroundTask.ts"],"names":[],"mappings":"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","sourcesContent":["import { isRunningInExpoGo } from 'expo';\nimport { Platform, UnavailabilityError } from 'expo-modules-core';\nimport * as TaskManager from 'expo-task-manager';\n\nimport { BackgroundTaskOptions, BackgroundTaskStatus } from './BackgroundTask.types';\nimport ExpoBackgroundTaskModule from './ExpoBackgroundTaskModule';\n\n// Flag to warn about running on Apple simulator\nlet warnAboutRunningOniOSSimulator = false;\n\nlet warnedAboutExpoGo = false;\n\nfunction _validate(taskName: unknown) {\n if (isRunningInExpoGo()) {\n if (!warnedAboutExpoGo) {\n const message =\n '`Background Task` functionality is not available in Expo Go:\\n' +\n 'You can use this API and any others in a development build. Learn more: https://expo.fyi/dev-client.';\n console.warn(message);\n warnedAboutExpoGo = true;\n }\n }\n if (!taskName || typeof taskName !== 'string') {\n throw new TypeError('`taskName` must be a non-empty string.');\n }\n}\n\n// @needsAudit\n/**\n * Returns the status for the Background Task API. On web, it always returns `BackgroundTaskStatus.Restricted`,\n * while on native platforms it returns `BackgroundTaskStatus.Available`.\n *\n * @returns A BackgroundTaskStatus enum value or `null` if not available.\n */\nexport const getStatusAsync = async (): Promise<BackgroundTaskStatus> => {\n if (!ExpoBackgroundTaskModule.getStatusAsync) {\n throw new UnavailabilityError('BackgroundTask', 'getStatusAsync');\n }\n\n return isRunningInExpoGo()\n ? BackgroundTaskStatus.Restricted\n : ExpoBackgroundTaskModule.getStatusAsync();\n};\n\n// @needsAudit\n/**\n * Registers a background task with the given name. Registered tasks are saved in persistent storage and restored once the app is initialized.\n * @param taskName Name of the task to register. The task needs to be defined first - see [`TaskManager.defineTask`](task-manager/#taskmanagerdefinetasktaskname-taskexecutor)\n * for more details.\n * @param options An object containing the background task options.\n *\n * @example\n * ```ts\n * import * as TaskManager from 'expo-task-manager';\n *\n * // Register the task outside of the component\n * TaskManager.defineTask(BACKGROUND_TASK_IDENTIFIER, () => {\n * try {\n * await AsyncStorage.setItem(LAST_TASK_DATE_KEY, Date.now().toString());\n * } catch (error) {\n * console.error('Failed to save the last fetch date', error);\n * return BackgroundTaskResult.Failed;\n * }\n * return BackgroundTaskResult.Success;\n * });\n * ```\n *\n * You can now use the `registerTaskAsync` function to register the task:\n *\n * ```ts\n * BackgroundTask.registerTaskAsync(BACKGROUND_TASK_IDENTIFIER, {});\n * ```\n */\nexport async function registerTaskAsync(\n taskName: string,\n options: BackgroundTaskOptions = {}\n): Promise<void> {\n if (!ExpoBackgroundTaskModule.registerTaskAsync) {\n throw new UnavailabilityError('BackgroundTask', 'registerTaskAsync');\n }\n if (!TaskManager.isTaskDefined(taskName)) {\n throw new Error(\n `Task '${taskName}' is not defined. You must define a task using TaskManager.defineTask before registering.`\n );\n }\n\n if ((await ExpoBackgroundTaskModule.getStatusAsync()) === BackgroundTaskStatus.Restricted) {\n if (!warnAboutRunningOniOSSimulator) {\n const message =\n Platform.OS === 'ios'\n ? `Background tasks are not supported on iOS simulators. Skipped registering task: ${taskName}.`\n : `Background tasks are not available in the current environment. Skipped registering task: ${taskName}.`;\n console.warn(message);\n warnAboutRunningOniOSSimulator = true;\n }\n return;\n }\n _validate(taskName);\n if (await TaskManager.isTaskRegisteredAsync(taskName)) {\n return;\n }\n await ExpoBackgroundTaskModule.registerTaskAsync(taskName, options);\n}\n\n// @needsAudit\n/**\n * Unregisters a background task, so the application will no longer be executing this task.\n * @param taskName Name of the task to unregister.\n * @return A promise which fulfils when the task is fully unregistered.\n */\nexport async function unregisterTaskAsync(taskName: string): Promise<void> {\n if (!ExpoBackgroundTaskModule.unregisterTaskAsync) {\n throw new UnavailabilityError('BackgroundTask', 'unregisterTaskAsync');\n }\n _validate(taskName);\n if (!(await TaskManager.isTaskRegisteredAsync(taskName))) {\n return;\n }\n await ExpoBackgroundTaskModule.unregisterTaskAsync(taskName);\n}\n\n// @needsAudit\n/**\n * When in debug mode this function will trigger running the background tasks.\n * This function will only work for apps built in debug mode.\n * This method is only available in development mode. It will not work in production builds.\n * @returns A promise which fulfils when the task is triggered.\n */\nexport async function triggerTaskWorkerForTestingAsync(): Promise<boolean> {\n if (__DEV__) {\n if (!ExpoBackgroundTaskModule.triggerTaskWorkerForTestingAsync) {\n throw new UnavailabilityError('BackgroundTask', 'triggerTaskWorkerForTestingAsync');\n }\n console.log('Calling triggerTaskWorkerForTestingAsync');\n return await ExpoBackgroundTaskModule.triggerTaskWorkerForTestingAsync();\n } else {\n return Promise.resolve(false);\n }\n}\n\n// @needsAudit\n/**\n * Adds a listener that is called when the background executor expires. On iOS, tasks can run\n * for minutes, but the system can interrupt the process at any time. This listener is called\n * when the system decides to stop the background tasks and should be used to clean up resources\n * or save state. When the expiry handler is called, the main task runner is rescheduled automatically.\n * @platform ios\n * @return An object with a `remove` method to unsubscribe the listener.\n */\nexport function addExpirationListener(listener: () => void): { remove: () => void } {\n if (!ExpoBackgroundTaskModule.addListener) {\n throw new UnavailabilityError('BackgroundTask', 'addListener');\n }\n return ExpoBackgroundTaskModule.addListener('onTasksExpired', listener);\n}\n\n// Export types\nexport {\n BackgroundTaskStatus,\n BackgroundTaskResult,\n BackgroundTaskOptions,\n} from './BackgroundTask.types';\n"]}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { type NativeModule } from 'expo';
|
|
2
2
|
import { BackgroundTaskOptions, BackgroundTaskStatus } from './BackgroundTask.types';
|
|
3
|
-
|
|
3
|
+
type ExpoBackgroundTaskEvents = {
|
|
4
|
+
onTasksExpired(): void;
|
|
5
|
+
};
|
|
6
|
+
declare class ExpoBackgroundTaskModule extends NativeModule<ExpoBackgroundTaskEvents> {
|
|
4
7
|
getStatusAsync(): Promise<BackgroundTaskStatus>;
|
|
5
8
|
registerTaskAsync(name: string, options: BackgroundTaskOptions): Promise<void>;
|
|
6
9
|
unregisterTaskAsync(name: string): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoBackgroundTaskModule.d.ts","sourceRoot":"","sources":["../src/ExpoBackgroundTaskModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,MAAM,CAAC;AAE9D,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAErF,OAAO,OAAO,wBAAyB,SAAQ,YAAY;
|
|
1
|
+
{"version":3,"file":"ExpoBackgroundTaskModule.d.ts","sourceRoot":"","sources":["../src/ExpoBackgroundTaskModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,MAAM,CAAC;AAE9D,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAErF,KAAK,wBAAwB,GAAG;IAC9B,cAAc,IAAI,IAAI,CAAC;CACxB,CAAC;AAEF,OAAO,OAAO,wBAAyB,SAAQ,YAAY,CAAC,wBAAwB,CAAC;IACnF,cAAc,IAAI,OAAO,CAAC,oBAAoB,CAAC;IAC/C,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IAC9E,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAChD,gCAAgC,IAAI,OAAO,CAAC,OAAO,CAAC;CACrD;;AAED,wBAAmF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoBackgroundTaskModule.js","sourceRoot":"","sources":["../src/ExpoBackgroundTaskModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAqB,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"ExpoBackgroundTaskModule.js","sourceRoot":"","sources":["../src/ExpoBackgroundTaskModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAqB,MAAM,MAAM,CAAC;AAe9D,eAAe,mBAAmB,CAA2B,oBAAoB,CAAC,CAAC","sourcesContent":["import { requireNativeModule, type NativeModule } from 'expo';\n\nimport { BackgroundTaskOptions, BackgroundTaskStatus } from './BackgroundTask.types';\n\ntype ExpoBackgroundTaskEvents = {\n onTasksExpired(): void;\n};\n\ndeclare class ExpoBackgroundTaskModule extends NativeModule<ExpoBackgroundTaskEvents> {\n getStatusAsync(): Promise<BackgroundTaskStatus>;\n registerTaskAsync(name: string, options: BackgroundTaskOptions): Promise<void>;\n unregisterTaskAsync(name: string): Promise<void>;\n triggerTaskWorkerForTestingAsync(): Promise<boolean>;\n}\n\nexport default requireNativeModule<ExpoBackgroundTaskModule>('ExpoBackgroundTask');\n"]}
|
package/expo-module.config.json
CHANGED
|
@@ -13,7 +13,10 @@ public class BackgroundTaskAppDelegateSubscriber: ExpoAppDelegateSubscriber {
|
|
|
13
13
|
// Set up expiration handler
|
|
14
14
|
task.expirationHandler = { ()
|
|
15
15
|
log.warn("Expo Background Tasks - task expired")
|
|
16
|
+
// Send message to Expo module
|
|
17
|
+
NotificationCenter.default.post(name: onTasksExpiredNotification, object: self, userInfo: [:])
|
|
16
18
|
task.setTaskCompleted(success: false)
|
|
19
|
+
self.reschedule()
|
|
17
20
|
}
|
|
18
21
|
|
|
19
22
|
// Let's find the task service implementation and call the runTasks(withReason)
|
|
@@ -21,24 +24,30 @@ public class BackgroundTaskAppDelegateSubscriber: ExpoAppDelegateSubscriber {
|
|
|
21
24
|
taskService.runTasks(with: EXTaskLaunchReasonBackgroundTask, userInfo: nil, completionHandler: { _ in
|
|
22
25
|
// Mark iOS task as finished - this is important so that we can continue calling it
|
|
23
26
|
task.setTaskCompleted(success: true)
|
|
24
|
-
|
|
25
|
-
// Reschedule
|
|
26
|
-
Task {
|
|
27
|
-
do {
|
|
28
|
-
log.debug("Background task successfully finished. Rescheduling")
|
|
29
|
-
try await BackgroundTaskScheduler.tryScheduleWorker()
|
|
30
|
-
} catch {
|
|
31
|
-
log.error("Could not reschedule the worker after task finished: \(error.localizedDescription)")
|
|
32
|
-
}
|
|
33
|
-
}
|
|
27
|
+
self.reschedule()
|
|
34
28
|
})
|
|
35
29
|
} else {
|
|
36
30
|
task.setTaskCompleted(success: false)
|
|
37
31
|
log.error("Expo Background Tasks: Could not find TaskService module")
|
|
38
32
|
}
|
|
39
33
|
}
|
|
34
|
+
|
|
35
|
+
// Signal to the scheduler that we're done.
|
|
36
|
+
BackgroundTaskScheduler.bgTaskSchedulerDidFinishRegister()
|
|
40
37
|
}
|
|
41
38
|
|
|
42
39
|
return true
|
|
43
40
|
}
|
|
41
|
+
|
|
42
|
+
private func reschedule() {
|
|
43
|
+
// Reschedule
|
|
44
|
+
Task {
|
|
45
|
+
do {
|
|
46
|
+
log.debug("Background task successfully finished. Rescheduling")
|
|
47
|
+
try await BackgroundTaskScheduler.tryScheduleWorker()
|
|
48
|
+
} catch {
|
|
49
|
+
log.error("Could not reschedule the worker after task finished: \(error.localizedDescription)")
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
44
53
|
}
|
|
@@ -1,12 +1,30 @@
|
|
|
1
1
|
// Copyright 2024-present 650 Industries. All rights reserved.
|
|
2
2
|
import ExpoModulesCore
|
|
3
3
|
|
|
4
|
+
private let onTasksExpired = "onTasksExpired"
|
|
5
|
+
public let onTasksExpiredNotification = Notification.Name(onTasksExpired)
|
|
6
|
+
|
|
4
7
|
public class BackgroundTaskModule: Module {
|
|
5
8
|
private var taskManager: EXTaskManagerInterface?
|
|
6
9
|
|
|
7
10
|
public func definition() -> ModuleDefinition {
|
|
8
11
|
Name("ExpoBackgroundTask")
|
|
9
12
|
|
|
13
|
+
Events(onTasksExpired)
|
|
14
|
+
|
|
15
|
+
OnStartObserving(onTasksExpired) {
|
|
16
|
+
NotificationCenter.default.addObserver(
|
|
17
|
+
self,
|
|
18
|
+
selector: #selector(handleTasksExpiredNotification),
|
|
19
|
+
name: onTasksExpiredNotification,
|
|
20
|
+
object: nil)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
OnStopObserving(onTasksExpired) {
|
|
24
|
+
// swiftlint:disable:next notification_center_detachment
|
|
25
|
+
NotificationCenter.default.removeObserver(self)
|
|
26
|
+
}
|
|
27
|
+
|
|
10
28
|
OnCreate {
|
|
11
29
|
taskManager = appContext?.legacyModule(implementing: EXTaskManagerInterface.self)
|
|
12
30
|
}
|
|
@@ -29,7 +47,8 @@ public class BackgroundTaskModule: Module {
|
|
|
29
47
|
}
|
|
30
48
|
|
|
31
49
|
// Register task
|
|
32
|
-
taskManager.registerTask(
|
|
50
|
+
taskManager.registerTask(
|
|
51
|
+
withName: name, consumer: BackgroundTaskConsumer.self, options: options)
|
|
33
52
|
}
|
|
34
53
|
|
|
35
54
|
AsyncFunction("unregisterTaskAsync") { (name: String) in
|
|
@@ -51,8 +70,15 @@ public class BackgroundTaskModule: Module {
|
|
|
51
70
|
}
|
|
52
71
|
|
|
53
72
|
AsyncFunction("getStatusAsync") {
|
|
54
|
-
return BackgroundTaskScheduler.supportsBackgroundTasks()
|
|
55
|
-
BackgroundTaskStatus.available : .restricted
|
|
73
|
+
return BackgroundTaskScheduler.supportsBackgroundTasks()
|
|
74
|
+
? BackgroundTaskStatus.available : .restricted
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
@objc func handleTasksExpiredNotification(_ notification: Notification) {
|
|
79
|
+
guard let url = notification.userInfo?["url"] as? URL else {
|
|
80
|
+
return
|
|
56
81
|
}
|
|
82
|
+
self.sendEvent(onTasksExpired, [:])
|
|
57
83
|
}
|
|
58
84
|
}
|
|
@@ -13,6 +13,52 @@ public class BackgroundTaskScheduler {
|
|
|
13
13
|
*/
|
|
14
14
|
private static var intervalSeconds: TimeInterval = 12 * 60 * 60
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
A one-time async gate that becomes ready after BGTaskScheduler registration finishes.
|
|
18
|
+
Multiple awaiters will be resumed when ready; subsequent awaiters return immediately.
|
|
19
|
+
*/
|
|
20
|
+
private actor RegistrationGate {
|
|
21
|
+
private var ready: Bool = false
|
|
22
|
+
private var waiters: [CheckedContinuation<Void, Never>] = []
|
|
23
|
+
|
|
24
|
+
func awaitReady() async {
|
|
25
|
+
if ready { return }
|
|
26
|
+
await withCheckedContinuation { (continuation: CheckedContinuation<Void, Never>) in
|
|
27
|
+
if ready {
|
|
28
|
+
continuation.resume()
|
|
29
|
+
} else {
|
|
30
|
+
waiters.append(continuation)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
func signalReady() {
|
|
36
|
+
guard !ready else { return }
|
|
37
|
+
ready = true
|
|
38
|
+
let continuations = waiters
|
|
39
|
+
waiters.removeAll()
|
|
40
|
+
for c in continuations {
|
|
41
|
+
c.resume()
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
Registration gate that will only be signaled when the bgTaskSchedulerDidFinishRegister is called.
|
|
48
|
+
*/
|
|
49
|
+
private static let registrationGate = RegistrationGate()
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
Call from the BackgroundTaskAppDelegate after the call to BGTaskScheduler.shared.register has finished
|
|
53
|
+
so that we can hold back any tryScheduleWorker calls, especially the call to BGTaskScheduler.shared.submit
|
|
54
|
+
that will fail if called before the BGTaskScheduler has successfully registered its handler.
|
|
55
|
+
*/
|
|
56
|
+
public static func bgTaskSchedulerDidFinishRegister() {
|
|
57
|
+
Task {
|
|
58
|
+
await registrationGate.signalReady()
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
16
62
|
/**
|
|
17
63
|
* Call when a task is registered to keep track of how many background task consumers we have
|
|
18
64
|
*/
|
|
@@ -50,6 +96,9 @@ public class BackgroundTaskScheduler {
|
|
|
50
96
|
return
|
|
51
97
|
}
|
|
52
98
|
|
|
99
|
+
// Wait until BGTaskScheduler registration has completed.
|
|
100
|
+
await registrationGate.awaitReady()
|
|
101
|
+
|
|
53
102
|
// Stop existing tasks
|
|
54
103
|
await stopWorker()
|
|
55
104
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"component": {
|
|
4
4
|
"group": "host.exp.exponent",
|
|
5
5
|
"module": "expo.modules.backgroundtask",
|
|
6
|
-
"version": "1.0.
|
|
6
|
+
"version": "1.0.8",
|
|
7
7
|
"attributes": {
|
|
8
8
|
"org.gradle.status": "release"
|
|
9
9
|
}
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
},
|
|
25
25
|
"files": [
|
|
26
26
|
{
|
|
27
|
-
"name": "expo.modules.backgroundtask-1.0.
|
|
28
|
-
"url": "expo.modules.backgroundtask-1.0.
|
|
27
|
+
"name": "expo.modules.backgroundtask-1.0.8.aar",
|
|
28
|
+
"url": "expo.modules.backgroundtask-1.0.8.aar",
|
|
29
29
|
"size": 48252,
|
|
30
30
|
"sha512": "5b5e60d520b379283db7486525e8801fa29159482770b20736ce592d9bc9d767c2aeedd2c365a1bc59723340a6064dbc1efc1bbbe64464109e0024b09720a70d",
|
|
31
31
|
"sha256": "c4f03f70e9596c443a6029c83837e20038469065042559e921d389804a9a1b98",
|
|
@@ -64,8 +64,8 @@
|
|
|
64
64
|
],
|
|
65
65
|
"files": [
|
|
66
66
|
{
|
|
67
|
-
"name": "expo.modules.backgroundtask-1.0.
|
|
68
|
-
"url": "expo.modules.backgroundtask-1.0.
|
|
67
|
+
"name": "expo.modules.backgroundtask-1.0.8.aar",
|
|
68
|
+
"url": "expo.modules.backgroundtask-1.0.8.aar",
|
|
69
69
|
"size": 48252,
|
|
70
70
|
"sha512": "5b5e60d520b379283db7486525e8801fa29159482770b20736ce592d9bc9d767c2aeedd2c365a1bc59723340a6064dbc1efc1bbbe64464109e0024b09720a70d",
|
|
71
71
|
"sha256": "c4f03f70e9596c443a6029c83837e20038469065042559e921d389804a9a1b98",
|
|
@@ -84,8 +84,8 @@
|
|
|
84
84
|
},
|
|
85
85
|
"files": [
|
|
86
86
|
{
|
|
87
|
-
"name": "expo.modules.backgroundtask-1.0.
|
|
88
|
-
"url": "expo.modules.backgroundtask-1.0.
|
|
87
|
+
"name": "expo.modules.backgroundtask-1.0.8-sources.jar",
|
|
88
|
+
"url": "expo.modules.backgroundtask-1.0.8-sources.jar",
|
|
89
89
|
"size": 6850,
|
|
90
90
|
"sha512": "0fc8a6188061d8818a320cd4c27e02e406cd4bf49aaef15fc95536365ff20a70d5e599ba86698b3b058fa676a7116f5d8530b0d0437eb90092e0d0593edb09bb",
|
|
91
91
|
"sha256": "b8464c6ac3c14d1f3fed11e436deb971f7203a5389a08fda08951223923d2fca",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
c1c94bff79921a7bc8860744f17fa2a7
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
dc7da2fe977890d176e77a0f5875f260424c709d
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
542f501224cc35735103ee3bc89b4bba0cfbeac197cf2e574227c7b96d83a820
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
623b51cdad33abc86aba097aa6a5bca40bb12e9ed72e1c11c480b15d9a988523bfaf9eb11f01f9e81086975fcaf8dc70ca6161187354ac05e8205616131781ee
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
<modelVersion>4.0.0</modelVersion>
|
|
10
10
|
<groupId>host.exp.exponent</groupId>
|
|
11
11
|
<artifactId>expo.modules.backgroundtask</artifactId>
|
|
12
|
-
<version>1.0.
|
|
12
|
+
<version>1.0.8</version>
|
|
13
13
|
<packaging>aar</packaging>
|
|
14
14
|
<name>expo.modules.backgroundtask</name>
|
|
15
15
|
<url>https://github.com/expo/expo</url>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
9b32b280b51bf8f68fa810142a03ce8f
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
c44fcf6b0f79e620a5aba056f48280bc30633c06
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
dfc4e72a1a499bb0676583deedc3b7932c94ccdcece276b0c5bd6cfa70ef9fa3
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
43a0a0ad207f00f709262c53a75ebc7008bbb4a7ce08f98b5a6c67742dc561e28180ec5b1d9a041018eb3d22515b3d815be966e1e1e48d55de56c178caa13d23
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
<groupId>host.exp.exponent</groupId>
|
|
4
4
|
<artifactId>expo.modules.backgroundtask</artifactId>
|
|
5
5
|
<versioning>
|
|
6
|
-
<latest>1.0.
|
|
7
|
-
<release>1.0.
|
|
6
|
+
<latest>1.0.8</latest>
|
|
7
|
+
<release>1.0.8</release>
|
|
8
8
|
<versions>
|
|
9
|
-
<version>1.0.
|
|
9
|
+
<version>1.0.8</version>
|
|
10
10
|
</versions>
|
|
11
|
-
<lastUpdated>
|
|
11
|
+
<lastUpdated>20250918213206</lastUpdated>
|
|
12
12
|
</versioning>
|
|
13
13
|
</metadata>
|
package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/maven-metadata.xml.md5
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
eda7ff3e888b83b1e9f7fd0e0a265b59
|
package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/maven-metadata.xml.sha1
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
d0f0b61438b5a4511ea4327cbd8b4aca4239b3eb
|
package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/maven-metadata.xml.sha256
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
a72fdc74f6d5af6ef96c952ae5c06c20aebc70bd1582fc63802c9ec6568d906c
|
package/local-maven-repo/host/exp/exponent/expo.modules.backgroundtask/maven-metadata.xml.sha512
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
dc0108fbcddcfb82815b96075716dc965a1f63974b3f37250067e9e715c71e103ab7b29feb117da17dc70680508f26e86fa379061304460f8348f8bae07d7ec6
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-background-task",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"description": "Expo Android and iOS module for Background Task APIs",
|
|
5
5
|
"main": "build/BackgroundTask.js",
|
|
6
6
|
"types": "build/BackgroundTask.d.ts",
|
|
@@ -40,5 +40,5 @@
|
|
|
40
40
|
"peerDependencies": {
|
|
41
41
|
"expo": "*"
|
|
42
42
|
},
|
|
43
|
-
"gitHead": "
|
|
43
|
+
"gitHead": "0d9ae61f3dea2e2b854576859e5b50fca5503fc1"
|
|
44
44
|
}
|
package/src/BackgroundTask.ts
CHANGED
|
@@ -138,6 +138,22 @@ export async function triggerTaskWorkerForTestingAsync(): Promise<boolean> {
|
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
+
// @needsAudit
|
|
142
|
+
/**
|
|
143
|
+
* Adds a listener that is called when the background executor expires. On iOS, tasks can run
|
|
144
|
+
* for minutes, but the system can interrupt the process at any time. This listener is called
|
|
145
|
+
* when the system decides to stop the background tasks and should be used to clean up resources
|
|
146
|
+
* or save state. When the expiry handler is called, the main task runner is rescheduled automatically.
|
|
147
|
+
* @platform ios
|
|
148
|
+
* @return An object with a `remove` method to unsubscribe the listener.
|
|
149
|
+
*/
|
|
150
|
+
export function addExpirationListener(listener: () => void): { remove: () => void } {
|
|
151
|
+
if (!ExpoBackgroundTaskModule.addListener) {
|
|
152
|
+
throw new UnavailabilityError('BackgroundTask', 'addListener');
|
|
153
|
+
}
|
|
154
|
+
return ExpoBackgroundTaskModule.addListener('onTasksExpired', listener);
|
|
155
|
+
}
|
|
156
|
+
|
|
141
157
|
// Export types
|
|
142
158
|
export {
|
|
143
159
|
BackgroundTaskStatus,
|
|
@@ -2,7 +2,11 @@ import { requireNativeModule, type NativeModule } from 'expo';
|
|
|
2
2
|
|
|
3
3
|
import { BackgroundTaskOptions, BackgroundTaskStatus } from './BackgroundTask.types';
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
type ExpoBackgroundTaskEvents = {
|
|
6
|
+
onTasksExpired(): void;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
declare class ExpoBackgroundTaskModule extends NativeModule<ExpoBackgroundTaskEvents> {
|
|
6
10
|
getStatusAsync(): Promise<BackgroundTaskStatus>;
|
|
7
11
|
registerTaskAsync(name: string, options: BackgroundTaskOptions): Promise<void>;
|
|
8
12
|
unregisterTaskAsync(name: string): Promise<void>;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
845896d6a748f7290adcce426b70b65e
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
8e68d182be84478a9f0d069b56fc8daf155a155b
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
4fe0637ff751d0cfb961905d65b93dc53245253613c15193ec49fbe3ada4049d
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
cd78298fdf20d5a3f4cc1f18c23324f6ce60917bbb87d33a63470102de1ca4e5a143232c39b009ba93937e6893e3296f95a1dd9a861d425ed0010c15527158e4
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
28ea3d0eaebf97c36b622818cd6ea9f5
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
485f45f0038a4cf310f6bbc55fd1e26448600e32
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
cc0b38c4ebc65f6031bcb07677149d2692be02b08bbea0170693e67d78a8663d
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
bd2ab4b781b0c6833e79ca9196c3494d6488241b9564959084365de05ee74612e448ff8902fbcd5af43d6df4114427874cf44f8d4e2da8b53a6d2d7ac7d2d844
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|