问题
My app get a silent push, then do some http request in background using AFNetworking,but it didn't enter the complete block, code is:
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);
}];
then I found maybe I could use NSURLSessionConfiguration to config the session:
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);
}];
but AFNetworking crash says:'Terminating app due to uncaught exception 'NSGenericException', reason: 'Data tasks are not supported in background sessions.' What should I do? And I appreciate your help!
回答1:
A couple of thoughts:
Proper background
NSURLSessionConfiguration
requiresNSURLSessionDownloadTask
orNSURLSessionUploadTask
. TheGET
method, though, createsNSURLSessionDataTask
.To use download or upload tasks, you'll have to build your request separately, and then leverage AFURLSessionManager to issue download or upload. Having said that, you can, though, create requests using the various request serializers, if you're trying to create HTTP GET/POST style requests. Just use the
AFHTTPRequestSerializer
methodrequestWithMethod
.For a basic introduction to using AFNetworking in conjunction with background
NSURLSessionConfiguration
, see https://stackoverflow.com/a/21359684/1271826. You'll have to marry that with therequestWithMethod
, discussed above.Note, be wary about using the task-specific completion blocks (because the tasks continue even if the app is terminated and these blocks are long gone). As the AFNetworking documentation for the background download tasks says:
Warning: If using a background
NSURLSessionConfiguration
on iOS, these blocks will be lost when the app is terminated. Background sessions may prefer to usesetDownloadTaskDidFinishDownloadingBlock:
to specify the URL for saving the downloaded file, rather than the destination block of this method.If you're making a modest request, it may be easier to just ask the OS for a little time to do so if the user happens to leave your app while the request is still in progress. See Executing Finite-Length Tasks section of App Programming Guide for iOS: Background Execution.
Bottom line, before issuing the request, do something like:
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; }];
And then in the completion block of the request, you can terminate the background task:
if (bgTask != UIBackgroundTaskInvalid) { [application endBackgroundTask:bgTask]; bgTask = UIBackgroundTaskInvalid; }
This is only good for finite length tasks, but it probably much easier than trying to do background
NSURLSessionConfiguration
.
来源:https://stackoverflow.com/questions/27852606/afhttpsessionmanager-block-is-not-called-when-app-is-on-background