фоновые задачи watchOS чрезвычайно громоздки для реализации и отладки, но на основе документации и реализаций Apple, которые обсуждали другие, вот что я считаю лучшей практикой. Здесь я вижу пару проблем.
Во-первых, из документов WKRefreshBackgroundTask :
Система приостанавливает расширение, как только все фоновые задачи завершены.
Вызов setTaskCompletedWithSnapshot
для задачи указывает системе, что вы закончили выполнять всю работу, которую вам нужно сделать, поэтому она приостановит ваше приложение. Ваш updateComplicationServer
метод, вероятно, никогда не получит шанса на запуск, потому что система слишком рано приостанавливает ваше расширение.
Что еще более важно, чтобы отправлять URL-запросы во время фонового обновления, вам потребуется использовать фоновый сеанс URL-адреса. , Пример процесса , описанный в документах WKRefreshBackgroundTask , показывает наилучшую практику для его настройки. Вкратце:
- Вы назначаете фоновый refre sh, используя
WKExtension
scheduleBackgroundRefresh
, как вы делаете. - Система разбудит ваше расширение через некоторое время после предпочитаемую вами дату (по усмотрению системы) с помощью
WKRefreshBackgroundTask
. - . В методе вашего дополнительного делегата
handle
проверьте наличие WKApplicationRefreshBackgroundTask
; вместо выполнения запроса с URLSessionDataTask
здесь вам нужно запланировать сеанс URL background , чтобы система могла приостановить ваш добавочный номер и выполнить запрос от вашего имени. См. WKURLSessionRefreshBackgroundTask документы для получения подробной информации о том, как следует устанавливать фоновые сеансы. Система выполнит ваш запрос URL в отдельном процессе и снова разбудит ваше расширение, как только оно получит законченный. Он будет вызывать метод вашего делегата расширения handle
, как и раньше, на этот раз с WKURLSessionRefreshBackgroundTask
. Здесь вам нужно сделать две вещи:
- Сохранить фоновую задачу в переменной экземпляра в вашем делегате расширения. Мы пока не хотим устанавливать его завершение, но нам нужно сохранить его, чтобы завершить его позже, когда запрос URL завершится.
- Создайте еще один сеанс фонового URL, используя
sessionIdentifier
фоновой задачи и используйте ваш делегат расширения в качестве делегата сеанса (почему не получается использовать другой объект в качестве делегата, я не могу сказать, но это, кажется, важная деталь). Обратите внимание, что использование того же идентификатора для создания второго сеанса URL-адреса позволяет системе подключить сеанс к загрузке, выполненной для вас в другом процессе; цель этого второго фонового сеанса URL-адресов состоит исключительно в том, чтобы соединить делегата с сеансом.
В делегате сеанса реализуйте функции urlSession(_ downloadTask: didFinishDownloadingTo:)
и urlSession(task: didCompleteWithError:)
.
В отличие от вашего NSURLSessionDataTask
на основе блоков, фоновые URL-запросы всегда выполняются как задачи загрузки. Система выполняет запрос и выдает временный файл с результирующими данными. В функции urlSession(_ downloadTask: didFinishDownloadingTo:)
данные в этом файле и обрабатываются по мере необходимости для обновления вашего пользовательского интерфейса.
Наконец, в функции делегата urlSession(task: didCompleteWithError:)
вызовите setTaskCompletedWithSnapshot
, чтобы сообщить системе, что вы закончил свою работу Фу.
Как я уже упоминал, все это очень сложно отладить, в основном потому, что все зависит от системы, когда эти вещи действительно происходят, если они вообще случаются. В документации Apple говорится о бюджете, выделенном на фоновые обновления:
В целом, система выполняет примерно одну задачу в час для каждого приложения в док-станции (включая последнее использованное приложение). Этот бюджет распределяется между всеми приложениями на док-станции. Система выполняет несколько задач в час для каждого приложения с усложнением на активном циферблате. Этот бюджет распределяется между всеми сложностями на циферблате. После исчерпания бюджета система задерживает ваши запросы до тех пор, пока не станет доступно больше времени.
Последнее замечание: легенда гласит, что имитатор watchOS не обрабатывает фоновые URL-ссылки повторно sh задачами должным образом, но, к сожалению, в документах Apple нет официального слова об этом. Лучше всего протестировать на оборудовании Apple Watch, если вы можете.