NSURLSessionDownloadTask resumes automatically all task while in background
Asked Answered
U

2

2

I have requirement to download files in serial order. Currently I am able to do that while app is in foreground.

Following is the logic I have used.

  1. Create all tasks for downloading.

  2. Resume one at a time and as the current finishes resume the next one from URLSession:task:didCompleteWithError:.

This logic is working while app is in foreground but once app started to run in background(By crashing) and we again run the app before download finishes all the tasks state has been changed to resume and all are downloading at the same time.

Is this the expected behaviour or anything I am missing to order this in serial in background mode too?

Edit: I checked by creating download task one by one. After finishing the first task create next inside setTaskDidCompleteBlock and so on. It only completes the first task and after that session crashed while task created inside setTaskDidCompleteBlock (This happens only when running in background mode, for foreground its working fine).

Here is my crash log screen shots:

drive.google.com/file/d/0B9jFCUPsPtV6YW5zbTJrQ0pQYlk/view?usp=sharing

and

drive.google.com/file/d/0B9jFCUPsPtV6UkEwOURpZmZYcEU/view?usp=sharing

Any help would be appreciated.

Unused answered 13/8, 2015 at 16:32 Comment(0)
T
1

If you absolutely need to run these requests sequentially, I would suggest not instantiating all of these tasks up front, but rather instantiate them one at a time, only instantiating the next one upon the completion of the prior one.

But we must recognize that you pay a significant performance penalty for running the requests sequentially. (And this problem will be magnified when using background sessions.) If at all possible, see if you can change your requests to run concurrently. Clearly, if you need the output of one in order to create the request for another, you're stuck (or at least until your refactor the server code), but that's clearly not the issue here (because you created all of the requests up front). If you're doing this sequential request process for artificial reasons (e.g., the code is populating an array and you want that in order), then you might want to redesign the implementation to remove this artificial constraint.

Typhoid answered 14/8, 2015 at 10:35 Comment(5)
Thank you very much for your suggestions. My files are mainly videos, when user select a clip I have to download four videos. About sequential order: because these four videos in a clip are very close to live telecasting, So my clients wants that in that order. I have also tried to create a new task from setTaskDidCompleteBlock . But it seems that my NSURLSession crashes after the first download (if downloading from back ground, for foreground it is working fine). Is this a good way to instantiate next download task from setTaskDidCompleteBlock ? BTW I am using AFnetworking.Unused
OK, but benchmark it, because if they want them downloaded quickly, it will go much faster if you download them concurrently. But I understand the custom issue. Regarding crashing, we cannot comment on that without details on the crash, your AFNetworking background implementation (a la https://mcmap.net/q/336303/-afnetworking-and-background-transfers), etc. That might warrant another question with these details.Typhoid
Okay, right now I am checking this concurrent downloading speed too. I have edited my question with crash logs. If I am not asking for too much could you please have a look at it too.Unused
@Unused - No, I'm afraid those crash logs don't help me (as they're within nsurlsessiond and don't illuminate what in your code caused the crash). I'd actually suggest adding tons of NSLog statements to figure out how far your code got before it crashed. There are tons of possible issues (when you create second request, double check everything looks good before calling resume; make sure you successfully called the completionHandler that was passed to your app delegate; monitor this with Charles etc.). Debugging background NSURLSession ain't always easy.Typhoid
Ok, I understand, I will try as suggested. Really appreciate your help.Unused
E
0

I have seen this happen too. If you create a downloadTask while the app is in the foreground but do not call resume(), it will not start — however, it will start automatically when the app is backgrounded.

The solution is to explicitly call suspend() on each downloadTask when you create it. Then, when you are ready to start downloading it, call resume().

Apparently a newly created downloadTask is neither suspended nor resumed. Its initial state is not .Running, but when the app is backgrounded it is shifted into .Running because it hasn't been explicitly suspended. This is suprising behavior; I don't know why the background session daemon works this way.

Ericson answered 21/3, 2017 at 16:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.