Загрузка нескольких файлов с не стабильной очередью в фоновом режиме - PullRequest
0 голосов
/ 01 февраля 2020

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

Я использую код Роба как указано в здесь , но он использует URLSessionConfiguration.default , который я хочу использовать URLSessionConfiguration.background (withIdentifier: "uniqueID") .

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

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

1 Ответ

2 голосов
/ 01 февраля 2020

Вся идея упаковки запросов в действии применима, только если приложение активно / работает. Он отлично подходит для таких вещей, как ограничение степени параллелизма для запросов переднего плана, управление зависимостями и т. Д. c.

Для фонового сеанса, который продолжается после приостановки приложения, однако ничего из этого не имеет значения. Вы создаете свой запрос, передаете его фоновому сеансу для управления и отслеживаете методы делегата, вызываемые для фонового сеанса. Никаких операций не требуется / желательно. Помните, что эти запросы будут обрабатываться демоном фоновой сессии, даже если ваше приложение приостановлено (или если оно было прервано в течение его обычного жизненного цикла, но не в случае принудительного выхода из него). Таким образом, сама идея операций, очередей операций и т. Д. c. Просто не имеет смысла, если демон URLSession обрабатывает запросы, а ваше приложение не активно.

См. { ссылка } например, фоновый сеанс.


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

Из-за этой сложности вы можете подумать, действительно ли это необходимо. Иногда, если вам требуется менее 30 секунд для выполнения некоторых запросов, проще просто попросить ОС оставить ваше приложение работающим в фоновом режиме немного после того, как пользователь выйдет из приложения и просто использовать стандартный URLSession. Для получения дополнительной информации см. Увеличение фонового времени выполнения вашего приложения . Это гораздо более простое решение, обходящее многие проблемы с фоном URLSession. Но это работает, только если вам нужно всего 30 секунд или меньше. Для больших запросов, которые могут превышать это маленькое окно, необходим истинный фон URLSession.


Ниже вы спросили:

Есть некоторые недостатки с [загрузкой нескольких файлов параллельно], насколько я понимаю.

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

Исключением здесь является значение по умолчанию, передний план URLSession. В этом случае вам нужно беспокоиться о том, что время ожидания последнего запроса истекло. В этом случае вы можете увеличить интервал ожидания. Или мы можем заключить наши запросы в подкласс Operation, что позволяет нам ограничивать не только количество одновременных запросов, которые мы разрешаем, но и не запускать последующие запросы до тех пор, пока более ранние не закончатся sh. Но даже в этом случае мы обычно делаем это не последовательно, а вместо этого используем maxConcurrentOperationCount из 4 или что-то в этом роде.

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

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

Конечно, вы не можете сделать наивное «добавление в конец массива», если запросы выполняются параллельно, потому что вам не гарантирован порядок их выполнения. Но не сложно захватить эти ответы по мере их поступления. Просто используйте словарь, например, возможно, с ключом URL исходного запроса. Затем вы можете легко найти в этом словаре ответ, связанный с конкретным URL-адресом запроса.

Это невероятно просто. И теперь мы можем выполнять запросы параллельно, что намного быстрее и эффективнее.

Вы можете go сказать:

[Параллельная загрузка] может привести аккумулятор к быть высоким потреблением с большим количеством запросов одновременно. Вот почему я пытался заставить его загружать каждый файл по одному.

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


Не связано, если вы загружаете более 800 файлов, вы можете разрешить пользователю не выполнять эти запросы, когда пользователь находится в «режиме низкого уровня данных». Например, в iOS 13 вы можете установить allowsExpensiveNetworkAccess и allowsConstrainedNetworkAccess.

Независимо (и особенно если вы поддерживаете старшую iOS версии), вы также можете рассмотреть соответствующие настройки isDiscretionary и allowsCellularAccess.

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

Для получения дополнительной информации об этих соображениях см. WWD C 2019 Достижения в области сетей, часть 1 .

...