Refactoring image request API to remove unnecessary configuration, and focus the design goals of those classes

This commit is contained in:
Mattt Thompson 2011-09-16 22:40:52 -05:00
parent 686854b8da
commit 50014afa22
6 changed files with 74 additions and 87 deletions

View file

@ -28,12 +28,10 @@
+ (id)sharedImageCache;
- (UIImage *)cachedImageForRequest:(NSURLRequest *)urlRequest
imageSize:(CGSize)imageSize
options:(AFImageRequestOptions)options;
cacheName:(NSString *)cacheName;
- (void)cacheImage:(UIImage *)image
forRequest:(NSURLRequest *)urlRequest
imageSize:(CGSize)imageSize
options:(AFImageRequestOptions)options;
cacheName:(NSString *)cacheName;
@end

View file

@ -22,8 +22,8 @@
#import "AFImageCache.h"
static inline NSString * AFImageCacheKey(NSURLRequest *urlRequest, CGSize imageSize, AFImageRequestOptions options) {
return [[[urlRequest URL] absoluteString] stringByAppendingFormat:@"#%fx%f:%d", imageSize.width, imageSize.height, options];
static inline NSString * AFImageCacheKey(NSURLRequest *urlRequest, NSString *cacheName) {
return [[[urlRequest URL] absoluteString] stringByAppendingFormat:@"#%@", cacheName];
}
@implementation AFImageCache
@ -40,22 +40,20 @@ static inline NSString * AFImageCacheKey(NSURLRequest *urlRequest, CGSize imageS
}
- (UIImage *)cachedImageForRequest:(NSURLRequest *)urlRequest
imageSize:(CGSize)imageSize
options:(AFImageRequestOptions)options
cacheName:(NSString *)cacheName
{
return [self objectForKey:AFImageCacheKey(urlRequest, imageSize, options)];
return [self objectForKey:AFImageCacheKey(urlRequest, cacheName)];
}
- (void)cacheImage:(UIImage *)image
forRequest:(NSURLRequest *)urlRequest
imageSize:(CGSize)imageSize
options:(AFImageRequestOptions)options
cacheName:(NSString *)cacheName
{
if (!image) {
return;
}
[self setObject:image forKey:AFImageCacheKey(urlRequest, imageSize, options)];
[self setObject:image forKey:AFImageCacheKey(urlRequest, cacheName)];
}
@end

View file

@ -24,19 +24,15 @@
#import <UIKit/UIKit.h>
#import "AFHTTPRequestOperation.h"
typedef enum {
AFImageRequestDefaultOptions = 0,
AFImageRequestRoundCorners = 1 << 1,
} AFImageRequestOptions;
@interface AFImageRequestOperation : AFHTTPRequestOperation
+ (id)operationWithRequest:(NSURLRequest *)urlRequest
success:(void (^)(UIImage *image))success;
+ (id)operationWithRequest:(NSURLRequest *)urlRequest
imageSize:(CGSize)imageSize
options:(AFImageRequestOptions)options
success:(void (^)(UIImage *image))success;
imageProcessingBlock:(UIImage *(^)(UIImage *))imageProcessingBlock
cacheName:(NSString *)cacheNameOrNil
success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image))success
failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error))failure;
@end

View file

