https://github.com/xinthink/flt_worker
Schedule & run Dart code in the background on both Android & iOS
https://github.com/xinthink/flt_worker
background-processing background-tasks flutter workmanager
Last synced: 2 months ago
JSON representation
Schedule & run Dart code in the background on both Android & iOS
- Host: GitHub
- URL: https://github.com/xinthink/flt_worker
- Owner: xinthink
- License: mit
- Created: 2020-03-31T11:47:09.000Z (about 5 years ago)
- Default Branch: master
- Last Pushed: 2021-04-09T09:13:25.000Z (about 4 years ago)
- Last Synced: 2025-03-17T03:51:19.927Z (2 months ago)
- Topics: background-processing, background-tasks, flutter, workmanager
- Language: Dart
- Homepage:
- Size: 155 KB
- Stars: 28
- Watchers: 2
- Forks: 8
- Open Issues: 10
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# flt_worker
[![Pub][pub-badge]][pub]
[![Check Status][check-badge]][github-runs]
[![MIT][license-badge]][license]The `flt_worker` plugin allows you to schedule and execute Dart-written background tasks in a dedicated isolate, by utilizing the [WorkManager] API on Android, and the [BackgroundTasks] API on iOS 13.0+, respectively.
Background processing is suitable for time-consuming tasks like downloading/uploading offline data, fitting a machine learning model, etc. You can use this plugin to schedule work like that. A pre-registed Dart worker will be launched and run in the background whenever the system decides to run the task.
## Integration
Add a dependency to `pubspec.yaml`:
```yaml
dependencies:
flt_worker: ^0.1.0
```A worker is running in a separate instance of Flutter engine. Any plugins needed in the worker have to be registered again. In the following example, the `path_provider` plugin is registered for the background isolate.
iOS:
```obj-c
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GeneratedPluginRegistrant registerWithRegistry:self];// set a callback to register all plugins to a headless engine instance
FltWorkerPlugin.registerPlugins = ^(NSObject *registry) {
[FLTPathProviderPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTPathProviderPlugin"]];
};
...
}
```Android:
```java
@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);// set a callback to register all plugins to a headless engine instance
FltWorkerPlugin.registerPluginsForWorkers = registry -> {
io.flutter.plugins.pathprovider.PathProviderPlugin.registerWith(
registry.registrarFor("io.flutter.plugins.pathprovider.PathProviderPlugin"));
return null;
};
}
```Fortunately, `flt_worker` itself is always available for the worker, so you don't have to register it again.
One more thing has to be done if you're working on iOS: all task identifiers must be registered before you can subimit any `BGTaskRequest`.
Add lines like this to the `Info.plist` file:
```xml
BGTaskSchedulerPermittedIdentifierscom.example.counter_task
dev.example.task2
...```
## Usage
### Initialization & work dispatcher
Before you can schedule background tasks, a worker callback must be registerted to the plugin:
```dart
import 'package:flt_worker/flt_worker.dart';void main() {
runApp(MyApp());
initializeWorker(worker);
}
```Please notice that the callback must be a [top-level or static function][CallbackHandle].
The `worker` function acts as a dispatcher of all background tasks, you can call different functions according to the payload of the work, and return a `Future` so that the plugin can notify the system scheduler whenever the work is done.
```dart
Future worker(WorkPayload payload) {
if (payload.tags.contains('download')) {
return _fetchData();
} else if (...) {
...
} else {
return Future.value();
}
}/// Cache data for offline use
Future _fetchData() async {
// fetch data & update local storage
}
```### Scheduling work
You can use the `enqueueWorkIntent` function to schedule a background `WorkIntent` like this:
```dart
enqueueWorkIntent(WorkIntent(
identifier: 'counter',
initialDelay: Duration(seconds: 59),
input: {
'counter': counter,
},
));
```The name of `WorkIntent` is chosen to avoid conflict with the term `WorkRequest` from the [WorkManager] API for Android.
Please see the documentation and also the example app to find out how to schedule different kinds of background work.
## High-level vs. Low-level APIs
The background processing strategies and APIs are quite different on the Android and iOS platforms. The `flt_worker` plugin manages to provide a unified yet simplified API for general tasks, as the above example.
However, to leverage the full power of each platform's background processing features, you may consider the low-level platform-specific APIs.
For example, you can schedule a periodic work using the `WorkManager` APIs on an Android device:
```dart
import 'package:flt_worker/android.dart';Future _startPolling() async {
await cancelAllWorkByTag('tag'); // cancel the previous work
await enqueueWorkRequest(const PeriodicWorkRequest(
repeatInterval: Duration(hours: 4),
flexInterval: Duration(minutes: 5),
tags: ['tag'],
constraints: WorkConstraints(
networkType: NetworkType.connected,
storageNotLow: true,
),
backoffCriteria: BackoffCriteria(
policy: BackoffPolicy.linear,
delay: Duration(minutes: 1),
),
));
}
```Or to use the `BackgroundTasks` APIs on iOS 13.0+:
```dart
import 'package:flt_worker/ios.dart';void _increaseCounter(int counter) {
submitTaskRequest(BGProcessingTaskRequest(
'com.example.counter_task',
earliestBeginDate: DateTime.now().add(Duration(seconds: 10)),
requiresNetworkConnectivity: false,
requiresExternalPower: true,
input: {
'counter': counter,
},
));
}
```## Limitations
It's the very beginning of this library, some limitations you may need to notice are:
- It relies on the `BackgroundTasks` framework, which means it's not working on iOS before `13.0`
- For the Android platform, advanced features of `WorkManager` like [Chaining Work] are not yet supported[github-runs]: https://github.com/xinthink/flt_worker/actions
[check-badge]: https://github.com/xinthink/flt_worker/workflows/check/badge.svg
[codecov-badge]: https://codecov.io/gh/xinthink/flt_worker/branch/master/graph/badge.svg
[codecov]: https://codecov.io/gh/xinthink/flt_worker
[license-badge]: https://img.shields.io/github/license/xinthink/flt_worker
[license]: https://raw.githubusercontent.com/xinthink/flt_worker/master/LICENSE
[pub]: https://pub.dev/packages/flt_worker
[pub-badge]: https://img.shields.io/pub/v/flt_worker.svg
[WorkManager]: https://developer.android.com/topic/libraries/architecture/workmanager
[BackgroundTasks]: https://developer.apple.com/documentation/backgroundtasks
[CallbackHandle]: https://api.flutter.dev/flutter/dart-ui/PluginUtilities/getCallbackHandle.html
[Chaining Work]: https://developer.android.com/topic/libraries/architecture/workmanager/how-to/chain-work