Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use NSURLCache to return cached API responses when offline (iOS App)

I'm hoping someone can shed some light on a few things I've been researching but not making much progress on.

I'd like to take advantage of NSURLCache to return cached responses for API calls that I make within an iOS App. When the device is online, I'd like to return the cached response if it's recent enough, otherwise fetch from remote. When the device is offline I'd like to immediately return the cached response (if any) regardless of it's age.

I'm using AFNetworking. The API calls that I'm making are to a server I control. Protocol is HTTPS. The Cache-Control response header is currently "max-age=0, public". I'm not currently setting cache related request headers (should I?). I set the request's cache policy to be NSURLRequestReturnCacheDataDontLoad when offline and use the default NSURLRequestUseProtocolCachePolicy when online. And I can see the requests and their responses in the default Cache.db on disk. However when I'm offline all requests fail (no cached responses (despite appearing to have been cached) are being used/returned.

Per http://nshipster.com/nsurlcache/ I initialize a sharedURLCache in didFinishLaunchingWithOptions and set the AFNetworking setCacheResponse block to something like this:

NSMutableDictionary *mutableUserInfo = [[cachedResponse userInfo] mutableCopy]; 
NSMutableData *mutableData = [[cachedResponse data] mutableCopy]; 
NSURLCacheStoragePolicy storagePolicy = NSURLCacheStorageAllowed;
return [[NSCachedURLResponse alloc] initWithResponse:[cachedResponse response] data:mutableData userInfo:mutableUserInfo storagePolicy:storagePolicy];

I've read these and other posts on the topic:

http://petersteinberger.com/blog/2012/nsurlcache-uses-a-disk-cache-as-of-ios5/ http://blackpixel.com/blog/2012/05/caching-and-nsurlconnection.html

I'm wondering if anyone out there has successfully achieved this functionality before using the standard NSURLCache (also interested in success stories involving SDURLCache but Peter S. says as of iOS5 disk caching is supported therefore SDURLCache is no longer needed, ie I'd like to use the default built in cache).

Thanks in advance!

like image 579
Alfie Hanssen Avatar asked Mar 29 '13 14:03

Alfie Hanssen


1 Answers

Did you see this post?

AFNetworking (AFHttpClient) offline mode not working with NSURLRequestReturnCacheDataDontLoad policy

Looks like it might be a bug with iOS 6. Here is what Robert Mao had to say in the post:

A summarized work around is read the response from cache, instead of use NSURLRequestReturnCacheDataDontLoad policy:

NSCachedURLResponse *cachedResponse = [[NSURLCache sharedURLCache]     cachedResponseForRequest:request];
if (cachedResponse != nil &&
    [[cachedResponse data] length] > 0)
{
    // Get cached data
    ....
}
like image 107
Del Brown Avatar answered Sep 23 '22 23:09

Del Brown