10

我正在使用 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;
4

2 回答 2

6

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

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

于 2013-12-11T15:58:34.563 回答
6

正如苹果所说:

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

希望能帮助到你。斯特凡

于 2014-11-14T16:46:49.740 回答