@ -25,14 +25,6 @@
#import "UIImage+AFNetworking.h"
static CGFloat const kAFImageRequestJPEGQuality = 0.8;
static NSUInteger const kAFImageRequestMaximumResponseSize = 8 * 1024 * 1024;
static inline CGSize kAFImageRequestRoundedCornerRadii(CGSize imageSize) {
CGFloat dimension = fmaxf(imageSize.width, imageSize.height) * 0.1;
return CGSizeMake(dimension, dimension);
}
static dispatch_queue_t af_image_request_operation_processing_queue;
static dispatch_queue_t image_request_operation_processing_queue() {
if (af_image_request_operation_processing_queue == NULL) {
@ -47,42 +39,48 @@ static dispatch_queue_t image_request_operation_processing_queue() {
+ (id)operationWithRequest:(NSURLRequest *)urlRequest
success:(void (^)(UIImage *image))success
{
return [self operationWithRequest:urlRequest imageSize:CGSizeZero options:AFImageRequestDefaultOptions success:success];
return [self operationWithRequest:urlRequest imageProcessingBlock:nil cacheName:nil success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
if (success) {
success(image);
}
} failure:nil];
}
+ (id)operationWithRequest:(NSURLRequest *)urlRequest
imageSize:(CGSize)imageSize
options:(AFImageRequestOptions)options
success:(void (^)(UIImage *image))success
imageProcessingBlock:(UIImage *(^)(UIImage *))imageProcessingBlock
cacheName:(NSString *)cacheNameOrNil
success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image))success
failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error))failure
{
AFImageRequestOperation *operation = [self operationWithRequest:urlRequest completion:^(NSURLRequest *request, NSHTTPURLResponse *response, NSData *data, NSError *error) {
dispatch_async(image_request_operation_processing_queue(), ^(void) {
UIImage *image = nil;
if ([[UIScreen mainScreen] scale] == 2.0) {
CGImageRef imageRef = [[UIImage imageWithData:data] CGImage];
image = [UIImage imageWithCGImage:imageRef scale:2.0 orientation:UIImageOrientationUp];
} else {
image = [UIImage imageWithData:data];
}
if (!(CGSizeEqualToSize(image.size, imageSize) || CGSizeEqualToSize(imageSize, CGSizeZero))) {
image = [UIImage imageByScalingAndCroppingImage:image size:imageSize];
}
if ((options & AFImageRequestRoundCorners)) {
image = [UIImage imageByRoundingCornersOfImage:image corners:UIRectCornerAllCorners cornerRadii:kAFImageRequestRoundedCornerRadii(image.size)];
}
dispatch_sync(dispatch_get_main_queue(), ^(void) {
if (success) {
success(image);
if (error) {
if (failure) {
failure(request, response, error);
}
});
[[AFImageCache sharedImageCache] cacheImage:image forRequest:request imageSize:imageSize options:options];
} else {
UIImage *image = nil;
if ([[UIScreen mainScreen] scale] == 2.0) {
CGImageRef imageRef = [[UIImage imageWithData:data] CGImage];
image = [UIImage imageWithCGImage:imageRef scale:2.0 orientation:UIImageOrientationUp];
} else {
image = [UIImage imageWithData:data];
}
if (imageProcessingBlock) {
image = imageProcessingBlock(image);
}
dispatch_sync(dispatch_get_main_queue(), ^(void) {
if (success) {
success(request, response, image);
}
});
[[AFImageCache sharedImageCache] cacheImage:image forRequest:request cacheName:cacheNameOrNil];
}
});
}];
operation.runLoopModes = [NSSet setWithObject:NSRunLoopCommonModes];
return operation;
}

View file

@ -32,14 +32,7 @@
- (void)setImageWithURL:(NSURL *)url
placeholderImage:(UIImage *)placeholderImage
imageSize:(CGSize)imageSize
options:(AFImageRequestOptions)options;
- (void)setImageWithURL:(NSURL *)url
placeholderImage:(UIImage *)placeholderImage
imageSize:(CGSize)imageSize
options:(AFImageRequestOptions)options
block:(void (^)(UIImage *image, BOOL cacheUsed))block;
success:(void (^)(UIImage *image, BOOL cacheUsed))block;
- (void)cancelImageRequestOperation;

View file

@ -24,6 +24,7 @@
#import <objc/runtime.h>
#import "UIImageView+AFNetworking.h"
#import "UIImage+AFNetworking.h"
#import "AFImageCache.h"
@ -54,37 +55,27 @@ static NSString * const kUIImageViewImageRequestObjectKey = @"_af_imageRequestOp
if (!_imageRequestOperationQueue) {
_imageRequestOperationQueue = [[NSOperationQueue alloc] init];
[_imageRequestOperationQueue setMaxConcurrentOperationCount:6];
[_imageRequestOperationQueue setMaxConcurrentOperationCount:8];
}
return _imageRequestOperationQueue;
}
#pragma mark -
- (void)setImageWithURL:(NSURL *)url {
[self setImageWithURL:url placeholderImage:nil];
}
- (void)setImageWithURL:(NSURL *)url
placeholderImage:(UIImage *)placeholderImage
placeholderImage:(UIImage *)placeholderImage
{
[self setImageWithURL:url placeholderImage:placeholderImage imageSize:self.frame.size options:AFImageRequestDefaultOptions];
[self setImageWithURL:url placeholderImage:placeholderImage success:nil];
}
- (void)setImageWithURL:(NSURL *)url
placeholderImage:(UIImage *)placeholderImage
imageSize:(CGSize)imageSize
options:(AFImageRequestOptions)options
{
[self setImageWithURL:url placeholderImage:placeholderImage imageSize:imageSize options:options block:nil];
}
- (void)setImageWithURL:(NSURL *)url
placeholderImage:(UIImage *)placeholderImage
imageSize:(CGSize)imageSize
options:(AFImageRequestOptions)options
block:(void (^)(UIImage *image, BOOL cacheUsed))block
success:(void (^)(UIImage *image, BOOL cacheUsed))success
{
if (!url || [url isEqual:self.imageRequestOperation.request.URL]) {
return;
@ -96,30 +87,43 @@ static NSString * const kUIImageViewImageRequestObjectKey = @"_af_imageRequestOp
[request setHTTPShouldHandleCookies:NO];
[request setHTTPShouldUsePipelining:YES];
UIImage *cachedImage = [[AFImageCache sharedImageCache] cachedImageForRequest:request imageSize:imageSize options:options];
NSString *cacheName = @"UIImageView";
if (placeholderImage) {
cacheName = [cacheName stringByAppendingFormat:@"(%@)", NSStringFromCGSize(placeholderImage.size)];
}
UIImage *cachedImage = [[AFImageCache sharedImageCache] cachedImageForRequest:request cacheName:cacheName];
if (cachedImage) {
self.image = cachedImage;
if (block) {
block(cachedImage, YES);
if (success) {
success(cachedImage, YES);
}
} else {
self.image = placeholderImage;
self.imageRequestOperation = [AFImageRequestOperation operationWithRequest:request imageSize:imageSize options:options success:^(UIImage *image) {
self.imageRequestOperation = [AFImageRequestOperation operationWithRequest:request imageProcessingBlock:^UIImage *(UIImage *image) {
if (placeholderImage) {
image = [UIImage imageByScalingAndCroppingImage:image size:placeholderImage.size];
}
return image;
} cacheName:cacheName success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
if (self.imageRequestOperation && ![self.imageRequestOperation isCancelled]) {
if (block) {
block(image, NO);
if (success) {
success(image, NO);
}
if ([[request URL] isEqual:[[self.imageRequestOperation request] URL]]) {
self.image = image;
} else {
self.image = placeholderImage;
}
}
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
self.imageRequestOperation = nil;
}];
[[[self class] sharedImageRequestOperationQueue] addOperation:self.imageRequestOperation];
}
}