NSURLSessionDownloadTask автоматически возобновляет все задачи в фоновом режиме

У меня есть требование загружать файлы в последовательном порядке. В настоящее время я могу сделать это, пока приложение находится на переднем плане.

Ниже приведена логика, которую я использовал.

  1. Создайте все задачи для скачивания.

  2. Возобновляйте по одному и по мере завершения текущего возобновляйте следующий с URLSession:task:didCompleteWithError:.

Эта логика работает, когда приложение находится на переднем плане, но как только приложение начинает работать в фоновом режиме (в результате сбоя), и мы снова запускаем приложение до завершения загрузки, все состояние задач было изменено на возобновление, и все загружаются одновременно.

Это ожидаемое поведение или что-то, что мне не хватает, чтобы заказать это в последовательном режиме и в фоновом режиме?

Редактировать: я проверял, создавая задачи загрузки одну за другой. После завершения первой задачи создайте следующую внутри setTaskDidCompleteBlock и так далее. Он завершает только первую задачу, и после этого сеанса происходит сбой, когда задача создается внутри setTaskDidCompleteBlock (это происходит только при работе в фоновом режиме, для переднего плана все работает нормально).

Вот скриншоты моего журнала сбоев:

drive.google.com/file/d/0B9jFCUPsPtV6YW5zbTJrQ0pQYlk/view?usp=sharing

а также

drive.google.com/file/d/0B9jFCUPsPtV6UkEwOURpZmZYcEU/view?usp=sharing

Любая помощь будет оценена по достоинству.


person Nikhil.T    schedule 13.08.2015    source источник


Ответы (2)


Если вам абсолютно необходимо запускать эти запросы последовательно, я бы предложил не создавать экземпляры всех этих задач заранее, а создавать их по одному, создавая экземпляр следующего только после завершения предыдущего.

Но мы должны признать, что вы платите значительное снижение производительности за последовательное выполнение запросов. (И эта проблема усугубится при использовании фоновых сеансов.) Если это вообще возможно, посмотрите, можете ли вы изменить свои запросы, чтобы они выполнялись одновременно. Понятно, что если вам нужен вывод одного, чтобы создать запрос для другого, вы застряли (или, по крайней мере, до вашего рефакторинга кода сервера), но это явно не проблема (потому что вы создали все запросы вверх). передний). Если вы выполняете этот процесс последовательного запроса по искусственным причинам (например, код заполняет массив, и вы хотите, чтобы это было сделано по порядку), вы можете перепроектировать реализацию, чтобы удалить это искусственное ограничение.

person Rob    schedule 14.08.2015
comment
Большое спасибо за ваши предложения. Мои файлы - это в основном видео, когда пользователь выбирает клип, мне нужно загрузить четыре видео. О последовательном порядке: поскольку эти четыре видео в клипе очень близки к прямой телетрансляции, поэтому мои клиенты хотят именно такого порядка. Я также попытался создать новую задачу из setTaskDidCompleteBlock. Но кажется, что мой NSURLSession вылетает после первой загрузки (при загрузке с фона, для переднего плана он работает нормально). Это хороший способ создать экземпляр следующей задачи загрузки из setTaskDidCompleteBlock? Кстати, я использую AFnetworking. - person Nikhil.T; 14.08.2015
comment
Хорошо, но сравните это, потому что, если они хотят, чтобы они загружались быстро, это будет происходить намного быстрее, если вы загрузите их одновременно. Но я понимаю проблему с заказом. Что касается сбоя, мы не можем комментировать это без подробностей о сбое, вашей фоновой реализации AFNetworking (а-ля stackoverflow.com/a/21359684/1271826) и т. д. В связи с этими деталями может возникнуть еще один вопрос. - person Rob; 14.08.2015
comment
Хорошо, сейчас я тоже проверяю скорость одновременной загрузки. Я отредактировал свой вопрос с помощью журналов сбоев. Если я не прошу слишком многого, не могли бы вы тоже взглянуть на это. - person Nikhil.T; 14.08.2015
comment
@Nikhil.T - Нет, боюсь, эти журналы сбоев мне не помогут (поскольку они находятся в пределах nsurlsessiond и не показывают, что в вашем коде вызвало сбой). На самом деле я бы предложил добавить множество операторов NSLog, чтобы выяснить, насколько далеко ваш код продвинулся до того, как он потерпел крах. Существует множество возможных проблем (когда вы создаете второй запрос, дважды проверьте, все ли выглядит хорошо, прежде чем вызывать resume; убедитесь, что вы успешно вызвали completionHandler, который был передан делегату вашего приложения; отслеживайте это с помощью Чарльз и т. д.). Отладка фона NSURLSession не всегда проста. - person Rob; 16.08.2015
comment
Хорошо, я понял, я попробую, как было предложено. Очень ценю вашу помощь. - person Nikhil.T; 17.08.2015

Я тоже видел, как это происходит. Если вы создадите downloadTask, когда приложение находится на переднем плане, но не вызовете resume(), оно не запустится, однако запустится автоматически, когда приложение перейдет в фоновый режим.

Решение заключается в явном вызове suspend() для каждой задачи загрузки при ее создании. Затем, когда вы будете готовы начать загрузку, позвоните по номеру resume().

По-видимому, вновь созданная задача загрузки не приостанавливается и не возобновляется. Его начальное состояние не .Running, но когда приложение находится в фоновом режиме, оно переходит в .Running, поскольку оно не было явно приостановлено. Это удивительное поведение; Я не знаю, почему демон фонового сеанса работает таким образом.

person Joseph    schedule 21.03.2017