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

时间:2014-10-15 16:09:50

标签: ios ios8 nsurlsession download-manager

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

关于Apple参考。

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

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

我发现了这个错误:

The operation couldn't be completed. (NSURLErrorDomain error -999.)

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

谢谢 安德烈

3 个答案:

答案 0 :(得分:6)

有几点意见:

  1. 错误-999是kCFURLErrorCancelled

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

    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:kBackgroundIdentifier];
    NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
    

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

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

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

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

答案 1 :(得分:4)

我插入这些新代码:

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

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

再次进入:

  • (void)URLSession:(NSURLSession *)会话任务:(NSURLSessionTask *)任务didCompleteWithError:(NSError *)错误 {

并再次给我-999错误。

答案 2 :(得分:1)

我使用此配置

- (NSURLSession *)backgroundSession
{
/*
 Using disptach_once here ensures that multiple background sessions with the same identifier are not created in this instance of the application. If you want to support multiple background sessions within a single process, you should create each session with its own identifier.
 */
    static NSURLSession *session = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfiguration:@"com.example.apple-samplecode.SimpleBackgroundTransfer.BackgroundSession"];
        session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
    });
    return session;
}

让我解释一下我的意思"终止应用程序" (在ios8中):

  • 双击主页按钮
  • 在我打开的应用上滑动。
  • app从打开的应用列表中消失
  • 重启应用。

当我重新打开应用程序时,我进入回调错误

The operation couldn't be completed. (NSURLErrorDomain error -999.)

有些事我无法理解。这种行为让我发疯! : - (