Фоновая загрузка iOS - как обработать просроченный токен авторизации
Я выполняю фоновые загрузки в конечную точку, для которой требуется авторизация с использованием токена. Маркер включается в качестве заголовка HTTP для отдельных задач загрузки, которые создаются / запускаются.
Можно ли ответить на сообщения с токенами с истекшим сроком действия и предотвратить 401? Грубо говоря, сроки, которые я надеюсь реализовать, таковы:
- Начать загрузку на переднем плане с действительным токеном
- Приложение имеет фон, загрузка продолжается, но само приложение закрыто
- Проходит некоторое время, пользователь использует устройство с другими приложениями и т. Д.
- Срок действия токена, использованного на шаге 1, истекает, и для всех продолжающихся загрузок потребуется новый токен.
- Приложение запускается в фоновом режиме, сообщая, что срок действия токена истек.
- Я обновляю токен приложения, и загрузка может продолжаться
- Загружает отчет об успехе.
До сих пор я не мог получить такое поведение - на шаге 5 вместо вызова вызова / и т.д. что делегат сеанса или задачи может обработать, я просто получаю 401 ответ.
Настройка конфигурации / сеанса / задачи:
let config = URLSessionConfiguration.background(withIdentifier: "background_upload_session")
session = URLSession(configuration: config, delegate: self, delegateQueue: nil)
var request = URLRequest(url: NetworkService.uploadUrl)
request.httpMethod = "POST"
...
request.setValue(authToken, forHTTPHeaderField: "Authorization-Token")
...
let task = session.uploadTask(with: request, fromFile: filePath)
task.taskDescription = filePath.lastPathComponent
task.resume()
Методы делегирования:
public func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
if error != nil {
DDLogError("NetworkService urlSession didCompleteWithError:\(String(describing: error))")
}
if let httpResponse = task.response as? HTTPURLResponse {
let statusMessage = httpResponse.statusCode == 201 ? "success" : "fail"
DDLogInfo("NetworkService didCompleteWithError status code: \(httpResponse.statusCode) - \(statusMessage)")
}
}
public func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
DDLogInfo("NetworkService urlSession task didReceive challenge")
completionHandler(.performDefaultHandling, nil)
}
Метод didReceiveChallenge не вызывается, чего я и ожидал в этом случае. Предполагая, что это вызвано, я не уверен, как ответить новым токеном в этой ситуации.
Есть идеи?