Skip to content

Instantly share code, notes, and snippets.

@bogardon
Created August 3, 2012 07:32
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bogardon/3245415 to your computer and use it in GitHub Desktop.
Save bogardon/3245415 to your computer and use it in GitHub Desktop.
Taking Advantage of iOS5 Built-In HTTP DiskCache
- (NSCachedURLResponse *) cachedResponseForRequest:(NSURLRequest *)request {
NSCachedURLResponse *cachedURLResponse = [super cachedResponseForRequest:request];
if (cachedURLResponse == nil && [request.HTTPMethod isEqualToString:@"GET"]) {
//[db executeQuery:@"select * from test where a = ?", @"hi'", nil];
FMResultSet *cfurl_cache_response = [self.db executeQuery:@"select * from cfurl_cache_response where request_key = ? limit 1", request.URL.absoluteString, nil];
if ([cfurl_cache_response next]) {
id entry_ID = [cfurl_cache_response objectForColumnName:@"entry_ID"];
[cfurl_cache_response close];
if (entry_ID != [NSNull null]) {
FMResultSet *cfurl_cache_blob_data = [self.db executeQuery:@"select * from cfurl_cache_blob_data where entry_ID = ? limit 1", entry_ID, nil];
if ([cfurl_cache_blob_data next]) {
id response_object = [cfurl_cache_blob_data objectForColumnName:@"response_object"];
[cfurl_cache_blob_data close];
FMResultSet *cfurl_receiver_data = [self.db executeQuery:@"select * from cfurl_cache_receiver_data where entry_ID = ? limit 1", entry_ID, nil];
if ([cfurl_receiver_data next]) {
id receiver_data = [cfurl_receiver_data objectForColumnName:@"receiver_data"];
[cfurl_receiver_data close];
if (response_object != [NSNull null] && receiver_data != [NSNull null] && response_object && receiver_data) {
NSURLResponse *urlResponse = [[[NSURLResponse alloc] initWithURL:request.URL MIMEType:[[request allHTTPHeaderFields] objectForKey:@"Accept"] expectedContentLength:[(NSData *)response_object length] textEncodingName:nil] autorelease];
cachedURLResponse = [[[NSCachedURLResponse alloc] initWithResponse:urlResponse data:receiver_data userInfo:nil storagePolicy:NSURLCacheStorageAllowed] autorelease];
}
}
}
}
}
}
return cachedURLResponse;
}
@bogardon
Copy link
Author

bogardon commented Aug 4, 2012

iOS 5 has a HTTP disk cache. Read more here: http://petersteinberger.com/blog/2012/nsurlcache-uses-a-disk-cache-as-of-ios5/

However, it is not documented and not supported by NSURLCache. The result is that NSURLCache does not take advantage of the disk cache as one might expect -- i.e. when NSURLCache hits a cache-miss in memory, it does not go to disk but instead goes to the network.

This is extremely frustrating especially when one is trying to implement an "offline mode" in their application. By using FMDB, we're essentially going to disk for them and bringing cached responses from the disk cache into the memory cache.

@asarazan
Copy link

I just want to take a second to thank you for this. NSURLCache has brought me nothing but sadness.

One question: How does this relate to the memory leaks that SDURLCache has been seeing? Since we're instantiating NSCachedURLResponse objects, is it still possibly an issue, or is that completely nonexistent without NSArchiving?

@bogardon
Copy link
Author

@asarazan My experience is that it only leaks when you explicitly call NSCachedURLResponse's data method. What have you found?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment