1

First time to use AFNetworking. When I use it to download/reload image for my collectionView with setImageWithURLRequest:request method, I found the images could be downloaded, but never load from the cached image.

Well, I searched internet before asking this question, most of them said to use setImageWithURLRequest:request and it has a cache policy for the NSURLRequest I could configure before. I configure the policy as NSURLRequestReturnCacheDataElseLoad, it means use the cached data first otherwise re-download it if I understand correctly. And they also said I could check the response == nil to know if cached image is used. I also set the cache capacity in AppDelegate didFinishLaunching, though my image is roughly 50KB.

However it never happened, the response is always has a value in my case. Please advice what I am missing here?

AppDelegate

    NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:20 * 1024 * 1024
                                                            diskCapacity:200 * 1024 * 1024
                                                            directoryURL:nil];
    [NSURLCache setSharedURLCache:sharedCache];

The code snipper for download image

- (void)setupThumbnailImage {
    
    __weak typeof(self) weakSelf = self;
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSURL *url = [NSURL URLWithString:weakSelf.video.thumbnailImageName];
        NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:60];
        [weakSelf.videoImageView setImageWithURLRequest:request placeholderImage:nil success:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, UIImage * _Nonnull image) {
            
            dispatch_async(dispatch_get_main_queue(), ^{
                if (!response) {
                    weakSelf.videoImageView.image = image;
                    NSLog(@"use cache image ");
                } else {
                    weakSelf.videoImageView.image = image;
                    NSLog(@"redownload image ");
                }
            });
        } failure:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, NSError * _Nonnull error) {
            NSLog(@"Error: %@", error.localizedDescription);
        }];
    });
}

Update

Per Larme's comment, I did 2 test. First I put a break point on line 97 UIImage *cachedImage = [imageCache imageforRequest:urlRequest withAdditionalIdentifier:nil]; in file "UIImageView+AFNetworking.h".

  1. Use NSURLRequestReturnCacheDataDontLoad and turn off network(offline mode).

Result: In debug console, I could see the cachedImage is nil. Then it try to use network to download the image. And an error fired as no network available.

Task <8A1D55F5-F884-4FEC-B7DF-756BD0BB2B34>.<6> HTTP load failed, 0/0 bytes (error code: -1009 [1:50]) Error Domain=NSURLErrorDomain Code=-1009 "The Internet connection appears to be offline."

  1. use NSURLRequestReturnCacheDataElseLoad, and put my method for downloading image into viewDidAppear, then do a VC switch/switch back.

Result: this method fired again, and this time it used cache image because code step over into if (cachedImage) statement and also NSLog(@"use cache image "); is printed out.

So in-memory cache image works. Current problem is in-disk cache image, when the app is closed and reopen, the method try to use the network to re-download images instead loading it from cache images.

Next, as larme'spoint, I'd like to dig into AFNetworking code to find out what URL path is actually used for their default cache image. Alternatively, I could write an in-disk image cache to not use AFNetworking image cache.

Zhou Haibo
  • 1,681
  • 1
  • 12
  • 32
  • Thanks, so I assume `on-disk cache` would take care cached images when the app is closed. Consider I have tried it on my iPhone or simulator, and be sure the space is enough. Then I will change the question title to the original one, focus on why cached image is not used when reopen the app. – Zhou Haibo Sep 11 '21 at 07:28
  • See the green counters “Related” on the right side of the stackoverflow webpage? Each represents similar questions.. one of them has your answer i think [this one](https://stackoverflow.com/questions/15705709/how-to-use-nsurlcache-to-return-cached-api-responses-when-offline-ios-app?rq=1). – Ol Sen Sep 11 '21 at 07:31
  • Thank you, I read the whole issue thread in Github. It seems there was an error about `NSURLConnection` in iOS 6 and was fixed in iOS 7, though I meet the same issue again in 2021. I would try to figure out what is wrong. – Zhou Haibo Sep 11 '21 at 12:47
  • Put a breakpoint on line 97 https://github.com/AFNetworking/AFNetworking/blob/77ef5fed64d98107acd177a90182163a20ba4567/UIKit%2BAFNetworking/UIImageView%2BAFNetworking.m#L97 checking the value of `[imageCache imageforRequest:urlRequest withAdditionalIdentifier:nil]` Indeed `response` nil means using the cache, but their cache, not yours, which I guess is the defaultone as said there https://github.com/AFNetworking/AFNetworking/blob/77ef5fed64d98107acd177a90182163a20ba4567/UIKit%2BAFNetworking/AFImageDownloader.m – Larme Sep 11 '21 at 19:13
  • @Larme, thanks, I did a few test and update in my question, feel free to have a look. – Zhou Haibo Sep 12 '21 at 02:58
  • `I'd like to dig into AFNetworking code to find out what URL path is actually used for their default cache image`: Did you read the code in that method? It's calling `id imageCache = downloader.imageCache;`, check the value of that cache, where it's set. And I guess it will be `+ (NSURLCache *)defaultURLCache` unless you set it, or it's a `[[AFAutoPurgingImageCache alloc] init]`... Add breakpoint inside the AFNetworking code... – Larme Sep 12 '21 at 22:29

0 Answers0