0

I try to download a zip-archive using NSURLSessionDataTask. I am aware that there is a NSURLSessionDownloadTask, but the point is I want a didReceiveData callback (to show the progress).

The code is:

NSURLRequest *request = [NSURLRequest requestWithURL:@"..."
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];

NSURLSessionConfiguration* config = [NSURLSessionConfiguration defaultSessionConfiguration];
NSOperationQueue *myQueue = [NSOperationQueue new];
myQueue.underlyingQueue = dispatch_get_main_queue();

NSURLSession *session = [NSURLSession sessionWithConfiguration:config
delegate:self 
delegateQueue:myQueue];

NSURLSessionDataTask* task = [session dataTaskWithRequest:request
completionHandler:^( NSData *data, NSURLResponse *response, NSError *error){ ... }

[task resume];

My class conforms to NSURLSessionDataDelegate.

When I call the method, after several seconds debugger goes to completionHandler with nil data and nil error. What am I doing wrong?

I also tried:

  • calling without completionHandler, then debugger goes to didReceiveResponse callback with 200 response and that's all.
  • using [NSOperationQueue new] for the queue
  • using [NSURLSession sharedSession] - didn't get any response
  • using [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier: @"..."] - falls saying that I can't use a completionHandler, but without it - also no response.
Milan Nosáľ
  • 19,169
  • 4
  • 55
  • 90
annaoomph
  • 552
  • 1
  • 4
  • 22
  • You got two options: 1) Use delegate and implement the necessary delegate methods 2) Use completion handler. The options are **not** mixable. `didReceiveData` belongs to *delegate*. `dataTaskWithRequest:completionHandler:` belongs to *completion handler* – vadian Jun 27 '18 at 11:11
  • Yeah but even if I'm using one of them it doesn't send me any data. – annaoomph Jun 27 '18 at 11:14
  • Basically *callback with 200* is good. Did you implement the other delegate methods which pass the data? – vadian Jun 27 '18 at 11:15
  • Yes I implemented this one: `- (void)URLSession:(NSURLSession *) session dataTask:(NSURLSessionDataTask *) dataTask didReceiveData:(NSData *)data` – annaoomph Jun 27 '18 at 11:17
  • At least implement also `didFailWithError` to get a possible error. – vadian Jun 27 '18 at 11:23
  • I did that, too – annaoomph Jun 27 '18 at 11:25
  • It says `lost connection to background trasnfer service`, so that's already something... – annaoomph Jun 27 '18 at 11:26
  • Maybe the `main` operation queue breaks the (background) functionality. Try `NSOperationQueue.currentQueue` – vadian Jun 27 '18 at 11:29
  • Tried. Still it sends me 200 and then nothing. – annaoomph Jun 27 '18 at 13:00
  • Maybe this is useful: https://stackoverflow.com/questions/39390388/urlsessiontask-runs-always-into-an-error ? – koen Jun 27 '18 at 13:08
  • Thanks for the help guys. It seems I have found out what the problem is :) – annaoomph Jun 27 '18 at 14:50

1 Answers1

1

So I have found the answer and it's not quite obvious from documentation: I had several callbacks, and among them didReceiveResponse.

Turns out I have to call completion handler in order for the future callbacks to work, i.e: completionHandler(NSURLSessionResponseAllow);

And one more thing: didCompleteWithError is actually the delegate that tells about successful finish, too, although the name implies that this is the error handler. What it means: when a download is successfully finished, this function is called with error = nil.

Hope this will be useful for somebody someday.

annaoomph
  • 552
  • 1
  • 4
  • 22