Из документа похоже, что загрузка файла - хороший пример использования за использование begin​Background​Task​With​Expiration​Handler​. Я обнаружил, что с помощью

let uploadTask = session.uploadTask(with: request as URLRequest, fromFile: file)
uploadTask.resume()

Будет уже запущен, пока приложение находится в фоновом режиме (некоторое время я получаю пинги прогресса загрузки). Кроме того, я могу установить URLSession для фона:

let config = URLSessionConfiguration.background(withIdentifier: "uploads")
session = URLSession(configuration: config, delegate: self, delegateQueue: nil)

Так в чем же преимущество использования begin​Background​Task​With​Expiration​Handler? Это продлит время, когда я закончу свою загрузку? Если да, могу ли я узнать, сколько (не видел ничего об этом в документе)? Или я просто пингуюсь до остановки приложения? Должен ли я использовать его в сочетании с фоновой URLSession?

Кроме того, в документах говорится, что обработчик будет вызываться незадолго до того, как оставшееся фоновое время приложения достигнет 0 . Означает ли это, что приложение будет завершено после этого? то есть я могу предположить, что следующим вызовом будет application:didFinishLaunchingWithOptions или applicationDidBecomeActive?

3
Guig 31 Мар 2017 в 23:15

2 ответа

Лучший ответ

Эта фоновая задача позволит вашему приложению продолжать работать в фоновом режиме после того, как пользователь покинет ваше приложение на дополнительные 3 минуты или около того (проверьте фактическое значение background​Time​Remaining), чтобы ваш запрос завершился. И да, ближе к концу этих 3 минут будет вызван обработчик тайм-аута, если вы еще не завершили фоновую задачу.

Таким образом, если вы завершите фоновую задачу во время обычного потока вашего приложения, это закрытие тайм-аута не нужно будет вызывать. Это закрытие предназначено исключительно для любой быстрой очистки в последнюю минуту, которая может потребоваться до того, как приложение перестанет работать в фоновом режиме, поскольку истекло время до того, как вы успели указать, что фоновая задача завершена. Это не для того, чтобы начинать что-то новое, а только для последней уборки. И обязательно завершите фоновую задачу в этом обработчике тайм-аута ... если вы не завершите фоновую задачу, ОС скорее убьет ваше приложение, чем просто приостановит его. Часто единственное, что вам нужно сделать в этом закрытии тайм-аута, это завершить фоновую задачу, но если вам нужно выполнить какую-либо другую очистку, это то место, где вы можете это сделать.

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

Что касается предположений о том, что произойдет, когда ваше приложение будет перезапущено пользователем позже, вы не можете делать предположения о том, какой метод делегата приложения будет вызван. Даже если вы корректно завершили фоновое задание, у вас нет никаких гарантий, что оно не будет отброшено по другим причинам (например, из-за нехватки памяти). Так что не думай ничего.

2
Rob 2 Апр 2017 в 22:43

Так в чем же преимущество использования фоновой задачи begin With Expiration Handler?

Если вы собираетесь использовать URLSessionConfiguration.background, такого преимущества нет, и вам вообще не следует использовать beginBackgroundTask(expirationHandler:). Вся ваша предпосылка (ваше первое предложение) была неверной. Загрузка файла не - хороший вариант использования для beginBackgroundTask(expirationHandler:). Это хороший вариант использования URLSessionConfiguration.background. Эти две вещи не имеют ничего общего друг с другом.

1
matt 31 Мар 2017 в 20:44