Загрузка NSURLSession - возобновление сбоя сети
После прочтения документации Apple о загрузке фона с новым iOS7 api (NSURLSession), я немного разочарован. Я был уверен, что Apple управляет паузой/резюме по доступности сети в фоновом режиме (или предоставляет возможность сделать это), но не...
Итак, прочитав документацию, это то, что у нас есть:
https://developer.apple.com/library/ios/documentation/cocoa/Conceptual/URLLoadingSystem/NSURLSessionConcepts/NSURLSessionConcepts.html
Когда какая-либо задача завершается, объект NSURLSession вызывает делегаты URLSession: task: didCompleteWithError: метод с объект ошибки, или nil, если задача выполнена успешно. Если задача является возобновляемой загрузкой, пользовательский словарь NSError содержит значение для ключа NSURLSessionDownloadTaskResumeData. Ваш приложение должно использовать API-интерфейсы достижимости, чтобы определить, когда следует повторить попытку, и затем следует вызвать downloadTaskWithResumeData: или downloadTaskWithResumeData: completeHandler: создать новую загрузку задача продолжить эту загрузку. Перейдите к шагу 3 (создание и возобновление объекты задачи).
До сих пор я понимаю решение, но мой вопрос: какая архитектура лучше всего справляется с потерей сети и возобновляет загрузку в фоновом режиме?
На моей стороне я использую доступность и каждый раз, когда сеть доступна, я возвращаю все задачи (ссылаясь на NSArray при создании) и приостанавливаю их, когда сеть потеряна. Это хорошо работает на переднем плане, но для фона мне нужна помощь по следующим пунктам:
-
Если у моего приложения нет возможности подключения на переднем плане, если я иду на задний план без подключения, все мои задачи остаются приостановленными и не вернутся, если сеть доступна...
-
Потеря сети в фоновом режиме, прекратите все мои загрузки/задачи.
Сценарий:
- На переднем плане я запускаю загрузку своих задач.
- Я перехожу на задний план и через 10 секунд переключится в режим "aireplan".
- Все мои задачи получили ошибку. Итак, в методе URLSession: task: didCompleteWithError: я возобновляю их, используя
downloadTaskWithResumeData или если я не могу (потому что у некоторых нет
достаточно возобновить данные) Я создаю новую задачу без ее возобновления (кроме случаев, когда сеть в это время).
- Затем я установил wifi
- Поскольку я все еще в фоновом режиме, я не могу запускать "возобновление", когда сеть возвращается без запуска приложения...
Как мне адресовать эти пункты? Я что-то пропустил?
Ответы
Ответ 1
Поскольку я все еще в фоновом режиме, я не могу запускать "возобновление", когда сеть возвращается без запуска приложения...
вы можете использовать "background fetch", когда приложение запускается с помощью выборки, тогда вы можете проверить сеть и возобновить загрузку.
Ответ 2
Вы должны создать NSURLSession с настройками фона, тогда ваша задача будет отправлена на фоновый демон, и ваше приложение будет вызвано, когда оно будет завершено.
Ответ 3
Реализация:
application:handleEventsForBackgroundURLSession:completionHandler:
в делетете приложения - без вызова функции completHandler - заставляет приложение зависать в фоновом режиме после того, как устройство теряет соединение, пока оно приостановлено. Таким образом, приложение все равно может прослушивать уведомления о достижении и перезагружать загрузку, когда сетевое соединение снова становится доступным. Тем не менее, это довольно хитроумный подход и может не соответствовать рекомендациям по представлению магазинов Apple. Кроме того, этот подход не очень помогает, когда соединение теряется, когда приложение находится на переднем плане, и соединение восстанавливается, пока приложение приостановлено.
В конце я сделал следующее:
- Использование уведомления
application:handleEventsForBackgroundURLSession:completionHandler:
для приостановки загрузки в фоновом режиме.
- Использование прерывистого уведомления извлечения фона (т.е.
application:performFetchWithCompletionHandler:completionHandler
) для проверки состояния соединения и перезапуска любых приостановленных загрузок. (hat-tip @gugupluto)
Это все еще не обеспечивает оптимальной загрузки и может заставить пользователей задаться вопросом, почему их "фоновая загрузка" еще не завершилась после их повторного открытия, но, похоже, это лучшее, что мы можем надеяться от Apple на данный момент.