Need to delay a background download.

I have a situation where I need to download a list of large files, one at a time. My existing strategy is to use the completion callback of one download to begin the next, continuing until the list is empty.

In general, this works fine whether the app is in the foreground or background.


The problem arises when the server reports some error with handling the request while the app is in the background and the error is deemed recoverable (too busy, for example).


The behaviour I'd like is to delay a random value in the range of 0.5 to 3.0 minutes and then re-issue the request. However, I know that there's a very limited amount of time allowed before the app must return from the callback or it will be terminated. (10 seconds?) Additionally, this should happen without any user involvement because the most likely usecase is that the user queues up a list of downloads and walks away, or goes to sleep....


Returning from the callback without issuing another request means not getting an opportunity to process the rest of the list until the app is brought to the foreground again.


What I need is something that acts as if it were a resumeAfter: or suspendUntil: method on NSURLSessionTask.

Suggestions?

Replies

My existing strategy is to use the completion callback of one download to begin the next, continuing until the list is empty.

This approach is not without its pitfalls; see NSURLSession’s Resume Rate Limiter for details.

What I need is something that acts as if it were a resumeAfter: or suspendUntil: method on NSURLSessionTask.

To be clear, iOS has no general-purpose ‘resume me at this time’ mechanism.

However, I know that there's a very limited amount of time allowed before the app must return from the callback or it will be terminated. (10 seconds?)

Something like that. However, you can use a UIApplication background task to keep your app running after it’s returned from that callback. That’ll give you up to 30 seconds of execution time, which gets you close to the lower bound of your requirement.

Beyond that, I think we’re in enhancement request territory. For example, it would be nice if you could:

  • specify a target start time for a task in an NSURLSession background session

  • dependencies between such tasks (don’t start this until you’ve completed this)

  • priorities for tasks (do all the members of this group before starting on members of this group)

and so on.

ps If you do file any enhancements requests like this, please post your bug number, just for the record.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

I understand that the download strategy has problems but, since the files being downloaded are individually useful, batching the list would be a poor UX.


"To be clear, iOS has no general-purpose ‘resume me at this time’ mechanism."

Oh, we've noticed! 🙂

(It sometimes feels as if providing any feature that does not involve a human tapping on glass is a high-risk venture.)


Thank you very much (as usual!) for your clarification of the situation and suggestions.


I'll think about the enhancement request; it does seem that some queue-like control over the session might be generally useful.

Submitted as issue 28563854.