Last active
August 29, 2015 14:05
-
-
Save a-square/1b6280e833f032ec08ba to your computer and use it in GitHub Desktop.
More responsive UIImageView+AFNetworking using NSURLCache
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// It's debatable if it's actually a good idea, because most of the time the image will be | |
// loaded from the cache without revalidation anyway, but it still has some utility in cases | |
// when max-age is short, or the image is big | |
// | |
// Also, it is more useful if we assume that max-age is smaller than the average user session, | |
// and that the iOS device never has to evict the images in the UIImageView+AFNetworking cache, | |
// because then *every* request for the image that actually goes through the NSURLCache will | |
// trigger the double request codepath. That being said, it's still probably excessive, because | |
// the amortised delay before the image is shown is still not affected much | |
- (void)setImageWithURLRequest:(NSURLRequest *)originalURLRequest | |
placeholderImage:(UIImage *)placeholderImage | |
success:(void (^)(NSURLRequest *, NSHTTPURLResponse *, UIImage *))success | |
failure:(void (^)(NSURLRequest *, NSHTTPURLResponse *, NSError *))failure | |
{ | |
__weak __typeof(self) weakSelf = self; | |
// first, try to find the image in the cache (both NSURLCache and UIImageView+AFNetworking caches) | |
NSMutableURLRequest *cacheOnlyURLRequest = [originalURLRequest mutableCopy]; | |
cacheOnlyURLRequest.cachePolicy = NSURLRequestReturnCacheDataDontLoad; | |
[self | |
superSetImageWithURLRequest:cacheOnlyURLRequest | |
placeholderImage:placeholderImage | |
// found the image in the cache | |
success:^void(NSURLRequest *urlRequest, NSHTTPURLResponse *urlResponse, UIImage *image) { | |
__typeof(self) strongSelf = weakSelf; | |
if (!strongSelf) { | |
return; | |
} | |
if (!urlResponse) { | |
// the image was in the UIImageView+AFNetworking cache, | |
// so we should just use it to avoid excessive network traffic | |
return; | |
} | |
// kill the image in the UIImageView+AFNetworking cache so that the next HTTP request | |
// goes through NSURLConnection | |
// WARNING: assumes that +sharedImageCache is actually an NSCache instance! | |
[(NSCache *)[[super class] sharedImageCache] removeObjectForKey:[[urlRequest URL] absoluteString]]; | |
// repeat the request, but now allow NSURLCache to revalidate it if needed | |
// use the previously received image as a placeholder | |
[strongSelf superSetImageWithURLRequest:originalURLRequest placeholderImage:image success:success failure:failure]; | |
} | |
// image not found in the cache | |
failure:^void(NSURLRequest *urlRequest, NSHTTPURLResponse *urlResponse, NSError *error) { | |
// default behavior | |
[weakSelf superSetImageWithURLRequest:originalURLRequest placeholderImage:placeholderImage success:success failure:failure]; | |
}]; | |
} | |
// a trick to avoid implicitly retaining self when using super | |
- (void)superSetImageWithURLRequest:(NSURLRequest *)urlRequest | |
placeholderImage:(UIImage *)placeholderImage | |
success:(void (^)(NSURLRequest *, NSHTTPURLResponse *, UIImage *))success | |
failure:(void (^)(NSURLRequest *, NSHTTPURLResponse *, NSError *))failure | |
{ | |
[super setImageWithURLRequest:urlRequest placeholderImage:placeholderImage success:success failure:failure]; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment