I've created an NSURLCache subclass which forces caching of responses for a designated amount of time. This is working well, and cached items are expired as expected. However I'm running into issues when trying to forcefully remove a cached response using NSURLCache's removeCachedResponseForRequest:
method.
What I'm looking to achieve is to allow users to force an immediate reload of remote data. To do this, I pass an "ignoreCache" flag when making a request. I construct my NSURLRequest as normal, but ask my NSURLCache to remove any previously cached responses for the given request. This doesn't seem to have any effect, however, as the cached result is still present and used when the request is executed.
The documentation around NSURLCache is fairly sparse. The NSURLCache headers state that the NSURLRequest passed to removeCachedResponseForRequest:
is used as a key to lookup the associated NSCachedURLResponse object, but there's little information given as to the logistics of that comparison. Does the NSURLCache class expect to receive the same NSURLRequest instance that generated the cached response, or does it simply compare the NSURL it represents?
Hopefully someone can point me in the right direction.
var error: NSError? = nil
var URLRequest: NSMutableURLRequest = self.operationManager.requestSerializer.requestWithMethod("GET", URLString: NSURL(string: request.URL, relativeToURL: self.operationManager.baseURL).absoluteString, parameters: request.parameters, error: &error)
URLRequest.cachePolicy = NSURLRequestCachePolicy.ReturnCacheDataElseLoad
// We've been asked to ignore the cache, so remove our previously cached response
if ignoreCache == true {
NSURLCache.sharedURLCache().removeCachedResponseForRequest(URLRequest)
}
Here's the Swift code from my NSURLCache subclass for reference:
// MARK: - NSURLCache
override func cachedResponseForRequest(request: NSURLRequest!) -> NSCachedURLResponse! {
var cachedResponse: NSCachedURLResponse? = super.cachedResponseForRequest(request)
if(cachedResponse != nil && cachedResponse!.userInfo != nil) {
var cacheDate: NSDate? = cachedResponse!.userInfo![self.cacheExpirationKey] as? NSDate
if(cacheDate != nil) {
var cacheDateLimit: NSDate = cacheDate!.dateByAddingTimeInterval(self.cacheExpirationInterval)
if(cacheDate!.compare(NSDate()) == NSComparisonResult.OrderedAscending) {
self.removeCachedResponseForRequest(request)
} else {
return cachedResponse
}
}
}
// Either our cached data was too old, or we don't have any that match the NSURLRequest
return nil
}
override func storeCachedResponse(cachedResponse: NSCachedURLResponse!, forRequest request: NSURLRequest!) {
var userInfo: NSMutableDictionary = NSMutableDictionary(dictionary: cachedResponse.userInfo)
userInfo[cacheExpirationKey] = NSDate().dateByAddingTimeInterval(self.cacheExpirationInterval)
var modifiedCacheResponse: NSCachedURLResponse = NSCachedURLResponse(response: cachedResponse.response, data: cachedResponse.data, userInfo: userInfo, storagePolicy: cachedResponse.storagePolicy)
super.storeCachedResponse(modifiedCacheResponse, forRequest: request)
}
Assuming you are on iOS 8, removeCachedResponseForRequest:
does not work.
See http://blog.airsource.co.uk/2014/10/13/nsurlcache-ios8-broken-2/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With