我使用以下代码进行缓存,从服务器接收到的响应具有以下标题。是否有任何标题需要从请求端设置,缓存才能工作10秒。
连接收到Resopnse Headers=日期: Sat,2015年9月12日22:51:16格林尼治时间,传输-编码:标识,服务器: Apache-Coyote/1.1,内容-类型: application/json;charset=UTF-8,过期: Sat,2015年9月12日22:51:26 GMT,缓存控制:最大年龄=10,必须重新验证
强大的代码,而不是缓存。
import UIKit
class HTTPJSONDonwload: NSObject , NSURLConnectionDataDelegate , NSURLConnectionDelegate {
static let httpjsonDownloader:HTTPJSONDonwload = HTTPJSONDonwload()
func startDownload(){
let serverRequest = getServerURL()
NSURLConnection(request: serverRequest, delegate: self, startImmediately: true)
}
func getServerURL() -> NSMutableURLRequest{
let request:NSMutableURLRequest = NSMutableURLRequest(URL:NSURL(string:"http://citiesfav-jcitiesj.rhcloud.com/Cache/getAllCities")! )
request.cachePolicy = NSURLRequestCachePolicy.UseProtocolCachePolicy
request.HTTPMethod = "POST"
return request
}
func connection(connection: NSURLConnection, didReceiveData data: NSData) {
print("Connection Data= \(NSString(data: data, encoding: NSUTF8StringEncoding))")
}
func connection(connection: NSURLConnection, didReceiveResponse response: NSURLResponse) {
print("Connection Received Resopnse Headers= \((response as! NSHTTPURLResponse).allHeaderFields)")
}
func connection(connection: NSURLConnection, willCacheResponse cachedResponse: NSCachedURLResponse) -> NSCachedURLResponse? {
print("Connection will cache Response")
return cachedResponse
}
}在从报头中删除必须重新验证之后,它仍在获取请求。
连接已接收Resopnse Headers=缓存-控制:最大年龄=10,传输-编码:标识,日期: Sun,2015年9月13日18:35:43 GMT,内容类型: application/json;charset=UTF-8,服务器: Apache-Coyote/1.1,过期: Sun,2015年9月13日18:35:53 GMT
后来的调查结果显示,POST请求确实被缓存,但不像GET那样工作,在get中考虑的是最大年龄。
func startDownload(){
let serverRequest = getServerURL()
let cache = NSURLCache.sharedURLCache()
let response = cache.cachedResponseForRequest(serverRequest)
if response != nil {
serverRequest.cachePolicy = NSURLRequestCachePolicy.ReturnCacheDataDontLoad
}
NSURLConnection(request: serverRequest, delegate: self, startImmediately: true)
}发布于 2015-09-14 06:32:44
tl;dr
您需要使用GET而不是POST。
冗长的解释
问题是,您的请求是一个POST。
func getServerURL() -> NSMutableURLRequest{
...
request.HTTPMethod = "POST"
...
}通常,POST请求用于创建(有时也是更新)服务器上的资源。为创建或更新请求重用缓存的响应没有多大意义,因为无论如何您必须将请求发送到服务器(否则不会创建或更新任何内容)。iOS似乎会自动绕过POST请求上的缓存。
但是,在您的特定情况下,您并不真正需要POST,因为您只是从服务器读取数据。这意味着您应该使用GET请求。
func getServerURL() -> NSMutableURLRequest{
...
request.HTTPMethod = "GET"
...
}我验证了iOS系统实际上使用以下代码片段重用缓存。
let d = HTTPJSONDonwload()
// Initial request. Can not reuse cache.
d.startDownload()
// Subsequent request after 5 seconds. Should be able to reuse the cache.
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(5 * NSEC_PER_SEC)), dispatch_get_main_queue()) {
d.startDownload()
}
// Subsequent request after 11 seconds. Cannot reuse the cache because
// the expiration timeout is 10 seconds.
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(11 * NSEC_PER_SEC)), dispatch_get_main_queue()) {
d.startDownload()
}当我在模拟器中运行这个程序并使用Charles Proxy监视网络调用时,我确实只看到两个事件:

第一个调用是初始请求。

第二个呼叫是延迟11秒后发出的第三个请求。

注意,5秒后发出的第二个请求没有出现,这意味着响应是从缓存中检索的。然而,NSURLConnection的委托方法仍然会被调用,就像响应来自网络一样。因此,使用代码中的日志输出,您将看到控制台上的所有三个请求。
Connection Received Resopnse Headers= [Server: Apache-Coyote/1.1, Content-Type: application/json;charset=UTF-8, Keep-Alive: timeout=15, max=100, Proxy-Connection: Keep-alive, Date: Mon, 14 Sep 2015 06:28:05 GMT, Content-Encoding: gzip, Content-Length: 36, Cache-Control: max-age=10, Vary: Accept-Encoding]
Connection Data= Optional({"1":"New York"})
Connection will cache Response
Connection Received Resopnse Headers= [Server: Apache-Coyote/1.1, Content-Type: application/json;charset=UTF-8, Keep-Alive: timeout=15, max=100, Proxy-Connection: Keep-alive, Date: Mon, 14 Sep 2015 06:28:05 GMT, Content-Encoding: gzip, Content-Length: 36, Cache-Control: max-age=10, Vary: Accept-Encoding]
Connection Data= Optional({"1":"New York"})
Connection Received Resopnse Headers= [Server: Apache-Coyote/1.1, Content-Type: application/json;charset=UTF-8, Keep-Alive: timeout=15, max=99, Proxy-Connection: Keep-alive, Date: Mon, 14 Sep 2015 06:28:16 GMT, Content-Encoding: gzip, Content-Length: 36, Cache-Control: max-age=10, Vary: Accept-Encoding]
Connection Data= Optional({"1":"New York"})
Connection will cache Response注意,在第二个请求之后没有Connection will cache Response,因为响应是从缓存中检索的,并且没有必要再次缓存它。
https://stackoverflow.com/questions/32368045
复制相似问题