Continue Uploading Process in Background iOS

Continue uploading process in background IOS

You need to ask the OS to keep the app running, it has nothing to do with Dropbox... When you start uploading, do this:

UIBackgroundTaskIdentifier bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:bgTask];
}];

... and store the bgTask somewhere. Then when your upload completes or fails, do this:

[[UIApplication sharedApplication] endBackgroundTask:bgTask];

That will tell the OS to keep your app running because there's a background task running...

Background upload of large amount of data

Unfortunately, Apple's APIs are terrible at this task because of bad design decisions. There are a couple of major obstacles that you face:

  • There are limits to how many simultaneous tasks you can create. I think performance starts to break down at somewhere on the order of 100 tasks.
  • There are limits to how often the OS will wake your app up. The more often it wakes your app, the longer it will wait before waking it again. At some point, this will result in not being able to schedule new tasks.
  • Uploads don't continue from where they left off in the event of a failure; they restart. This can result in huge bandwidth costs on a bad network.

I suspect that the best approach is to:

  • Chunk the requests into several large groups, each of which can be written to a single ZIP archive that is not so big that the user runs out of disk space, but not so small that it uploads too quickly.
  • Write the first set of those files into a single file (e.g. in ZIP format).
  • Use a custom script on the server side that lets you resume uploads from where it left off by adding extra CGI parameters.
  • On failure, ask the server how much data it got, then truncate the front of the file and reupload from the current spot.
  • On success, compute how quickly the first large file finished uploading, and if it is not O(minutes), combine the next few sets. Write the set/sets to a file, and start the next request.

With the caveat that all of this must be done fairly quickly. You may find it necessary to pre-combine the files into ZIP archives ahead of time to avoid getting killed. But do not be tempted to combine them into a single file, because then you'll take too long when truncating the head on retry. (Ostensibly, you could also provide any parameters as part of the URL, and make the POST body be raw data, and provide a file stream to read from the ZIP archive starting at an offset.)

If you're not banging your head against a wall already, you soon will be. :-)

How do you extend an iOS app's background execution time when continuing an upload operation?

You have stumbled across a less-than-stellar code sample in Apple’s documentation.

  • First, if you perform a synchronous network request, you definitely should dispatch it to a background queue. If you don't, you risk having the watchdog process kill your app. But you shouldn’t dispatch the network request synchronously to the global queue, but rather asynchronously, or else you just end up with the same problem, namely blocking the main thread.

  • That having been said, one really should never perform network requests synchronously. You should perform them asynchronously and end the background task in the completion handler.

  • In that example, they use NSData, which we don’t use anymore.

  • Also UIBackgroundTaskInvalid doesn’t exist anymore. It is now UIBackgroundTaskIdentifier.invalid.

  • In Apple’s defense, the point of this code sample is the background task, not the network code. They really didn’t want to get into the weeds of the implementation of this network code and were trying to keep it simple. That having been said, it really is a horrible and outdated code example.

See this answer for a better example of how one might use background tasks. Also, if the upload might take more than 30 seconds, we wouldn’t use the background task at all, but a proper (but more complicated) background URLSession. (See Downloading files in the background. Upload tasks follow the same basic pattern outlined there, though make sure to upload from a file, not a Data.)



Related Topics



Leave a reply



Submit