I am running a background NSURLSession session and i am trying to figure out a way to get the JSON response out of one of the NSURLDownloadTaskDelegate callbacks. I have configured my session to accept JSON responses.
NSURLSessionConfiguration *backgroundSession = [NSURLSessionConfiguration backgroundSessionConfiguration:@"com.Att.Locker.BackgroundUpload"];
backgroundSession.HTTPAdditionalHeaders = @{ @"Accept":@"application/json"};
session = [NSURLSession sessionWithConfiguration:backgroundSession delegate:uploader delegateQueue:nil];
I can easily parse JSON response for NSURLSessionDownloadTasks using the following callback. It writes the JSON response onto the sandbox in the form of NSURL.
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location {
//Reading the Json response from the sandbox using the NSURL parameter
}
My problem is if i encounter an error the callback above is not called, it seems to only get invoked in case of a successful download. Since i am using a background session i cannot use any of the NSURLSessionDataDelegate callbacks. I can only use the NSURLSessionDownloadTaskDelegate and NSURLSessionTaskDelegate and while i can get the task response using the following callback. I don't see the JSON in the response.
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
NSHTTPURLResponse *response = (NSHTTPURLResponse *)downloadTask.response;
NSDictionary *httpResponse = [response allHeaderFields];
NSLog(@"Response Header Fields:%@",[httpResponse allKeys]);
}
NSURLConnection has a didReceiveData parameter which gives us an NSData object which we can use to get the JSON response. I don't see that in the delegate callbacks for NSURLSession except for NSURLDataTask but we cant use data tasks in the background so how are we supposed to get the JSON response out ? Any help is appreciated
EDIT:
I usually experience this issue while i am running the app in the background (mostly when it is kicked out memory and not just suspended). I have implemented the callbacks in the appDelegate and i am able to re associate with the session.I think didFinishDownloadingToURL is only invoked in case of successful completion of a task but when a task fails there is no guarantee its going to be called but on the other hand didCompleteWithError gets called every time there is a failure
Using a download task, you can get the data using the didFinishDownloadingToURL
as you stated.
All NSURLSession tasks have this delegate as well. If you get in here and error is not nil, then walah you have an error. It does not need to complete to get in here. If it does get in here with an error, then the delegate didFinishDownloadingToURL
will not be called.
If there is no error, and all of your data downloads, than both delegates will be called.
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
NSLog(@"didCompleteWithError");
}
EDIT:
So something has to bet not setup correctly as there has to be a way to get the data.
Are you implementing application:handleEventsForBackgroundURLSession:completionHandler: in your AppDelegate which will hook your app back up to the completion handler to get the delegate calls?
I highly recommend watching the 2013 WWDC session #705, "Whats New in Foundation Networking". Background session talk begins at around 32 minutes, and the code demo begins around 37:50
来源:https://stackoverflow.com/questions/19547897/nsurlsessiondownloadtaskdelegate-json-response