【问题标题】:iOS background task using NSURLSessionDataTask使用 NSURLSessionDataTask 的 iOS 后台任务
【发布时间】:2017-01-31 01:04:35
【问题描述】:

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

我使用苹果示例编写了以下逻辑,以使 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;
}

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

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

【问题讨论】:

  • 您是否尝试过从目标“功能”选项卡中添加后台提取功能?
  • 在 backgroundmodes 中启用后台获取选项。 xcode - 功能 - 背景模式
  • 是的,我这样做了,但我仍然收到相同的错误消息。

标签: ios background-task nsurlsessiondatatask


【解决方案1】:

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

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

Apple 的 documentation 对此进行了解释。

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

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

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

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

【讨论】:

  • 感谢克鲁姆鲁尔!我用下载任务修改了代码,它工作正常。
  • 在下载任务请求后互联网断开连接时,没有调用 didCompleteWithError 委托方法。互联网连接恢复后,它会自动恢复。有没有办法让互联网断开错误消息。
  • 应该支持bg中的数据任务:“在iOS 8和OS X 10.10之前,后台会话中不支持数据任务。” (来自链接的文档)
  • @vonovak 我认为 iOS 11 仍然不支持数据任务。通过创建数据任务然后将应用程序置于后台很容易验证这一点:数据任务将不会运行。不知道为什么苹果把这个令人困惑的行放在文档中。我猜 Apple 的意思是“你不能在 iOS 8 及之前的后台会话中创建 dataTask,但在 iOS 9+ 上你可以创建 dataTask 然后在需要时将其转换为 downloadTask”
  • @NSPratik 为迟到的回复道歉。也许这可以帮助您将来参考。我已经使用 Alamofire.download API 来实现后台数据下载。请查看以下链接以获取更多信息。 github.com/tonyli508/AlamofireDomain#downloading-data-to-a-file
猜你喜欢
  • 2017-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-30
  • 1970-01-01
相关资源
最近更新 更多