1

我的应用程序得到一个静默推送,然后使用 AFNetworking 在后台执行一些 http 请求,但它没有进入完整的块,代码是:

AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] init];
[manager GET:urlString
  parameters:nil
     success:^(NSURLSessionDataTask *task, id responseObject) {
         NSLog(@"response objece:%@", responseObject);
     }
     failure:^(NSURLSessionDataTask *task, NSError *error) {
         NSLog(@"error:%@", error);
     }];

然后我发现也许我可以使用 NSURLSessionConfiguration 来配置会话:

NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfiguration:@"com.company.backgroundDownloadSession"];
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithSessionConfiguration:configuration];
[manager GET:urlString
  parameters:nil
     success:^(NSURLSessionDataTask *task, id responseObject) {
         NSLog(@"response objece:%@", responseObject);
     }
     failure:^(NSURLSessionDataTask *task, NSError *error) {
         NSLog(@"error:%@", error);
     }];

但 AFNetworking 崩溃说:“由于未捕获的异常‘NSGenericException’而终止应用程序,原因:‘后台会话不支持数据任务。’ 我应该怎么办?我感谢你的帮助!

4

1 回答 1

2

几个想法:

  1. 适当的背景NSURLSessionConfiguration需要NSURLSessionDownloadTaskNSURLSessionUploadTaskGET但是,该方法会创建NSURLSessionDataTask.

    要使用下载或上传任务,您必须单独构建您的请求,然后利用AFURLSessionManager来发出下载或上传。话虽如此,但是,如果您尝试创建 HTTP GET/POST 样式的请求,则可以使用各种请求序列化程序创建请求。只需使用AFHTTPRequestSerializer方法requestWithMethod

    有关将 AFNetworking 与背景结合使用的基本介绍NSURLSessionConfiguration,请参阅https://stackoverflow.com/a/21359684/1271826。您必须将其与requestWithMethod上面讨论的 结合起来。

    请注意,请谨慎使用特定于任务的完成块(因为即使应用程序终止并且这些块早已消失,任务也会继续)。正如后台下载任务的 AFNetworking 文档所说:

    警告:如果在 iOS 上使用背景NSURLSessionConfiguration,这些块将在应用程序终止时丢失。后台会话可能更喜欢使用setDownloadTaskDidFinishDownloadingBlock:指定用于保存下载文件的 URL,而不是此方法的目标块。

  2. 如果您提出一个适度的请求,如果用户碰巧在请求仍在进行中时离开了您的应用程序,那么只要求操作系统一点时间这样做可能会更容易。请参阅iOS 应用程序编程指南的执行有限长度任务部分:后台执行。

    最重要的是,在发出请求之前,请执行以下操作:

    UIApplication *application = [UIApplication sharedApplication];
    
    bgTask = [application beginBackgroundTaskWithName:@"MyTask" expirationHandler:^{
        // Clean up any unfinished task business by marking where you
        // stopped or ending the task outright.
        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    }];
    

    然后在请求的完成块中,可以终止后台任务:

    if (bgTask != UIBackgroundTaskInvalid) {
        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    }
    

    这仅适用于有限长度的任务,但它可能比尝试做背景容易得多NSURLSessionConfiguration

于 2015-01-09T02:52:23.307 回答