handleEventsForBackgroundURLSession从未在downloadTask完成时调用

时间:2013-12-05 02:45:56

标签: ios multitasking afnetworking-2 nsurlsession

我正在使用AFURLSessionManager,并将管理器设置为单例实例。

- (AFURLSessionManager *)backgroundSession
{
    static AFURLSessionManager *backgroundSession = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration backgroundSessionConfiguration:@"com.testBackground.BackgroundDownload.BackgroundSession1234"];
    backgroundSession = [[AFURLSessionManager alloc]initWithSessionConfiguration:config];
    [backgroundSession setDownloadTaskDidWriteDataBlock:^(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite){
        NSLog(@"i am downloading my id = %d progress= %f",downloadTask.taskIdentifier, totalBytesWritten*1.0/totalBytesExpectedToWrite);
        [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

    }];
    [backgroundSession setDownloadTaskDidFinishDownloadingBlock:^NSURL *(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, NSURL *location){
        NSLog(@"download finished");
        [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
        return location;

    }];
    });
    return backgroundSession;
}
//assign a download task
NSURLSessionDownloadTask *task = [manager1 downloadTaskWithRequest:request progress:&progress destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
        return targetPath;
    } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
    NSLog("%download success");
}];
[task resume];

我发现当我将应用程序切换到后台时,下载任务正在运行,但是当它完成时,系统调用handleEventsForBackgroundURLSession将永远不会被调用。我觉得我错过了一些设置或选项。任何想法对我都有用,非常感谢。

- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler;

2 个答案:

答案 0 :(得分:6)

正如Apple所说:

  

如果iOS应用程序被系统终止并重新启动,则应用程序可以使用相同的标识符来创建新的配置对象和会话,并检索终止时正在进行的传输的状态。此行为仅适用于系统正常终止应用程序。如果用户从多任务屏幕终止应用程序,系统将取消所有会话的后台传输。此外,系统不会自动重新启动用户强制退出的应用程序。在再次开始传输之前,用户必须明确重新启动应用程序。

希望它有所帮助。 斯蒂芬

答案 1 :(得分:5)

你可能已经想到了这一点,但无论如何,在编写一些测试代码以使用后台传输服务API(没有AFNetworking)时,我发生了同样的事情。解决方案只是更改后台会话配置的标识符字符串。不知怎的,我使用的那个被窃听,系统不会触发handleEventsForBackgroundURLSession回调。甚至没有重新启动设备修复它...但只是更改标识符。

我的理论是我的代码使用相同的配置创建了NSURLSession的多个实例,Apple明确建议(如果你这样做,他们在文档中说它有一个未定义的行为)。我在视图控制器的viewDidLoad方法中获得NSURLSessionConfiguration而没有dispatch_once块,因此发生这种情况肯定是合理的。