应用程序在后台时不调用 AFHTTPSessionManager 块
Posted
技术标签:
【中文标题】应用程序在后台时不调用 AFHTTPSessionManager 块【英文标题】:AFHTTPSessionManager block is not called when app is on background 【发布时间】: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'而终止应用程序,原因:'后台会话中不支持数据任务。' 我该怎么办?感谢您的帮助!
【问题讨论】:
【参考方案1】:一些想法:
正确的背景NSURLSessionConfiguration
需要NSURLSessionDownloadTask
或NSURLSessionUploadTask
。不过,GET
方法会创建 NSURLSessionDataTask
。
要使用下载或上传任务,您必须单独构建您的请求,然后利用AFURLSessionManager
发出下载或上传。话虽如此,但是,如果您尝试创建 HTTP GET/POST 样式的请求,则可以使用各种请求序列化程序创建请求。只需使用AFHTTPRequestSerializer
方法requestWithMethod
。
有关将 AFNetworking 与背景NSURLSessionConfiguration
结合使用的基本介绍,请参阅https://***.com/a/21359684/1271826。您必须将其与上面讨论的requestWithMethod
结合起来。
请注意,请谨慎使用特定于任务的完成块(因为即使应用程序终止并且这些块早已消失,任务也会继续进行)。正如后台下载任务的 AFNetworking 文档所说:
警告:如果在 ios 上使用背景
NSURLSessionConfiguration
,这些块将在应用程序终止时丢失。后台会话可能更喜欢使用setDownloadTaskDidFinishDownloadingBlock:
来指定保存下载文件的 URL,而不是此方法的目标块。
如果您提出的请求不大,如果用户碰巧在请求仍在进行时离开了您的应用,那么只需向操作系统请求一点时间来完成此操作可能会更容易。请参阅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。 请注意,您无法控制何时调用服务器,但您确实有这种在后台下载数据的机制。跨度>以上是关于应用程序在后台时不调用 AFHTTPSessionManager 块的主要内容,如果未能解决你的问题,请参考以下文章
onMessageReceived(RemoteMessage remoteMessage) 应用程序在后台或被杀死时不调用
Firebase onMessageReceived(RemoteMessage remoteMessage),当应用程序在后台时不被调用[重复]