Блок 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 ответ

Решение

Пара мыслей:

  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 для сохранения загруженного файла, а не целевой блок этого метода.

  2. Если вы делаете скромный запрос, может быть проще попросить у ОС немного времени, если пользователь покидает ваше приложение, пока запрос еще выполняется. См. Раздел " Выполнение задач конечной длины " в Руководстве по программированию приложения для 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,

Другие вопросы по тегам