iOS后台任务使用NSURLSessionDataTask

时间:2016-09-22 12:37:00

标签: ios background-task nsurlsessiondatatask

我的应用程序中有飞行搜索功能,这需要很长时间才能获取数据(超过25秒)。如果应用程序进入后台或进入睡眠模式,则互联网连接将断开连接。

我已经使用apple示例编写了下面的逻辑来使api请求继续运行,即使应用程序转到后台但它不起作用。

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;
}

以下是委托方法

- (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;
}

当应用程序处于前台时,一切正常,但只要我将应用程序放在后台,就会出现错误消息。

  

错误已完成:与后台传输服务的连接丢失

1 个答案:

答案 0 :(得分:6)

您无法将数据任务用于后台传输。这些必须使用下载任务完成:

  

下载任务以文件的形式检索数据,并提供支持   应用程序未运行时下载后台。

这在Apple的documentation中有解释。

另请务必查看他们的background transfer considerations

  

使用后台会话,因为实际传输是通过执行的   一个单独的进程,因为重新启动应用程序的进程是   相对昂贵,一些功能不可用,导致了   以下限制......

这里的关键是它在一个单独的进程中运行,该进程无法访问您保留在内存中的数据。它必须通过文件路由。

我在(长)blog post中收集了很多关于iOS背景传输的信息。