{"id":16198109,"url":"https://github.com/xinthink/flt_worker","last_synced_at":"2025-03-19T05:30:33.304Z","repository":{"id":53021985,"uuid":"251587064","full_name":"xinthink/flt_worker","owner":"xinthink","description":"Schedule \u0026 run Dart code in the background on both Android \u0026 iOS","archived":false,"fork":false,"pushed_at":"2021-04-09T09:13:25.000Z","size":159,"stargazers_count":28,"open_issues_count":10,"forks_count":8,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-17T03:51:19.927Z","etag":null,"topics":["background-processing","background-tasks","flutter","workmanager"],"latest_commit_sha":null,"homepage":"","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xinthink.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-03-31T11:47:09.000Z","updated_at":"2023-03-30T13:07:36.000Z","dependencies_parsed_at":"2022-09-05T01:50:58.295Z","dependency_job_id":null,"html_url":"https://github.com/xinthink/flt_worker","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xinthink%2Fflt_worker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xinthink%2Fflt_worker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xinthink%2Fflt_worker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xinthink%2Fflt_worker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xinthink","download_url":"https://codeload.github.com/xinthink/flt_worker/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244364570,"owners_count":20441457,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["background-processing","background-tasks","flutter","workmanager"],"created_at":"2024-10-10T09:11:22.953Z","updated_at":"2025-03-19T05:30:32.869Z","avatar_url":"https://github.com/xinthink.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"# flt_worker\n\n[![Pub][pub-badge]][pub]\n[![Check Status][check-badge]][github-runs]\n[![MIT][license-badge]][license]\n\nThe `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.\n\nBackground 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.\n\n## Integration\n\nAdd a dependency to `pubspec.yaml`:\n```yaml\ndependencies:\n  flt_worker: ^0.1.0\n```\n\nA 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.\n\niOS:\n```obj-c\n- (BOOL)application:(UIApplication *)application\n    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {\n  [GeneratedPluginRegistrant registerWithRegistry:self];\n\n  // set a callback to register all plugins to a headless engine instance\n  FltWorkerPlugin.registerPlugins = ^(NSObject\u003cFlutterPluginRegistry\u003e *registry) {\n    [FLTPathProviderPlugin registerWithRegistrar:[registry registrarForPlugin:@\"FLTPathProviderPlugin\"]];\n  };\n  ...\n}\n```\n\nAndroid:\n```java\n@Override\npublic void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {\n  GeneratedPluginRegistrant.registerWith(flutterEngine);\n\n  // set a callback to register all plugins to a headless engine instance\n  FltWorkerPlugin.registerPluginsForWorkers = registry -\u003e {\n    io.flutter.plugins.pathprovider.PathProviderPlugin.registerWith(\n        registry.registrarFor(\"io.flutter.plugins.pathprovider.PathProviderPlugin\"));\n    return null;\n  };\n}\n```\n\nFortunately, `flt_worker` itself is always available for the worker, so you don't have to register it again.\n\nOne more thing has to be done if you're working on iOS: all task identifiers must be registered before you can subimit any `BGTaskRequest`.\n\nAdd lines like this to the `Info.plist` file:\n\n```xml\n\u003ckey\u003eBGTaskSchedulerPermittedIdentifiers\u003c/key\u003e\n\u003carray\u003e\n  \u003cstring\u003ecom.example.counter_task\u003c/string\u003e\n  \u003cstring\u003edev.example.task2\u003c/string\u003e\n  ...\n\u003c/array\u003e\n```\n\n## Usage\n\n### Initialization \u0026 work dispatcher\n\nBefore you can schedule background tasks, a worker callback must be registerted to the plugin:\n\n```dart\nimport 'package:flt_worker/flt_worker.dart';\n\nvoid main() {\n  runApp(MyApp());\n  initializeWorker(worker);\n}\n```\n\nPlease notice that the callback must be a [top-level or static function][CallbackHandle].\n\nThe `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.\n\n```dart\nFuture\u003cvoid\u003e worker(WorkPayload payload) {\n  if (payload.tags.contains('download')) {\n    return _fetchData();\n  } else if (...) {\n    ...\n  } else {\n    return Future.value();\n  }\n}\n\n/// Cache data for offline use\nFuture\u003cvoid\u003e _fetchData() async {\n  // fetch data \u0026 update local storage\n}\n```\n\n### Scheduling work\n\nYou can use the `enqueueWorkIntent` function to schedule a background `WorkIntent` like this:\n\n```dart\nenqueueWorkIntent(WorkIntent(\n  identifier: 'counter',\n  initialDelay: Duration(seconds: 59),\n  input: \u003cString, dynamic\u003e{\n    'counter': counter,\n  },\n));\n```\n\nThe name of `WorkIntent` is chosen to avoid conflict with the term `WorkRequest` from the [WorkManager] API for Android.\n\nPlease see the documentation and also the example app to find out how to schedule different kinds of background work.\n\n## High-level vs. Low-level APIs\n\nThe 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.\n\nHowever, to leverage the full power of each platform's background processing features, you may consider the low-level platform-specific APIs.\n\nFor example, you can schedule a periodic work using the `WorkManager` APIs on an Android device:\n\n```dart\nimport 'package:flt_worker/android.dart';\n\nFuture\u003cvoid\u003e _startPolling() async {\n  await cancelAllWorkByTag('tag'); // cancel the previous work\n  await enqueueWorkRequest(const PeriodicWorkRequest(\n    repeatInterval: Duration(hours: 4),\n    flexInterval: Duration(minutes: 5),\n    tags: ['tag'],\n    constraints: WorkConstraints(\n      networkType: NetworkType.connected,\n      storageNotLow: true,\n    ),\n    backoffCriteria: BackoffCriteria(\n      policy: BackoffPolicy.linear,\n      delay: Duration(minutes: 1),\n    ),\n  ));\n}\n```\n\nOr to use the `BackgroundTasks` APIs on iOS 13.0+:\n\n```dart\nimport 'package:flt_worker/ios.dart';\n\nvoid _increaseCounter(int counter) {\n  submitTaskRequest(BGProcessingTaskRequest(\n    'com.example.counter_task',\n    earliestBeginDate: DateTime.now().add(Duration(seconds: 10)),\n    requiresNetworkConnectivity: false,\n    requiresExternalPower: true,\n    input: \u003cString, dynamic\u003e{\n      'counter': counter,\n    },\n  ));\n}\n```\n\n## Limitations\n\nIt's the very beginning of this library, some limitations you may need to notice are:\n\n- It relies on the `BackgroundTasks` framework, which means it's not working on iOS before `13.0`\n- For the Android platform, advanced features of `WorkManager` like [Chaining Work] are not yet supported\n\n[github-runs]: https://github.com/xinthink/flt_worker/actions\n[check-badge]: https://github.com/xinthink/flt_worker/workflows/check/badge.svg\n[codecov-badge]: https://codecov.io/gh/xinthink/flt_worker/branch/master/graph/badge.svg\n[codecov]: https://codecov.io/gh/xinthink/flt_worker\n[license-badge]: https://img.shields.io/github/license/xinthink/flt_worker\n[license]: https://raw.githubusercontent.com/xinthink/flt_worker/master/LICENSE\n[pub]: https://pub.dev/packages/flt_worker\n[pub-badge]: https://img.shields.io/pub/v/flt_worker.svg\n[WorkManager]: https://developer.android.com/topic/libraries/architecture/workmanager\n[BackgroundTasks]: https://developer.apple.com/documentation/backgroundtasks\n[CallbackHandle]: https://api.flutter.dev/flutter/dart-ui/PluginUtilities/getCallbackHandle.html\n[Chaining Work]: https://developer.android.com/topic/libraries/architecture/workmanager/how-to/chain-work\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxinthink%2Fflt_worker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxinthink%2Fflt_worker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxinthink%2Fflt_worker/lists"}