Alamofire - NSURLCache 不工作?
Alamofire - NSURLCache is not working?
我的缓存设置如下
var cacheSizeMemory = 20 * 1024 * 1024
var cacheSizeDisk = 100 * 1024 * 1024
var sharedCache = NSURLCache(memoryCapacity: cacheSizeMemory, diskCapacity: cacheSizeDisk, diskPath: "SOME_PATH")
NSURLCache.setSharedURLCache(sharedCache)
使用缓存策略创建请求
var request = NSMutableURLRequest(URL: NSURL(string: "\(baseUrl!)\(path)")!, cachePolicy: .ReturnCacheDataElseLoad, timeoutInterval: timeout)
发出请求并获得以下响应 Cache-Control
private, max-age=60
然后尝试检查缓存
var cachedResponse = NSURLCache.sharedURLCache().cachedResponseForRequest(urlRequest)
值为零
有什么想法吗?
我最终在我的请求的 header 中手动添加 Cache-Control
作为 private
,它现在可以工作了。甚至不需要手动检查缓存,Alamofire 为您代劳
let cachePolicy: NSURLRequestCachePolicy = isReachable() ? .ReloadIgnoringLocalCacheData : .ReturnCacheDataElseLoad
var request = NSMutableURLRequest(URL: NSURL(string: "\(baseUrl!)\(path)")!, cachePolicy: cachePolicy, timeoutInterval: timeout)
request.addValue("private", forHTTPHeaderField: "Cache-Control")
var alamoRequest = Manager.sharedInstance.request(urlRequest)
我可以像这样将页面写入 sharedURLCache 来手动缓存页面:
Alamofire.request(req)
.response {(request, res, data, error) in
let cachedURLResponse = NSCachedURLResponse(response: res!, data: (data as NSData), userInfo: nil, storagePolicy: .Allowed)
NSURLCache.sharedURLCache().storeCachedResponse(cachedURLResponse, forRequest: request)
}
NSURLCache 似乎尊重服务器发送的headers,即使您在代码中的其他地方配置了相反的配置。
维基百科API,例如,发送
Cache-control: private, must-revalidate, max-age=0
这意味着:必须在 0 秒后重新生效。
所以 NSURLCache 说:“好的,我不会缓存任何东西。”
但是通过手动将响应保存到缓存中,它可以工作。至少在 iOS 8.2.
我差点对这个失去理智。 :)
[SwiftNSURLcache过期解决方案]
我认为这里的主要问题是:ReturnCacheDataElseLoad
。
@arayax 给了你可能会解决这个问题的答案,但我的解决方案是这样的:
因为我将 Alamofire 用于网络请求,所以我设置了我的配置:
configuration.requestCachePolicy = .ReturnCacheDataElseLoad
当我发出请求时,我会检查互联网连接,如果是真的,然后清除 NSURLCache,这样它会强制 Alamofire 在服务器上而不是从缓存中发出请求:
if Reachability.isConnectedToNetwork() == true {
ConfigService.cache.removeAllCachedResponses()
}
ConfigService.manager?.request(.GET, ...
我希望这会有所帮助,也许对于 NSURLCache 的其他类型的问题:)
对我来说是 Pragma →no-cache 删除后一切正常。
这就是我如何让缓存与 Alamofire 4 和 swift 3 一起工作(半完整功能供参考):
func getTheList(courseId : String )-> Void{
appConstants.sharedInstance.startLoading()
let TheURL = DEFAULT_APP_URL + "api/getMyList?Id="+ID
let urlString = NSURL(string: TheURL)
var mutableURLRequest = URLRequest(url: urlString! as URL)
mutableURLRequest.httpMethod = "GET"
mutableURLRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
mutableURLRequest.cachePolicy = NSURLRequest.CachePolicy.returnCacheDataElseLoad
Alamofire.request(mutableURLRequest)
.responseJSON
{.......
我发现 URLCache 不会保存大于 5% (1/20) 容量的响应。
默认缓存的 memoryCapacity = 512000,它不会将大于 25600 的响应保存到内存中。
作为扩展容量的解决方案
我的缓存设置如下
var cacheSizeMemory = 20 * 1024 * 1024
var cacheSizeDisk = 100 * 1024 * 1024
var sharedCache = NSURLCache(memoryCapacity: cacheSizeMemory, diskCapacity: cacheSizeDisk, diskPath: "SOME_PATH")
NSURLCache.setSharedURLCache(sharedCache)
使用缓存策略创建请求
var request = NSMutableURLRequest(URL: NSURL(string: "\(baseUrl!)\(path)")!, cachePolicy: .ReturnCacheDataElseLoad, timeoutInterval: timeout)
发出请求并获得以下响应 Cache-Control
private, max-age=60
然后尝试检查缓存
var cachedResponse = NSURLCache.sharedURLCache().cachedResponseForRequest(urlRequest)
值为零
有什么想法吗?
我最终在我的请求的 header 中手动添加 Cache-Control
作为 private
,它现在可以工作了。甚至不需要手动检查缓存,Alamofire 为您代劳
let cachePolicy: NSURLRequestCachePolicy = isReachable() ? .ReloadIgnoringLocalCacheData : .ReturnCacheDataElseLoad
var request = NSMutableURLRequest(URL: NSURL(string: "\(baseUrl!)\(path)")!, cachePolicy: cachePolicy, timeoutInterval: timeout)
request.addValue("private", forHTTPHeaderField: "Cache-Control")
var alamoRequest = Manager.sharedInstance.request(urlRequest)
我可以像这样将页面写入 sharedURLCache 来手动缓存页面:
Alamofire.request(req)
.response {(request, res, data, error) in
let cachedURLResponse = NSCachedURLResponse(response: res!, data: (data as NSData), userInfo: nil, storagePolicy: .Allowed)
NSURLCache.sharedURLCache().storeCachedResponse(cachedURLResponse, forRequest: request)
}
NSURLCache 似乎尊重服务器发送的headers,即使您在代码中的其他地方配置了相反的配置。
维基百科API,例如,发送
Cache-control: private, must-revalidate, max-age=0
这意味着:必须在 0 秒后重新生效。
所以 NSURLCache 说:“好的,我不会缓存任何东西。”
但是通过手动将响应保存到缓存中,它可以工作。至少在 iOS 8.2.
我差点对这个失去理智。 :)
[SwiftNSURLcache过期解决方案]
我认为这里的主要问题是:ReturnCacheDataElseLoad
。
@arayax 给了你可能会解决这个问题的答案,但我的解决方案是这样的:
因为我将 Alamofire 用于网络请求,所以我设置了我的配置:
configuration.requestCachePolicy = .ReturnCacheDataElseLoad
当我发出请求时,我会检查互联网连接,如果是真的,然后清除 NSURLCache,这样它会强制 Alamofire 在服务器上而不是从缓存中发出请求:
if Reachability.isConnectedToNetwork() == true {
ConfigService.cache.removeAllCachedResponses()
}
ConfigService.manager?.request(.GET, ...
我希望这会有所帮助,也许对于 NSURLCache 的其他类型的问题:)
对我来说是 Pragma →no-cache 删除后一切正常。
这就是我如何让缓存与 Alamofire 4 和 swift 3 一起工作(半完整功能供参考):
func getTheList(courseId : String )-> Void{
appConstants.sharedInstance.startLoading()
let TheURL = DEFAULT_APP_URL + "api/getMyList?Id="+ID
let urlString = NSURL(string: TheURL)
var mutableURLRequest = URLRequest(url: urlString! as URL)
mutableURLRequest.httpMethod = "GET"
mutableURLRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
mutableURLRequest.cachePolicy = NSURLRequest.CachePolicy.returnCacheDataElseLoad
Alamofire.request(mutableURLRequest)
.responseJSON
{.......
我发现 URLCache 不会保存大于 5% (1/20) 容量的响应。
默认缓存的 memoryCapacity = 512000,它不会将大于 25600 的响应保存到内存中。
作为扩展容量的解决方案