我的应用程序获得静默推送,然后使用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',原因:'后台会话不支持数据任务。' 我该怎么办?我感谢你的帮助!
答案 0 :(得分:2)
有几点想法:
正确的背景NSURLSessionConfiguration
需要NSURLSessionDownloadTask
或NSURLSessionUploadTask
。但是,GET
方法会创建NSURLSessionDataTask
。
要使用下载或上传任务,您必须单独构建请求,然后利用AFURLSessionManager
发布下载或上传。尽管如此,如果您尝试创建HTTP GET / POST样式请求,您可以使用各种请求序列化程序创建请求。只需使用AFHTTPRequestSerializer
方法requestWithMethod
。
有关将AFNetworking与后台NSURLSessionConfiguration
结合使用的基本介绍,请参阅https://stackoverflow.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
容易得多。