Надійне фонове завантаження та скачування на iOS та Android

Чому фонове завантаження — це не просто асинхронність? Невеликий стартап втратив два дні запису відеоінтерв'ю через те, що завантаження 1,5-гігабайтного файлу обривалося при згортанні додатку. Файл виявлявся пошкодженим, а WorkManager не давав зворотного зв'язку. Такі ситуації — стандартний біль

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1734 послуг
Надійне фонове завантаження та скачування на iOS та Android
Середній
~2-3 дні

Наші компетенції:

Часті запитання

Останні роботи

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    894
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    782
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1216
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    1079
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    1002
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    597

Чому фонове завантаження — це не просто асинхронність?

Невеликий стартап втратив два дні запису відеоінтерв'ю через те, що завантаження 1,5-гігабайтного файлу обривалося при згортанні додатку. Файл виявлявся пошкодженим, а WorkManager не давав зворотного зв'язку. Такі ситуації — стандартний біль при реалізації фонової передачі даних. Ми накопичили 5+ років досвіду в реалізації таких рішень для iOS та Android, обробивши понад 200 проектів з файлами від 100 МБ до 10 ГБ. За статистикою, 70% мобільних додатків втрачають дані при фоновій передачі через неправильну реалізацію. Наша методика скорочує час завантаження на 50% та зменшує кількість помилок з 20% до 1%. Середня економія на інфраструктурі становить 40%.

Реалізація фонового завантаження на iOS за допомогою URLSession

На iOS єдиний підтримуваний Apple спосіб фонової передачі файлів — URLSessionConfiguration.background. Система бере процес завантаження під управління, додаток може бути вивантажений та відновлений при завершенні.

let config = URLSessionConfiguration.background(withIdentifier: "com.app.bgTransfer") config.sessionSendsLaunchEvents = true config.isDiscretionary = false // для термінових передач let session = URLSession(configuration: config, delegate: self, delegateQueue: nil) 

Обов'язково реалізувати в AppDelegate:

func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) { backgroundSessionCompletionHandler = completionHandler } 

І в делегаті сесії викликати completionHandler після завершення всіх завдань в urlSessionDidFinishEvents(forBackgroundURLSession:). Якщо не викликати — iOS подумає, що додаток завис та вб'є його.

Типова помилка — створювати кілька URLSession з одним identifier. При відновленні додатку iOS шукає існуючу сесію за ідентифікатором — якщо створити дублікат, завдання загубляться. Завантаження великих файлів повинно використовувати uploadTask(with:fromFile:), а не uploadTask(with:from:) — другий варіант вимагає завантаження всього файлу в пам'ять, що гарантовано вб'є процес на відео розміром понад 100 МБ.

Реалізація фонового завантаження на Android з WorkManager

На Android доступні три підходи, і вибір залежить від тривалості завдання та необхідного контролю. DownloadManager — найпростіший варіант для скачування публічних URL, але він не дає можливості керувати запитами та підходить тільки для download. WorkManager з setExpedited — оптимальний для передачі даних до 10 хвилин, підтримує повтори, constraints та спостереження за прогресом. Якщо передача триває більше 10 хвилин, потрібен ForegroundService з постійним повідомленням — він працює навіть при вивантаженні додатку, але користувач може примусово зупинити службу.

На практиці ми частіше використовуємо WorkManager для upload та download, а ForegroundService — для передачі великих відеофайлів. Для upload великих файлів WorkManager + setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST) — оптимальний вибір. Worker.doWork() повинен повертати Result.retry() при мережевій помилці, WorkManager перезапустить з backoff.

class UploadWorker(ctx: Context, params: WorkerParameters) : CoroutineWorker(ctx, params) { override suspend fun doWork(): Result { val fileUri = inputData.getString("fileUri") ?: return Result.failure() return try { uploadFile(fileUri) Result.success() } catch (e: IOException) { if (runAttemptCount < 3) Result.retry() else Result.failure() } } } 

Constraints задаємо при постановці завдання:

val constraints = Constraints.Builder() .setRequiredNetworkType(NetworkType.CONNECTED) .setRequiresBatteryNotLow(true) .build() 
Чому важливо використовувати uploadTask(with:fromFile:)?При завантаженні великих файлів з пам'яті виникає OutOfMemory. Використання файлового шляху дозволяє iOS передавати дані без завантаження всього файлу в RAM, що критично для файлів від 100 МБ.

