Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Weird NSURLSessionDownloadTask behavior over cellular (not wifi)

I've enabled Background Modes with remote-notification tasks to download a small file (100kb) in background when the app receives a push notification. I've configured the download Session using

NSURLSessionConfiguration *backgroundConfiguration = [NSURLSessionConfiguration backgroundSessionConfiguration:sessionIdentifier];
[backgroundConfiguration setAllowsCellularAccess:YES];


self.backgroundSession = [NSURLSession sessionWithConfiguration:backgroundConfiguration
                                                       delegate:self
                                                  delegateQueue:[NSOperationQueue mainQueue]];

and activate it using

 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[hostComponents URL]];

[request setAllowsCellularAccess:YES];


NSMutableData *bodyMutableData = [NSMutableData data];
[bodyMutableData appendData:[params dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPMethod:@"POST"];
[request setHTTPBody:[bodyMutableData copy]];


_downloadTask =  [self.backgroundSession downloadTaskWithRequest:request];

[self.downloadTask resume];

Now everything works correctly only if I'm connected over Wifi or over Cellular but with the iPhone connected with the cable to xCode, if I disconnect the iPhone and receive a push notification over cellular the code stop at [self.downloadTask resume]; line without call the URL.

The class that handles these operation is a NSURLSessionDataDelegate, NSURLSessionDownloadDelegate, NSURLSessionTaskDelegate and so implements:

    - (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location

I've try to insert a debug line with a UILocalNotification (presented 'now') after the [self.downloadTask resume] but is called after 5 minutes and says that the self.downloadTask.state is 'suspended'

What is due this weird behavior ?

like image 926
Cers Avatar asked Jul 09 '14 23:07

Cers


2 Answers

I got the same problem ,finally i set

configuration.discretionary = NO;

the everything works fine, for backgroundConfiguration , discretionary = YES default, it seems the task begin in connection with WIFI and battery both. hope helpful

like image 66
jiangzf Avatar answered Sep 24 '22 11:09

jiangzf


The documentation for NSURLSessionConfiguration Class Reference here:

https://developer.apple.com/Library/ios/documentation/Foundation/Reference/NSURLSessionConfiguration_class/Reference/Reference.html#//apple_ref/occ/instp/NSURLSessionConfiguration/discretionary

Says: for the discretionary property:

Discussion

When this flag is set, transfers are more likely to occur when plugged into power and on Wi-Fi. This value is false by default.

This property is used only if a session’s configuration object was originally constructed by calling the backgroundSessionConfiguration: method, and only for tasks started while the app is in the foreground. If a task is started while the app is in the background, that task is treated as though discretionary were true, regardless of the actual value of this property. For sessions created based on other configurations, this property is ignored.

This seems to imply that if a download is started in the background the OS always has discretion as to whether and when to proceed with the download. It seems that the OS is always waiting for a wifi connection before completing these tasks.

My experience supports this conjecture. I find that I can send several notifications for downloads while device is on cellular. They remain stuck. When I switch the device to wifi they all go through.

like image 38
Sani Elfishawy Avatar answered Sep 22 '22 11:09

Sani Elfishawy