Реализация Background Fetch для обновления данных в фоне
Пользователь открывает приложение и видит актуальные данные — без ожидания загрузки. Это результат фоновой синхронизации, сделанной правильно. Сделанной неправильно — это разряженная батарея и жалобы пользователей.
iOS: BGAppRefreshTask
С iOS 13 Apple перевела фоновое обновление на BackgroundTasks framework. Старый UIApplication.setMinimumBackgroundFetchInterval работает, но deprecated.
Регистрация задачи:
BGTaskScheduler.shared.register(
forTaskWithIdentifier: "com.myapp.refresh",
using: nil
) { task in
self.handleAppRefresh(task: task as! BGAppRefreshTask)
}
Идентификатор должен быть прописан в Info.plist в ключе BGTaskSchedulerPermittedIdentifiers. Без этого задача не зарегистрируется — ошибки не будет, просто ничего не произойдёт. Это типичная ошибка при первой реализации.
Планирование следующего запуска происходит в конце текущего выполнения через BGAppRefreshTaskRequest. Минимальный интервал задаётся earliestBeginDate, но iOS решает когда реально запустить задачу — с учётом батареи, паттернов использования, заряда. Гарантии конкретного времени нет.
Важно: у фоновой задачи есть лимит CPU-времени. Если задача не завершилась вовремя, система вызывает task.expirationHandler. Нужно сохранить прогресс и вызвать task.setTaskCompleted(success: false).
Android: WorkManager
WorkManager — правильный инструмент для периодических задач на Android. Заменяет JobScheduler, AlarmManager и SyncAdapter в большинстве случаев.
val refreshRequest = PeriodicWorkRequestBuilder<DataRefreshWorker>(
repeatInterval = 1,
repeatIntervalTimeUnit = TimeUnit.HOURS,
flexTimeInterval = 15,
flexTimeIntervalUnit = TimeUnit.MINUTES
)
.setConstraints(
Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresBatteryNotLow(true)
.build()
)
.build()
WorkManager.getInstance(context).enqueueUniquePeriodicWork(
"data_refresh",
ExistingPeriodicWorkPolicy.KEEP,
refreshRequest
)
ExistingPeriodicWorkPolicy.KEEP — не перезаписывает существующую задачу при повторном вызове enqueue. Это важно при каждом запуске приложения.
Минимальный интервал для PeriodicWorkRequest — 15 минут. Меньше система не позволит.
Что делать в фоновой задаче
Фоновая задача должна быть минимальной: запросить только то, что изменилось (incremental sync), сохранить в локальную базу (Room / Core Data), отправить локальное уведомление если есть важные изменения.
Не делайте в фоновой задаче: тяжёлые вычисления, большие HTTP-запросы без таймаута, синхронную работу с UI-слоем.
React Native и Flutter
В React Native фоновые задачи реализуются через нативные модули. Библиотека react-native-background-fetch оборачивает BGAppRefreshTask на iOS и JobScheduler/WorkManager на Android в единый JS API.
В Flutter — workmanager плагин для Android, background_fetch для iOS. Ограничения те же что у нативных платформ — абстракция не убирает платформенные constraints.
Сроки реализации: 3-5 дней для одной платформы, 1-1.5 недели для iOS + Android с тестированием граничных случаев (батарея, нет сети, Doze Mode на Android).







