Срок действия CachedURLResponse не работает

Я пытался установить пользовательские заголовки для «Cache-Control», чтобы получить кеш на стороне клиента (на стороне сервера есть «Cache-Control: no-cache»). Пытаясь достичь следующих двух основных вещей.

  1. Ответ некоторых конечных точек должен быть кэширован в памяти и должен иметь срок действия (определяется пользователем)
  2. По истечении срока действия приложение должно игнорировать кеш и получать данные с сервера.

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

Вот фрагменты кода.

Конфигурация сеанса:

let sessionConfiguration: URLSessionConfiguration = URLSessionConfiguration.ephemeral
    sessionConfiguration.requestCachePolicy = .returnCacheDataElseLoad
    sessionConfiguration.urlCache = .shared

    self.currentURLSession = URLSession(configuration: sessionConfiguration, delegate: self, delegateQueue: nil)

Запрос:

if let urlPath = URL(string: <WEB_API_END_POINT>){
        var aRequest = URLRequest(url: urlPath, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 60)
        aRequest.addValue("private", forHTTPHeaderField: "Cache-Control")

        let aTask = self.currentURLSession.dataTask(with: aRequest)

        aTask.resume()

}

Логика кэширования:

func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, willCacheResponse proposedResponse: CachedURLResponse, completionHandler: @escaping (CachedURLResponse?) -> Void) {       
    if proposedResponse.response.url?.path.contains("/employees") == true {
        let updatedResponse = proposedResponse.response(withExpirationDuration: 60)
        completionHandler(updatedResponse)
    } else {
        completionHandler(proposedResponse)
    }
}

Расширение CachedURLResponse:

extension CachedURLResponse {
func response(withExpirationDuration duration: Int) -> CachedURLResponse {
    var cachedResponse = self
    if let httpResponse = cachedResponse.response as? HTTPURLResponse, var headers = httpResponse.allHeaderFields as? [String : String], let url = httpResponse.url{

        headers["Cache-Control"] = "max-age=\(duration)"
        headers.removeValue(forKey: "Expires")
        headers.removeValue(forKey: "s-maxage")

        if let newResponse = HTTPURLResponse(url: url, statusCode: httpResponse.statusCode, httpVersion: "HTTP/1.1", headerFields: headers) {
            cachedResponse = CachedURLResponse(response: newResponse, data: cachedResponse.data, userInfo: headers, storagePolicy: .allowedInMemoryOnly)
        }
    }
    return cachedResponse
}

}


person Om Prakash    schedule 02.06.2020    source источник


Ответы (1)


Смог починить своими силами. Все еще делюсь ответом на случай, если он поможет кому-то еще в этом нуждается.

Добавлен заголовок ответа «Cache-Control» в ответе сервера, и там у нас есть «max-age: 60». , что указывает на то, что ответ может быть действителен только до 60 секунд. Таким образом, до 60 секунд приложение будет кэшировать эти данные, а через 60 секунд, если будет выполнен еще один запрос, оно будет получать свежие данные с сервера.

При этом на стороне клиента, кроме определения вашей политики кэширования, больше ничего не требуется. Вы можете сделать это либо для всего сеанса URL:

let sessionConfiguration: URLSessionConfiguration = URLSessionConfiguration.ephemeral
sessionConfiguration.requestCachePolicy = .useProtocolCachePolicy
sessionConfiguration.urlCache = .shared

self.currentURLSession = URLSession(configuration: sessionConfiguration, delegate: self, delegateQueue: nil)

Или может сделать это по конкретному запросу.

if let urlPath = URL(string: <WEB_API_END_POINT>) {
    var aRequest = URLRequest(url: urlPath, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 60)
    
    let aTask = self.currentURLSession.dataTask(with: aRequest)
    aTask.resume()
}
person Om Prakash    schedule 26.06.2020