All http responses from a server come with the headers that inform our app not to cache the responses:
Cache-Control: no-cache
Pragma: no-cache
Expires: 0
So, if you are making NSUrlRequests with default cache policy "NSURLRequestUseProtocolCachePolicy" then the app will always load data from the server. However, we need to cache the responses and the obvious solution would be to set these headers to some time for example (at backend side), set to 10 seconds. But I'm interested in a solution how to bypass this policy and cache every request for 10 seconds.
For that you need to setup shared cache. That might be done in AppDelegate didFinishLaunchingWithOptions:
NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024
diskCapacity:20 * 1024 * 1024
diskPath:nil];
[NSURLCache setSharedURLCache:URLCache];
Then, we need to embed our code to force to cache a response. If you use an instance of AFHttpClient then it can be done by overriding the method below and manually storing the cache into the shared cache:
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection
willCacheResponse:(NSCachedURLResponse *)cachedResponse {
NSMutableDictionary *mutableUserInfo = [[cachedResponse userInfo] mutableCopy];
NSMutableData *mutableData = [[cachedResponse data] mutableCopy];
NSURLCacheStoragePolicy storagePolicy = NSURLCacheStorageAllowedInMemoryOnly;
// ...
return [[NSCachedURLResponse alloc] initWithResponse:[cachedResponse response]
data:mutableData
userInfo:mutableUserInfo
storagePolicy:storagePolicy];
}
And the last thing is to set cachePolicy for the requests. In our case we want to set the same cache policy to all requests. So again, if you use an instance of AFHttpClient then it can be done by overriding the method below:
- (NSMutableURLRequest *)requestWithMethod:(NSString *)method path:(NSString *)path parameters:(NSDictionary *)parameters {
NSMutableURLRequest *request = [super requestWithMethod:method path:path parameters:parameters];
request.cachePolicy = NSURLRequestReturnCacheDataElseLoad;
return request;
}
So far so good. "NSURLRequestReturnCacheDataElseLoad" makes to perform request first time and load response from cache all other times. The problem is, it's unclear how to set cache expiration time, for example 10 seconds.