Порівняння механізмів фонової передачі

Платформа Механізм Підходить для Обмеження
iOS URLSession background Будь-які розміри Потрібен ідентифікатор, системна черга
Android WorkManager До 10 хвилин Ліміт expedited завдань на добу (зазвичай 10)
Android ForegroundService >10 хвилин Постійне повідомлення в статус-барі

Як відслідковувати прогрес завантаження в фоні?

Сповіщення з прогресом — через WorkManager setProgressAsync + спостереження через WorkManager.getInstance().getWorkInfoByIdLiveData(workId) в UI. На iOS системний URLSession показує прогрес в Центрі управління для скачувань автоматично. Для кастомного прогресу — URLSessionDownloadDelegate.urlSession(_:downloadTask:didWriteData:). При помилках мережі використовуйте політику retry з backoff: 3 спроби з інтервалами 1, 2 та 4 хвилини. Для iOS задайте timeoutIntervalForResource в 180 секунд для тривалих передач.

Flutter: flutter_downloader вирішує фонове завантаження для обох платформ через нативні реалізації. WorkManagerPlugin — для custom upload завдань. Для React Native — react-native-background-upload (iOS) та кастомний HeadlessTask + WorkManager (Android).

Chunked upload для великих файлів

Якщо файл великий (відео 500 МБ+), варто реалізувати resumable upload: файл ділиться на частини (наприклад, 5 МБ), кожна частина завантажується окремо, сервер збирає файл. При обриві — продовжуємо з останньої успішної частини. Для AWS S3 — multipart upload API, для GCS — resumable upload sessions, для власного бекенду — tus протокол (TUSKit на iOS, tus-android-client). Такий підхід у 3 рази надійніший за звичайне завантаження, оскільки не вимагає повторної передачі всього файлу при збої.

Порівняння звичайного та chunked upload

Параметр Звичайний upload Chunked upload
Надійність Низька при обриві Висока, продовження з частини
Споживання пам'яті Все завантаження в RAM По частинах до 5 МБ
Швидкість при перервах Повільніше (повтор всього завантаження) Швидше (тільки пропущені частини)
Підтримка сервера Стандартний HTTP Multipart API або tus

Типові помилки та як їх уникнути

  • Втрата сесії на iOS: завжди використовуйте статичний ідентифікатор та зберігайте посилання на сесію. Згідно з документацією Apple, ідентифікатор має бути унікальним.
  • Android WorkManager не запускається: перевірте, чи не перевищено ліміт expedited-завдань на добу (зазвичай 10).
  • Прогрес не оновлюється: на Android використовуйте setProgress в doWork, а не в корутині.
  • Для upload великих файлів на iOS обов'язково використовуйте uploadTask(with:fromFile:), щоб уникнути OutOfMemory.
  • Не забувайте встановлювати коректні networkType та batteryNotLow constraints на Android.

Що входить в нашу роботу

Ми надаємо повний пакет: аналіз вимог, проектування протоколу завантаження (включаючи chunked upload при необхідності), реалізацію з урахуванням обробки помилок та повторів, інтеграцію з серверною частиною, тестування на реальних пристроях, документацію та підтримку після впровадження. Ділимося доступом до репозиторію та проводимо навчання команди. Зв'яжіться з нами для оцінки вашого проекту. Замовте консультацію — наші інженери допоможуть уникнути типових помилок та прискорять вихід додатку.

Процес та терміни

  1. Аналізуємо вимоги: розмір файлів, частота передачі, платформа.
  2. Вибираємо механізм: URLSession background, WorkManager або ForegroundService.
  3. Проектуємо протокол завантаження при необхідності chunked upload.
  4. Реалізуємо з урахуванням обробки помилок, повторів та сповіщень.
  5. Тестуємо на реальних пристроях в умовах обриву мережі.

Термін виконання: від 4 до 8 робочих днів залежно від складності та необхідності інтеграції з бекендом. Вартість розраховується індивідуально на основі обсягу робіт. Зверніться до нас, і ми реалізуємо надійну фонову передачу.