We have configured NSULRSession

- (NSURLSession *)downloadSession
{
    static NSURLSession *session = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{

        NSOperationQueue *delegateQueue = [[NSOperationQueue alloc] init];

        NSString *identifier = ORDERS_DOWNLOADER_SESSION_IDENTIFIER;
        NSURLSessionConfiguration* sessionConfig = [NSURLSessionConfiguration backgroundSessionConfiguration:identifier];
        session = [NSURLSession sessionWithConfiguration:sessionConfig
                                                                delegate:self
                                                           delegateQueue:delegateQueue];
    });

    return session;
}

On iOS 7.0.x built no SDK 7.0 and 7.1. Problem doesn't appears on iOS 7.1.

We often can see the following:

  • start performing background downloading

    [AppDelegate application:performFetchWithCompletionHandler:]

  • But after 30 seconds we don't have any callbacks to our delegate.

We have implemented

 - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error

 - (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session

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

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

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

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
willPerformHTTPRedirection:(NSHTTPURLResponse *)response
        newRequest:(NSURLRequest *)request
 completionHandler:(void (^)(NSURLRequest *))completionHandler

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
 needNewBodyStream:(void (^)(NSInputStream *bodyStream))completionHandler

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
   didSendBodyData:(int64_t)bytesSent
    totalBytesSent:(int64_t)totalBytesSent
totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend
  • We don't have any callbacks on it.

What may be wrong? It looks like iOS 7.0.x problem. Is there any good workarounds?

有帮助吗?

解决方案

That is an issue of iOS

more info here: https://devforums.apple.com/message/926113#926113

Any solutions / workarounds? I'm seeing the same problem.

Tested using a basic [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"..."]] and -downloadTaskWithRequest:

A couple of observations:

  1. The very first time the app calls -downloadTaskWithRequest: it works perfectly.

  2. Subsequent calls to -downloadTaskWithRequest: return nil, until the app is killed.

Now we have only one workaround: Multiple calls of task creation method. And it works for us! Usually it has effect on second-third time.

_task = [[self downloadSession] downloadTaskWithRequest:request completionHandler:nil];

// Workaround to solve issue https://devforums.apple.com/message/926113
// Occurs consistently on iOS 7.0.5 and lower
// Sometimes _task may not be initialized, so we try again:
if (!_task)
{
    for (int i = 0; i < 5; i++)
    {
        NSLog(@"%s, attempt #%d to recreate download task", __func__, i + 1);

        _task = [[self downloadSession] downloadTaskWithRequest:request completionHandler:nil];
        if (_task)
        {
            break;
        }
    }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top