Is it possible to force response caching if it contains neither Expires
or Cache-Control: max-age
?
I've came across this article, but unfortunately URLSession:dataTask:willCacheResponse:completionHandler:
never gets called in my AFHTTPSessionManager
subclass.
Any help appreciated.
You can force the caching by implementing your own NSURLProtocol
that does not follow the standard HTTP caching rules. A complete tutorial is here, which persists the data using Core Data, but the basic steps are:
NSURLProtocol
+registerClass:
YES
in your +canInitWithRequest:
method if this is the first time you've seen request
, or NO
if it isn'tYou now have two choices:
Assuming you want #2, override connection:didReceiveResponse:
in your protocol subclass to create a response that has the cache control headers you want to emulate:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response {
// Create a dictionary with the headers you want
NSMutableDictionary *newHeaders = [response.allHeaderFields mutableCopy];
newHeaders[@"Cache-Control"] = @"no-transform,public,max-age=300,s-maxage=900";
// Create a new response
NSHTTPURLResponse *newResponse = [[NSHTTPURLResponse alloc] initWithURL:response.URL
statusCode:response.statusCode
HTTPVersion:@"HTTP/1.1"
headerFields:newHeaders];
[self.client URLProtocol:self
didReceiveResponse:newResponse
cacheStoragePolicy:NSURLCacheStorageAllowed];
}
This will cause the response to be cached as if the server had provided these headers.
For URL sessions only, you need to set the session configuration's protocolClasses
. Since you're using AFNetworking, that looks like:
[AFHTTPSessionManager sharedManager].session.configuration.protocolClasses = @[[MyURLProtocol class]]
There are some caveats, so make sure you read the protocolClasses
documentation.
A few notes:
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