5

I am trying to save data into cache using ASIHTTP (http://allseeing-i.com/ASIHTTPRequest/How-to-use#using_a_download_cache). I am not sure what I am doing wrong but it seems not to be storing data into cache. The output of the following code is this:

2010-08-12 15:44:13.801 TabBar[51728:207] Success is YES
2010-08-12 15:44:13.802 TabBar[51728:207] Success is NO
2010-08-12 15:44:13.804 TabBar[51728:207] Success is YES
2010-08-12 15:44:13.805 TabBar[51728:207] S-----------
2010-08-12 15:44:13.874 TabBar[51728:207] Success is YES
2010-08-12 15:44:13.874 TabBar[51728:207] Success is NO
2010-08-12 15:44:13.876 TabBar[51728:207] Success is YES

Here is the code:

[[ASIDownloadCache sharedCache] clearCachedResponsesForStoragePolicy:
                              ASICacheForSessionDurationCacheStoragePolicy];
[[ASIDownloadCache sharedCache] 
                    setDefaultCachePolicy:ASIOnlyLoadIfNotCachedCachePolicy];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL 
                                URLWithString:@"http://www.nytimes.com/"]];
[request setDownloadCache:[ASIDownloadCache sharedCache]];
[request startSynchronous];

request = [ASIHTTPRequest requestWithURL:[NSURL 
                                URLWithString:@"http://www.nytimes.com/"]];
[request setDownloadCache:[ASIDownloadCache sharedCache]];
[request startSynchronous];
BOOL success = ([request responseStatusCode] == 200);
NSLog(@"Success is %@\n", (success ? @"YES" : @"NO"));

success = [request didUseCachedResponse];
NSLog(@"Success is %@\n", (success ? @"YES" : @"NO"));

success = ([[request responseData] length]);
NSLog(@"Success is %@\n", (success ? @"YES" : @"NO"));

NSLog(@"S-----------");
request = [ASIHTTPRequest requestWithURL:[NSURL 
                    URLWithString:@"http://www.nytimes.com/"]];
[request setDownloadCache:[ASIDownloadCache sharedCache]];
[request startSynchronous];
success = ([request responseStatusCode] == 200);
NSLog(@"Success is %@\n", (success ? @"YES" : @"NO"));

success = [request didUseCachedResponse];
NSLog(@"Success is %@\n", (success ? @"YES" : @"NO"));

success = ([[request responseData] length]);
NSLog(@"Success is %@\n", (success ? @"YES" : @"NO"));

Can someone give me some code snippet on how to accomplish this?

Thanks!

-----------------------------------------------------------------------

NEW CODE REVISION:

NSURL *url = [NSURL URLWithString:imageURL];

ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDownloadCache:[ASIDownloadCache sharedCache]];
[request setCacheStoragePolicy:ASICachePermanentlyCacheStoragePolicy];
[request setCachePolicy:ASIOnlyLoadIfNotCachedCachePolicy];
[request setSecondsToCache:60*60*24*30]; // Cache for 30 days

[request startSynchronous];//startAsynchronous];

BOOL success = [request didUseCachedResponse];
NSLog(@"------------>>>>>>> Success is %@\n", (success ? @"YES" : @"NO"));

NSData *responseData = [request responseData];
UIImage *image = [[UIImage alloc] initWithData:responseData];

This only works with [request startSynchronous]; if I try Asynchronous method, it dosent call this function:

- (void)requestFinished:(ASIHTTPRequest *)request
user348398
  • 511
  • 2
  • 7
  • 17

2 Answers2

4

You are missing something like this,

ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDownloadCache:[ASIDownloadCache sharedCache]];
[request setCacheStoragePolicy:ASICachePermanentlyCacheStoragePolicy];
[request setCachePolicy:ASIOnlyLoadIfNotCachedCachePolicy];
[request setSecondsToCache:60*60*24*30]; // Cache for 30 days
[request setDelegate:self]; // A delegate must be specified
[request setDidFinishSelector:@selector(requestFinished:)]; // And an appropriate selector specified

And you should also have

- (void)requestFinished:(ASIHTTPRequest *)request {
  BOOL success = [request didUseCachedResponse];
  NSLog(@"------------>>>>>>> Success is %@\n", (success ? @"YES" : @"NO"));

  NSData *responseData = [request responseData];
  UIImage *image = [[UIImage alloc] initWithData:responseData];

  ...
}

This should do the trick.

StefanE
  • 41
  • 2
1

nytimes.com sets a lot of "don't cache me" type headers:

    $ HEAD http://www.nytimes.com/           
    200 OK
    Cache-Control: no-cache
    Date: Fri, 13 Aug 2010 07:14:46 GMT
    Pragma: no-cache
    Server: Sun-ONE-Web-Server/6.1
    Content-Length: 121266
    Content-Type: text/html
    Expires: Thu, 01 Dec 1994 16:00:00 GMT

So I would expect these are the problem.

You could try setting:

[[ASIDownloadCache sharedCache] shouldRespectCacheControlHeaders:NO];
JosephH
  • 37,173
  • 19
  • 130
  • 154
  • yeah I tried, but still getting no caching... I used [[ASIDownloadCache sharedCache] setShouldRespectCacheControlHeaders:NO]; – user348398 Aug 13 '10 at 14:48
  • Apologies for that typo - what you have is correct (I've fixed my answer now). I suggest you try single stepping through storeResponseForRequest in ASIDownloadCache.m, and if that appears to be storing the response correctly then try stepping through cachedHeadersForRequest and then out to it's caller. – JosephH Aug 13 '10 at 15:00
  • so I tried to put breakpoint in "" its going into this if condition all the time: if (policy == ASIIgnoreCachePolicy) { [[self accessLock] unlock]; return; } – user348398 Aug 13 '10 at 15:59
  • I was talking about "storeResponseForRequest" method – user348398 Aug 13 '10 at 16:00
  • Well done! I am not sure why that is happening though; you should be getting the policy you're setting, ASIOnlyLoadIfNotCachedCachePolicy. I think you'll need to debug a bit further. – JosephH Aug 13 '10 at 16:52
  • OK so I have got caching to work... but it only works with synchronous requests... how to make it work with [request startAsynchronous]? Will I have to run my own thread in background with Synchronous request? Will that cause any problem with caching? – user348398 Aug 13 '10 at 21:39
  • The caching works fine for asynchronous requests. Have you changed your code over to looking for the result in the requestFinished: selector and setup the delegate? Can you post the full new code? – JosephH Aug 14 '10 at 09:31
  • Hi Joseph, I have pasted the new code above under my question. Please have a look :) – user348398 Aug 15 '10 at 19:57
  • I think you need a call to [request setDelegate:self]; before the startAsynchronous – JosephH Aug 15 '10 at 20:49
  • Oh yeah! I totally forgot about that... That solved the problem, its all working flawlessly now, at least one of my life's problem is now solved :) Thanks for all the help! Have a wonderful day! – user348398 Aug 15 '10 at 21:38
  • Glad to hear it - if you're happy with the solution you can mark this answer as accepted (click the tick to the top left of the answer) and upvote it by clicking on the up arrow. Thanks – JosephH Aug 16 '10 at 07:25
  • i was having issues with the cache as well. I finally narrowed down the problem to this line of code in the main method of ASIHTTPRequest: if (![[self requestMethod] isEqualToString:@"GET"]) { [self setDownloadCache:nil]; } – ecbtln Mar 12 '12 at 19:38