Реалізація 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. Обмеження такі ж, як у нативних платформ — абстракція не усуває платформені обмеження.
Терміни реалізації: 3-5 днів для однієї платформи, 1-1.5 тижні для iOS + Android з тестуванням граничних випадків (батарея, немає мережі, Doze Mode на Android).







