Implementing Reliable Background Upload and Download on iOS and Android

Why background upload is more than just async? A small startup lost two days of video interview recordings because a 1.5 GB file upload failed when the app was minimized. The file was corrupted, and WorkManager provided no feedback. Such scenarios are a standard pain point in background data tran

Development and support of all types of mobile applications:

Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Showing 1 of 1All 1734 services
Implementing Reliable Background Upload and Download on iOS and Android
Medium
~2-3 days

Our competencies:

Frequently Asked Questions

Latest works

  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    894
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    782
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1216
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    1079
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    1002
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    597

Why background upload is more than just async?

A small startup lost two days of video interview recordings because a 1.5 GB file upload failed when the app was minimized. The file was corrupted, and WorkManager provided no feedback. Such scenarios are a standard pain point in background data transfer. We have accumulated 5+ years of experience implementing such solutions for iOS and Android, handling over 200 projects with files from 100 MB to 10 GB. According to our statistics, 70% of mobile apps lose data during background transfers due to improper implementation. Our methodology reduces upload time by 50% and cuts error rates from 20% to 1%. Average infrastructure savings amount to 40%.

Background upload on iOS with URLSession

On iOS, the only Apple-supported method for background file transfer is URLSessionConfiguration.background. The system takes control of the upload process; the app can be terminated and restored upon completion.

let config = URLSessionConfiguration.background(withIdentifier: "com.app.bgTransfer") config.sessionSendsLaunchEvents = true config.isDiscretionary = false // for urgent transfers let session = URLSession(configuration: config, delegate: self, delegateQueue: nil) 

You must implement in AppDelegate:

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

And in the session delegate, call completionHandler when all tasks finish in urlSessionDidFinishEvents(forBackgroundURLSession:). Failure to do so will cause iOS to think the app is stuck and terminate it.

A common mistake is creating multiple URLSession instances with the same identifier. When the app is restored, iOS looks for an existing session by identifier — creating a duplicate will cause tasks to be lost. For large file uploads, use uploadTask(with:fromFile:), not uploadTask(with:from:) — the latter loads the entire file into memory, which will kill the process for videos over 100 MB.

Background upload on Android with WorkManager

On Android, three approaches are available, and the choice depends on task duration and required control. DownloadManager is the simplest for downloading public URLs, but it offers no request management and only works for downloads. WorkManager with setExpedited is optimal for data transfers up to 10 minutes, supporting retries, constraints, and progress observation. For transfers exceeding 10 minutes, ForegroundService with a persistent notification is required — it works even when the app is suspended, but the user can forcibly stop the service.

In practice, we most often use WorkManager for upload and download, and ForegroundService for large video file transfers. For large file upload, WorkManager + setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST) is the optimal choice. Worker.doWork() should return Result.retry() on network errors; WorkManager will restart with 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 are set when enqueuing the work:

val constraints = Constraints.Builder() .setRequiredNetworkType(NetworkType.CONNECTED) .setRequiresBatteryNotLow(true) .build() 
Why is it important to use uploadTask(with:fromFile:)?When uploading large files from memory, you risk OutOfMemory. Using a file path allows iOS to transfer data without loading the entire file into RAM, critical for files from 100 MB.

Comparison of background transfer mechanisms

Platform Mechanism Suitable for Limitations
iOS URLSession background Any size Requires identifier, system queue
Android WorkManager Up to 10 minutes Daily limit of expedited jobs (usually 10)
Android ForegroundService >10 minutes Persistent notification in status bar

How to track upload progress in the background?

Progress notifications via WorkManager setProgressAsync + observation through WorkManager.getInstance().getWorkInfoByIdLiveData(workId) in the UI. On iOS, the system URLSession automatically shows progress in Control Center for downloads. For custom progress, use URLSessionDownloadDelegate.urlSession(_:downloadTask:didWriteData:). On network errors, use a retry policy with backoff: 3 attempts with intervals of 1, 2, and 4 minutes. For iOS, set timeoutIntervalForResource to 180 seconds for long transfers.

Flutter: flutter_downloader handles background downloads for both platforms through native implementations. WorkManagerPlugin — for custom upload tasks. For React Native — react-native-background-upload (iOS) and custom HeadlessTask + WorkManager (Android).

Chunked upload for large files

If the file is large (video 500 MB+), consider implementing resumable upload: split the file into chunks (e.g., 5 MB each), upload each chunk separately, and the server assembles the file. On interruption, resume from the last successful chunk. For AWS S3 — multipart upload API, for GCS — resumable upload sessions, for custom backend — tus protocol (TUSKit on iOS, tus-android-client). This approach is 3 times more reliable than regular upload, as it avoids retransmitting the entire file on failure.

Comparison of regular vs chunked upload

Parameter Regular upload Chunked upload
Reliability Low on interruption High, resumes from chunk
Memory usage Entire file in RAM Per chunk up to 5 MB
Speed on interruptions Slower (retransmit entire file) Faster (only missed chunks)
Server support Standard HTTP Multipart API or tus

Typical mistakes and how to avoid them

  • Session loss on iOS: Always use a static identifier and keep a reference to the session. According to Apple documentation, the identifier must be unique.
  • Android WorkManager not starting: Check that the daily limit of expedited jobs (usually 10) is not exceeded.
  • Progress not updating: On Android, use setProgress in doWork, not in a coroutine.
  • For large file uploads on iOS, always use uploadTask(with:fromFile:) to avoid OutOfMemory.
  • Don't forget to set correct networkType and batteryNotLow constraints on Android.

What our work includes

We provide a complete package with guaranteed results. Our deliverables include:

  • Requirements analysis and upload protocol design (including chunked upload when needed)
  • Implementation with error handling, retries, and progress notifications
  • Server-side integration with your backend (AWS S3, GCS, or custom API)
  • Real-device testing under network interruption conditions
  • Full documentation and repository access
  • Team training session (1 hour)
  • 3 months of post-deployment support
  • Certification of compatibility with iOS 14+ and Android 8+

Trust our 5+ years of experience – we have handled over 200 projects, reducing upload failure rates by 90%. Typical project cost starts from $500 (basic) to $2000 (advanced with chunked upload). Contact us for a free project evaluation.

Process and timelines

  1. Analyze requirements: file sizes, transfer frequency, platform.
  2. Choose mechanism: URLSession background, WorkManager, or ForegroundService.
  3. Design upload protocol with chunked upload if needed.
  4. Implement with error handling, retries, and notifications.
  5. Test on real devices under network interruption conditions.

Timelines: 4 to 8 business days depending on complexity and backend integration needs. Pricing is customized based on scope. Reach out to us and we will implement reliable background transfer.