URLCache.cachedResponse(for:) 和 URLCache.getCachedResponse(for:completionHandler:) 有什么区别?

问题描述 投票:0回答:2

我正在使用一个使用以下标头响应的服务器:

Cache-Control: no-cache  
last-modified: Mon, 17 Dec 2018 14:47:19 GMT  

以下代码:

let myTask = URLSession.shared.dataTask(request: myRequest, completionHandler: { ... })  
myTask.resume()  

正确发送

If-Modified-Since
标头。

但是当我这样做时:

URLCache.shared.cachedResponse(for: myRequest)  

我得到了

nil
结果,而:

URLCache.shared.getCachedResponse(for: myTask, completionHandler: { ... })  

我在

nil
中得到了非
completionHandler
结果。

我本以为两者都会给我类似的结果。有人可以向我解释一下吗?

swift nsurlcache
2个回答
0
投票

这会检查我的本地缓存响应。

if let request = dataRequest.request {
  if (URLCache.shared.cachedResponse(for: request) != nil) {
    URLCache.shared.removeCachedResponse(for: request)
  }
}

您也可以按照苹果检查定义。

enter image description here

enter image description here


0
投票

我知道这已经很老了,但鉴于这已经引起了一些关注,我想分享我的经验。我的问题是在设置请求标头之前我正在检查 URLCache。两个请求都需要有标头。如果不这样做,最终就会失败。我不确定有多少标题需要相等(如果有的话)。 AFAIK 两个请求都需要有标头存在,或者都没有标头

下面是异步工作示例,我们可以检查数据是否被缓存并返回缓存的数据

let token = "JWTToken"
let url = URL(string: "someWebsite")!
let headers = [
    "Authorization": "Bearer \(token)",
    "accept-language": "en-US",
]
var request = URLRequest(url: url)
request.allHTTPHeaderFields = headers

// Pull data from cache if exists

if let cachedResponse = URLCache.shared.cachedResponse(for: request) {
    let myCachedResponseObject = try JSONDecoder().decode(MyCustomObject.self, from: cachedResponse.data)
} else {
    print("No cached response")
}

// Else perform request

let (data, res) = try await URLSession.shared.data(for: request)
// ...

或者,我们可以修改请求以从缓存的响应中获取 ETag,并检查服务器以查看数据是否尚未修改(它将返回状态代码 304)(如果服务器设置为以这种方式工作)

if let cachedResponse = URLCache.shared.cachedResponse(for: request) {
    if let response = cachedResponse.response as? HTTPURLResponse {
        let headers = response.allHeaderFields
        let etag = headers["Etag"] as? String ?? "-" // get the etag and cache control
        let cc = headers["Cache-Control"] ?? "-" // policy from the headers
        request.setValue(etag, forHTTPHeaderField: "if-none-match") // set our request
        request.setValue(cc, forHTTPHeaderField: "cache-control") // headers to match it
    }
} else {
    print("No cached response")
}

let (data, res) = try await URLSession.shared.data(for: request) // perform request

if let response = (res as? HTTPURLResponse) {
    if response.statusCode == 304 {
// Server told us no need to update data
        print("\(response.statusCode) Not modified")
        guard let cachedResponse = URLCache.shared.cachedResponse(for: request) else {
            return // this should theoretically never hit because to get here there must've been existing cache for this request
        }
        let myResponseObject = try JSONDecoder().decode(MyCustomObject.self, from: cachedResponse.data) // decode the data from cache
    } else {
        print("Status: \(response.statusCode)")
    }
}
// Server said its time to update our data
let myResponseObject = try JSONDecoder().decode(MyCustomObject.self, from: data) // decode the new data received from the server
URLCache.shared.removeCachedResponse(for: request) // Remove the old cached data
URLCache.shared.storeCachedResponse(CachedURLResponse(response: res, data: data), for: request) // store the newly received data in cache

请记住,这使用异步函数调用,因此您必须将整个内容包装在异步函数或

Task {}
组中

希望这有帮助:)

© www.soinside.com 2019 - 2024. All rights reserved.