0

I am using this block for a synchronous image downloading in an iOS 5 app. The logic is simple, if image is in cache use it, if not download it, I suppose NSURLRequestReturnCacheDataElseLoad has exactly this behavior.

    [factory.downloadImagesQueue addOperationWithBlock:^(){
        NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/%@",IP2BaseImgURL,imgName]];
        NSURLRequest *request = [NSURLRequest requestWithURL:url
                         cachePolicy:NSURLRequestReturnCacheDataElseLoad
                     timeoutInterval:15.0];

        NSCachedURLResponse* cachedResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:request];
        if (cachedResponse!=nil) {
            NSLog(@"%@ found in cache",imgName);
            [delegate imageDidFinishDownload:[UIImage imageWithData:[cachedResponse data]] atIndexPath:indexPath];
        } else {
            NSError *error;
            NSURLResponse *response;
            NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
            if (data == nil) {
                FULL_ERROR_LOG(error)
            } else {
                NSLog(@"%@ downloaded",imgName);
                if (![response.MIMEType isEqualToString:@"image/png"] && ![response.MIMEType isEqualToString:@"image/jpeg"]) {
                    NSLog(@"Found wrong mime type: %@",response.MIMEType);
                    [delegate imageDidEncounterErrorWhileDownload:imgName atIndexPath:indexPath];
                } else {
                    NSCachedURLResponse *cachedResponse = [[NSCachedURLResponse alloc] initWithResponse:response data:data];
                    [[NSURLCache sharedURLCache] storeCachedResponse:cachedResponse forRequest:(NSURLRequest *)request];
                    [delegate imageDidFinishDownload:[UIImage imageWithData:data] atIndexPath:indexPath];
                }
            }
        }

    }];

I did a test with three images. When I am downloading them for first time, I can see the message 'downloaded MyimgName1.jpg' 'downloaded MyimgName2.jpg' 'downloaded MyimgName3.jpg', and by opening the Cache.db I can see all my images correctly stored in it.

However when I am trying to download again, only the very first downloaded images show the message 'MyimgName1.jpg found in cache', which means that the cachedResponse is nil for all the other 2 and 3 request:

    NSCachedURLResponse* cachedResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:request];
    if (cachedResponse!=nil) { // <-- nil
    }

am I missing something in the settings or creation of NSCache ?

Leonardo
  • 9,607
  • 17
  • 49
  • 89

1 Answers1

0

The line:

[[NSURLCache sharedURLCache] storeCachedResponse:cachedResponse forRequest:(NSURLRequest *)request];

Will always store nil as it's inside the if when value for 'cachedResponse' is nil. I wonder how you even are caching anything.

Anyway, you should write allocate a new instance of NSCachedURLResponse before inserting it inside the cache. As a side note, try to change the capacity of cache, that may be the problem. You can change it with setMemoryCapacity:

DarthMike
  • 3,471
  • 1
  • 22
  • 18
  • You are right, it's typo error, I forgot to paste a line of code, where I am creating the new cachedResponse. I am modifying my code. – Leonardo Nov 10 '12 at 12:57
  • Did you try augment the size of shared URL cache via setMemoryCapacity? – DarthMike Nov 10 '12 at 16:54