当应用程序以NSURLSession终止时,NSURLDomainErrorDomain错误-999

And*_*zza 2 download-manager ios nsurlsession ios8

当我终止应用程序时,我在NSURLSession遇到大麻烦.我已经下载了苹果样本:https: //developer.apple.com/library/ios/samplecode/SimpleBackgroundTransfer/Introduction/Intro.html

在Apple参考.

当我开始正确下载文件下载.当我在后台输入时,继续下载.当我终止应用程序并重新启动应用程序时,应用程序输入:

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
Run Code Online (Sandbox Code Playgroud)

我发现了这个错误:

The operation couldn't be completed. (NSURLErrorDomain error -999.)
Run Code Online (Sandbox Code Playgroud)

当应用程序终止时,我似乎无法恢复下载.这是正确的吗?为了继续下载,我必须让应用程序在后台保持活动状态?

谢谢安德烈

Rob*_*Rob 6

几点意见:

  1. 错误-999是kCFURLErrorCancelled.

  2. 如果您正在使用NSURLSessionDownloadTask,可以使用后台会话配置在后台下载,例如

    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:kBackgroundIdentifier];
    NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
    
    Run Code Online (Sandbox Code Playgroud)

    如果不使用后台会话(例如,您必须使用数据任务),则可以beginBackgroundTaskWithExpirationHandler在应用程序终止之前使用在后台请求应用程序完成请求的一点时间.

  3. 请注意,在使用后台会话时,您的应用委托必须响应handleEventsForBackgroundURLSession,捕获它将在适当时调用的完成处理程序(例如,通常在URLSessionDidFinishEventsForBackgroundURLSession).

  4. 你是怎么"终止应用程序"的?如果你手动杀死它(通过双击主页按钮,按住图标运行应用程序,然后点击小红色"x"),这不仅会终止应用程序,但它也将停止后台会话.或者,如果应用程序崩溃或者由于前台应用程序需要更多内存而被简单地放弃,后台会话将继续.

    就个人而言,每当我想在应用程序终止后测试后台操作时,我的应用程序中的代码都会崩溃(deference nil指针,就像Apple在他们的WWDC视频介绍中所做的那样NSURLSession).很明显,你永远不会在生产应用程序中这样做,但由于内存限制,很难模拟被抛弃的应用程序,因此故意崩溃是该场景的良好代理.


And*_*zza 5

我插入这个新的代码行:

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
    BLog();

    NSInteger errorReasonNum = [[error.userInfo objectForKey:@"NSURLErrorBackgroundTaskCancelledReasonKey"] integerValue];

    if([error.userInfo objectForKey:@"NSURLErrorBackgroundTaskCancelledReasonKey"] &&
       (errorReasonNum == NSURLErrorCancelledReasonUserForceQuitApplication ||
        errorReasonNum == NSURLErrorCancelledReasonBackgroundUpdatesDisabled))
    {
        NSData *resumeData = error.userInfo[NSURLSessionDownloadTaskResumeData];
        if (resumeData) {
            // resume
            NSURL *downloadURL = [NSURL URLWithString:DownloadURLString];
            NSURLRequest *request = [NSURLRequest requestWithURL:downloadURL];
            if (!self.downloadTask) {
                self.downloadTask = [self.session downloadTaskWithRequest:request];
                         }

            [self.downloadTask resume];
            if (!_session){
               [[_session downloadTaskWithResumeData:resumeData]resume];
                                         }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

它捕获 NSURLErrorCancelledReasonUserForceQuitApplication 但当应用程序尝试 [[_session downloadTaskWithResumeData:resumeData]resume]

再次进入:

  • (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {

并再次给我 -999 错误。