【问题标题】:AFHTTPSessionManager block is not called when app is on background应用程序在后台时不调用 AFHTTPSessionManager 块
【发布时间】:2015-01-09 01:42:47
【问题描述】:

我的应用得到一个静默推送,然后在后台使用 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'而终止应用程序,原因:'后台会话中不支持数据任务。' 我该怎么办?感谢您的帮助!

【问题讨论】:

    标签: ios background afnetworking afnetworking-2 nsurlsessionconfiguration


    【解决方案1】:

    一些想法:

    1. 正确的背景NSURLSessionConfiguration 需要NSURLSessionDownloadTaskNSURLSessionUploadTask。不过,GET 方法会创建 NSURLSessionDataTask

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

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

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

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

    2. 如果您提出的请求不大,如果用户碰巧在请求仍在进行时离开了您的应用,那么只需向操作系统请求一点时间来完成此操作可能会更容易。请参阅App Programming Guide for iOS: Background Execution执行有限长度任务部分。

      底线,在发出请求之前,请执行以下操作:

      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 容易得多。

    【讨论】:

    • 这只是几个http请求,所以第二个建议正是我想要的,非常感谢,你是救命稻草!
    • @rob 当应用程序终止并且我想连接用户并在 XMPP 服务器中获取在线用户而不是如何连接?
    • 如果您想在应用程序未运行时执行请求,唯一的方法是后台获取。请参阅 iOS 应用程序编程指南中的 Downloading Content in the Background 请注意,您无法控制何时调用服务器,但您确实有这种在后台下载数据的机制。跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-14
    • 2015-02-02
    • 2013-03-29
    • 2017-04-22
    相关资源
    最近更新 更多