WatchOS 3 WKApplicationRefreshBackgroundTask didReceiveChallenge

Наконец-то (игнорируя пример кода, который я никогда не видел в работе после "задача приложения получена, начать сеанс URL-адреса") мне удалось получить мой код WatchOS3 для запуска фоновой задачи сеанса URL-адреса следующим образом:

 func handle(_ backgroundTasks: Set<WKRefreshBackgroundTask>) {

    for task in backgroundTasks {
        if let refreshTask = task as? WKApplicationRefreshBackgroundTask {
            // this task is completed below, our app will then suspend while the download session runs
            print("application task received, start URL session")

            let request = self.getRequestForRefresh()
            let backgroundConfig = URLSessionConfiguration.background(withIdentifier: NSUUID().uuidString)
            backgroundConfig.sessionSendsLaunchEvents = true
            backgroundConfig.httpAdditionalHeaders = ["Accept":"application/json"]
            let urlSession = URLSession(configuration: backgroundConfig, delegate: self, delegateQueue: nil)
            let downloadTask = urlSession.downloadTask(with: request)

            print("Dispatching data task at \(self.getTimestamp())")
            downloadTask.resume()

            self.scheduleNextBackgroundRefresh(refreshDate: self.getNextPreferredRefreshDate())
            refreshTask.setTaskCompleted()
        }
        else if let urlTask = task as? WKURLSessionRefreshBackgroundTask {
            //awakened because background url task has completed
            let backgroundConfigObject = URLSessionConfiguration.background(withIdentifier: urlTask.sessionIdentifier)
            self.backgroundUrlSession = URLSession(configuration: backgroundConfigObject, delegate: self, delegateQueue: nil) //set to nil in task:didCompleteWithError: delegate method

            print("Rejoining session ", self.backgroundUrlSession as Any)
            self.pendingBackgroundURLTask = urlTask //Saved for .setTaskComplete() in downloadTask:didFinishDownloadingTo location: (or if error non nil in task:didCompleteWithError:) 

        } else {
            //else different task, not handling but must Complete all tasks (snapshot tasks hit this logic)
            task.setTaskCompleted()
        }
    }
}

Однако проблема, которую я сейчас вижу, заключается в том, что мой метод делегата urlSession:task:didReceiveChallenge: никогда не ударил, поэтому я не могу завершить загрузку. (Я также добавил сеансовый уровень urlSession:didReceiveChallenge: метод делегата, и он также не используется).

Вместо этого я сразу же ударил task:didCompleteWithError: метод делегата с ошибкой:

"Сертификат для этого сервера недействителен. Возможно, вы подключаетесь к серверу, который притворяется… который может поставить под угрозу вашу конфиденциальную информацию".

Кто-нибудь получил фоновое обновление часов для работы с дополнительным требованием попадания в didReceiveChallenge метод во время фоновой сессии URL?

Любая помощь или совет, который вы можете предложить, приветствуется.

1 ответ

Решение

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

Я никогда не ударил urlSession:task:didReceiveChallenge: но оказалось мне не нужно.

Сделано небольшое несвязанное изменение:
Без отпечатков / точек останова я иногда бил task:didCompleteWithError Error: как мс, прежде чем я ударил downloadTask:didFinishDownloadingTo location:,

Поэтому я вместо этого устанавливаю self.pendingBackgroundURLTask, выполненный в downloadTask:didFinishDownloadingTo location:, Я только установил его в task:didCompleteWithError Error: если ошибка!= ноль.

func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {

    //Complete task only if error, if no error it will be completed when download completes (avoiding race condition)
    if error != nil {
        self.completePendingBackgroundTask()
    }

}

func completePendingBackgroundTask()
{
    //Release the session
    self.backgroundUrlSession = nil

    //Complete the task
    self.pendingBackgroundURLTask?.setTaskCompleted()
    self.pendingBackgroundURLTask = nil
}

Надеюсь, кто-то еще найдет это полезным.

Другие вопросы по тегам