Надёжная фоновая загрузка и скачивание на 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 рабочих дней в зависимости от сложности и необходимости интеграции с бэкендом. Стоимость рассчитывается индивидуально на основе объёма работ. Обратитесь к нам, и мы реализуем надёжную фоновую передачу.