iOS background task using NSURLSessionDataTask

寵の児 提交于 2019-12-22 00:40:39

问题


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


回答1:


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!