WKURLSessionRefreshBackgroundTask не вызывается при попытке обновления фона в watchOS
Я работаю над усложнением, чтобы получить запланированные данные из веб-службы. Каждые 20-30 минут (или вручную) я планирую WKRefreshBackgroundTask, чтобы сделать это.
По предложению Apple, я хочу, чтобы операционная система обрабатывала получение этих данных через фон NSURLSession
,
Это функция, которую я использую для загрузки нужных мне данных:
func scheduleURLSession()
{
print("\nScheduling URL Session...")
let backgroundSessionConfig:URLSessionConfiguration = URLSessionConfiguration.background(withIdentifier: NSUUID().uuidString)
backgroundSessionConfig.sessionSendsLaunchEvents = true
let backgroundSession = URLSession(configuration: backgroundSessionConfig)
let downloadTask = backgroundSession.downloadTask(with: URL(string: "https://www.myserver.com/somedata")!)
downloadTask.resume()
}
Несколько вещей об этом:
- Это действительно вызывается, когда я планирую это. Я вижу его оператор печати в консоли.
- Это почти идентично примеру Apple.
- Я опустил URL. Тот же URL работает в приложениях iOS/watchOS просто отлично, так что с этим все в порядке.
Проблема, хотя я звоню resume()
на задачу и позволяя ему разбудить мое приложение, когда оно будет завершено, похоже, что это не так.
Когда он завершится, он должен вернуться к обработчику WKExtensionDelegate:
func handle(_ backgroundTasks: Set<WKRefreshBackgroundTask>)
как WKURLSessionRefreshBackgroundTask
, но это не так.
Мой код, идентичный образцу кода Apple, затем создает другой сеанс, но присоединяется к нему через WKURLSessionRefreshBackgroundTask
Идентификатор Это где делегат установлен для обработки загруженных данных. Проверьте код:
func handle(_ backgroundTasks: Set<WKRefreshBackgroundTask>) {
for task in backgroundTasks {
switch task {
case let backgroundTask as WKApplicationRefreshBackgroundTask:
print("\nWatchKit - WKApplicationRefreshBackgroundTask")
// self.updateComplicationDataArrivalTimes(backgroundTask)
self.scheduleURLSession()
backgroundTask.setTaskCompleted()
case let snapshotTask as WKSnapshotRefreshBackgroundTask:
// Snapshot tasks have a unique completion call, make sure to set your expiration date
print("\nWatchKit - WKSnapshotRefreshBackgroundTask")
snapshotTask.setTaskCompleted(restoredDefaultState: true, estimatedSnapshotExpiration: Date.distantFuture, userInfo: nil)
case let connectivityTask as WKWatchConnectivityRefreshBackgroundTask:
print("\nWatchKit - WKWatchConnectivityRefreshBackgroundTask")
connectivityTask.setTaskCompleted()
case let urlSessionTask as WKURLSessionRefreshBackgroundTask:
print("\nWatchKit - WKURLSessionRefreshBackgroundTask")
let backgroundConfigObject = URLSessionConfiguration.background(withIdentifier: urlSessionTask.sessionIdentifier)
let backgroundSession = URLSession(configuration: backgroundConfigObject, delegate: self, delegateQueue: nil)
print("Rejoining session ", backgroundSession)
urlSessionTask.setTaskCompleted()
default:
// make sure to complete unhandled task types
task.setTaskCompleted()
}
}
}
Но опять же, похоже, он никогда не вернется. Я не могу понять, почему это работает, несмотря на то, что код идентичен примеру кода Apple для этого проекта: WatchBackgroundRefresh: Использование WKRefreshBackgroundTask для обновления приложений WatchKit в фоновом режиме.
Есть ли какие-то настройки в моем проекте, которые мне не хватает? Я помещаю весь этот код в ExtensionDelegate
Новое в watchOS 3. Я также соответствую WKExtensionDelegate
а также URLSessionDownloadDelegate
,
Заранее спасибо за помощь!
2 ответа
Я получил это работает! Я начал с просмотра видео / заметок WWDC'16, сравнивая их с примером WatchBackgroundRefresh от Apple. Затем, просматривая форумы Apple Dev, я нашел эту тему с той же проблемой, с которой мы столкнулись. Там, парень, "Даниэль Фонтес", публикует свой "рецепт", чтобы заставить его работать (обратите внимание, не принятый ответ!), И это в сочетании с видео сработало для меня.
Что я сделал, чтобы пример Apple работал:
- Сделайте MainInterfaceController URLSessionDelegate
- Создайте локальную переменную:
var savedTask:WKRefreshBackgroundTask?
- в
handle( backgroundTasks:)
функция, сохранитьWKURLSessionRefreshBackgroundTask
к локальной переменнойself.savedTask = task
- не task.setTaskCompleted() (!!) - в
urlSession - didFinishDownloading:
установите сохраненное задание как выполненное:self.savedTask?.setTaskCompleted()
после того, как вы прочитали полученные данные. - Убедитесь, что ресурс, к которому вы обращаетесь, - https://, в противном случае добавьте "Настройки безопасности транспорта приложения" в файл Info.plist.
Надеюсь, что это может помочь!
пс. это работает в симуляторе (xcode 8.3.3, watchOS 3.2)
Я никогда не работал с примером Apple, но у меня работало фоновое обновление. В отличие от их примера, вам нужно сделать себя делегатом сессии. Так что вместо этого создайте свой фоновый сеанс:
let backgroundSession = URLSession (конфигурация: backgroundSessionConfig, делегат: self, делегат Queue: nil)
У меня есть подробный пример кода здесь (см. Код вопроса):
WatchOS 3 WKApplicationRefreshBackgroundTask didReceiveChallenge
Надеюсь, поможет.