2

I am trying to run a background NSURLSessionDownloadTask. However, I noticed that it takes approximately 30 seconds before the task actually begins. When I use the defaultSessionConfiguration, the task starts almost immediately. Is there a way to trigger the NSURLSessionDownloadTask immediately when using the backgroundSessionConfiguration?

Below is the result I get when I use backgroundSessionConfiguration:

NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration backgroundSessionConfiguration:[NSString stringWithFormat:bgIdentifier, self.urlModel.code]];

Here are the log output. Note that “Start uploading…” is logged right before calling the “resume” method and “Upload progress” is logged in the NSURLSessionTaskDelegate’s didSendData method.

2014-02-18 20:13:55.403 myapp[396:60b] [DoneViewController] Start uploading...
2014-02-18 20:14:17.699 myapp[396:60b] [DoneViewController] Upload progress - 1%
2014-02-18 20:14:17.704 myapp[396:60b] [DoneViewController] Upload progress - 2%
2014-02-18 20:14:17.705 myapp[396:60b] [DoneViewController] Upload progress - 3%
2014-02-18 20:14:17.706 myapp[396:60b] [DoneViewController] Upload progress - 4%

Just for reference, the same thing but with the default session configuration.

NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];

You can see there is no delay on console result is like this:

2014-02-18 19:57:00.552 myapp[376:60b] [DoneViewController] Start uploading...
2014-02-18 19:57:00.707 myapp[376:60b] [DoneViewController] Upload progress - 2%
2014-02-18 19:57:00.710 myapp[376:60b] [DoneViewController] Upload progress - 5%
2014-02-18 19:57:00.711 myapp[376:60b] [DoneViewController] Upload progress - 8%
2014-02-18 19:57:00.711 myapp[376:60b] [DoneViewController] Upload progress - 11%

Edit: With iOS 7.1, there are times when there are no delays. However, there are still times where there are about 20 second delays.

jhk
  • 261
  • 3
  • 13
  • are u downloading multiple files at a time ? – ChenSmile Feb 19 '14 at 04:48
  • @Immi nope. In both cases I ran the app from scratch to make sure there were no lingering sessions. – jhk Feb 19 '14 at 06:05
  • 1
    Why do you care about the delay? "Background" means "Hey, system, please do this on your own, whenever it's convenient". If you don't want that, don't do that. – matt Feb 19 '14 at 06:33
  • @matt ya this is also right – ChenSmile Feb 19 '14 at 06:36
  • @matt i just bought ur book for iOS 7 Programming Fundamentals. it cleared my lots of doubt. Appreciate your work.. – ChenSmile Feb 19 '14 at 06:38
  • @Immi hey cool thanks - I'm really glad if I could help out – matt Feb 19 '14 at 06:39
  • @user960112 check my answer. hope it ll resolve ur delay problem – ChenSmile Feb 19 '14 at 06:58
  • @matt appreciate for the reply. My intentions were to start updating the my upload progress right away to let the end user know that the action is being worked on. At the same time I still wanted keep it a background job in order to keep the session alive if the end user exits out of the app. I played around with a static label to the end user but I feel that a live updating one felt most responsive. – jhk Feb 19 '14 at 07:39

3 Answers3

3

Though Apple doesn't document it at all, this is how background sessions are designed. You simply cannot take over the network connection while another app is running. iOS/Apple is in charge of running your background uploads/downloads in the way it feels will provide the best user experience. Imagine being the running app and having the network connection clogged by another app while trying to make basic HTTP calls. I've written more about my experience and when to use this feature. https://medium.com/@KyleRStewart/zombie-uploads-with-ios-dd3b1f6b66

KyleStew
  • 420
  • 1
  • 5
  • 14
  • This actually is documented by Apple in a description of method `+[NSURLSessionConfiguration backgroundSessionConfiguration:]`: "Sessions created with configuration objects returned by this method are called background sessions. These sessions differ from other sessions in the following ways: Upload and download tasks in background sessions are performed by an external daemon instead of by the app itself. As a result, the transfers continue in the background even if the app is suspended, exits, or crashes." – Max Desiatov Jul 27 '14 at 09:33
  • 1
    Best answer. Looks like with iOS 8 beta 5 they added a way to add priority (NSURLSessionTaskPriorityDefault, NSURLSessionTaskPriorityLow, or NSURLSessionTaskPriorityHigh) to the background config. https://developer.apple.com/library/prerelease/ios/releasenotes/General/RN-iOSSDK-8.0/ – jhk Aug 11 '14 at 20:14
0
-(NSURLSession *)backgroundSession // For Background Download
{
static NSURLSession *backgroundSession = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration backgroundSessionConfiguration:@"com.shinobicontrols.BackgroundDownload.BackgroundSession"];
    backgroundSession = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];
});
return backgroundSession;
}

For More check this LINK. You can see here there are various methods of downloading. I hope you'll get your solution here.

ChenSmile
  • 3,401
  • 4
  • 39
  • 69
  • Thanks for the answer @Immi! Unfortunately I've tried this before posing the question but it did not help. I even tried playing with the delegateQueue without any luck. – jhk Feb 19 '14 at 07:41
  • @user960112 so i ll suggest u. don't care delay..because ultimately it gets start downloading. – ChenSmile Feb 19 '14 at 07:43
  • Thanks for the suggestion. :) That is the solution I've gone with after pulling on my hair all day. I posted this question in hopes to see if anyone was able to make a background NSURLSession task to start immediately. That would let me get the ideal UX I want. – jhk Feb 19 '14 at 08:01
  • Sorry @Immi, but you didn't answer the question. Your answer just gives an example of how to set up a NSURLSession background task. – jhk Feb 19 '14 at 19:13
0

Can you try this?

config.discretionary = NO;

According to the docs, it:

determines whether background tasks can be scheduled at the discretion of the system for optimal performance.

Caveat: you can only do this while the app is in the foreground.

https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSURLSessionConfiguration_class/Reference/Reference.html#//apple_ref/doc/uid/TP40013440-CH1-SW31

Isak
  • 1,591
  • 1
  • 17
  • 23
  • Thanks for answering! Unfortunately, this was not the case. I had it set to NO. – jhk Jul 30 '14 at 02:04