I have flight search feature in my application which is taking too long to get the data (more than 25 seconds). if application goes background or went to sleep mode, internet connection get disconnected.
I have written below logic using apple example to make api request keep going even though if app goes to background but it's not working.
self.session = [self backgroundSession];
self.mutableData = [NSMutableData data];
NSURL *downloadURL = [NSURL URLWithString:@"http://jsonplaceholder.typicode.com/photos"];
NSURLRequest *request = [NSURLRequest requestWithURL:downloadURL];
self.dataTask = [self.session dataTaskWithRequest:request];
[self.dataTask resume];
- (NSURLSession *)backgroundSession
{
static NSURLSession *session = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"com.example.apple-samplecode.SimpleBackgroundTransfer.BackgroundSession"];
session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
});
return session;
}
below are the delegate methods
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
didReceiveResponse:(NSURLResponse *)response
completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler {
NSLog(@"response: %@", response.debugDescription);
NSURLSessionResponseDisposition disposition = NSURLSessionResponseAllow;
if (completionHandler) {
completionHandler(disposition);
}
}
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
didReceiveData:(NSData *)data {
[self.mutableData appendData:data];
}
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
BLog();
if (error == nil)
{
NSData *data = nil;
if (self.mutableData) {
data = [self.mutableData copy];
self.mutableData = nil;
}
NSError* error;
NSArray* json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
if (!json) {
NSLog(@"Error parsing JSON: %@", error);
} else {
NSLog(@"Data: %@", json);
}
}
else
{
NSLog(@"Task: %@ completed with error: %@", task, [error localizedDescription]);
}
double progress = (double)task.countOfBytesReceived / (double)task.countOfBytesExpectedToReceive;
dispatch_async(dispatch_get_main_queue(), ^{
self.progressView.progress = progress;
});
self.dataTask =nil;
}
Everything works fine when application is in foreground but as soon as I put application on background getting below error message.
Completed with error: Lost connection to background transfer service
You cannot use data tasks for background transfers. Those must be done using download tasks:
Download tasks retrieve data in the form of a file, and support background downloads while the app is not running.
This is explained in Apple's documentation.
Also be sure to check out their background transfer considerations:
With background sessions, because the actual transfer is performed by a separate process and because restarting your app’s process is relatively expensive, a few features are unavailable, resulting in the following limitations...
The key here is that it's running in a separate process which cannot access the data you keep in memory. It must be routed through a file.
I collected a lot of information about background transfer on iOS in a (long) blog post.
来源:https://stackoverflow.com/questions/39639268/ios-background-task-using-nsurlsessiondatatask