Блок AFHTTPSessionManager не вызывается, когда приложение находится в фоновом режиме
Мое приложение получает тихий толчок, затем выполняет http-запрос в фоновом режиме, используя AFNetworking, но оно не вводит полный блок, код:
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
см. /questions/30637589/afnetworking-i-fonovyie-peredachi/30637612#30637612. Вы должны жениться на этом сrequestWithMethod
, обсуждалось выше.Обратите внимание, что будьте осторожны с использованием специфичных для задачи блоков завершения (поскольку задачи продолжаются, даже если приложение завершено и эти блоки давно ушли). В документации AFNetworking для задач фоновой загрузки сказано:
Предупреждение: при использовании фона
NSURLSessionConfiguration
на iOS эти блоки будут потеряны после завершения работы приложения. Фоновые сеансы могут предпочесть использоватьsetDownloadTaskDidFinishDownloadingBlock:
указать URL для сохранения загруженного файла, а не целевой блок этого метода.Если вы делаете скромный запрос, может быть проще попросить у ОС немного времени, если пользователь покидает ваше приложение, пока запрос еще выполняется. См. Раздел " Выполнение задач конечной длины " в Руководстве по программированию приложения для 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
,