Skip to content

Instantly share code, notes, and snippets.

@donholly
Created June 8, 2015 21:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save donholly/934f52eacf510943a110 to your computer and use it in GitHub Desktop.
Save donholly/934f52eacf510943a110 to your computer and use it in GitHub Desktop.
//
// EAImageCacheEntity.h
// Pods
//
// Created by Don Holly on 3/4/15.
//
//
#import <FastImageCache/FICEntity.h>
#import "EAImageCacheFormat.h"
@protocol EAImageCacheEntity <FICEntity>
@required
- (CGFloat)aspectRatioForFormatFamily:(NSString *)formatFamily;
- (NSURL *)sourceImageURLForFormatFamily:(NSString *)formatFamily;
- (EAImageCacheFormat *)imageFormatForFormatFamily:(NSString *)formatFamily;
@end
//
// EAFastDiskImageCache.h
// Pods
//
// Created by Don Holly on 3/11/15.
//
//
#import "FICImageCache.h"
#import "EAImageCacheImports.h"
@interface EAFastDiskImageCache : FICImageCache
+ (unsigned long long)currentCacheSize;
+ (void)setDirectoryPath:(NSString *)directoryPath;
- (void)addFormat:(EAImageCacheFormat *)imageFormat;
- (EAImageCacheFormat *)formatWithName:(NSString *)formatName;
- (EAImageCacheFormat *)existingFormatForEntity:(id<EAImageCacheEntity>)entity
inFormatFamily:(NSString *)formatFamily;
- (BOOL)removeImageForEntity:(id<EAImageCacheEntity>)entity
inFormatFamily:(NSString *)formatFamily;
@end
//
// EAFastDiskImageCache.m
// Pods
//
// Created by Don Holly on 3/11/15.
//
//
#import "EAFastDiskImageCache.h"
#import "FICImageTable.h"
@interface EAFastDiskImageCache ()
@property (nonatomic, strong) NSMutableDictionary *imageAspectRatioToFormat;
@end
@implementation EAFastDiskImageCache
- (id)init {
if (self = [super init]) {
}
return self;
}
+ (instancetype)sharedImageCache {
return (EAFastDiskImageCache *)[super sharedImageCache];
}
+ (unsigned long long)currentCacheSize {
return [FICImageTable currentCacheSize];
}
+ (void)setDirectoryPath:(NSString *)directoryPath {
[FICImageTable setDirectoryPath:directoryPath];
}
- (void)addFormat:(EAImageCacheFormat *)imageFormat {
[super addFormat:imageFormat];
}
- (NSArray *)formatsWithFamily:(NSString *)family {
NSArray *formats = [super formatsWithFamily:family];
NSMutableArray *eaFormats = @[].mutableCopy;
for (FICImageFormat *format in formats) {
EAImageCacheFormat *eaFormat = ((EAImageCacheFormat *)format);
[eaFormats addObject:eaFormat];
}
return [eaFormats copy];
}
- (FICImageFormat *)formatWithName:(NSString *)formatName {
return ((EAImageCacheFormat *)[super formatWithName:formatName]);
}
- (EAImageCacheFormat *)existingFormatForEntity:(id<EAImageCacheEntity>)entity
inFormatFamily:(NSString *)formatFamily {
NSString *imageAspectRatio = [NSString stringWithFormat:@"%.2f",
roundedTrucatedAspectRatio([entity aspectRatioForFormatFamily:formatFamily])];
// Check our cache first.
EAImageCacheFormat *format = [self imageAspectRatioToFormat][imageAspectRatio][formatFamily];
if (format) {
return format;
}
NSArray *imageFormats = [self formatsWithFamily:formatFamily];
// Iterate the formats if it hasn't been cached yet.
for (EAImageCacheFormat *f in imageFormats) {
NSString *formatAspectRatio = f.entityAspectRatio;
if ([imageAspectRatio isEqualToString:formatAspectRatio]) {
[self imageAspectRatioToFormat][imageAspectRatio][formatFamily] = f;
return f;
}
}
return nil;
}
- (NSMutableDictionary *)imageAspectRatioToFormat {
if (!_imageAspectRatioToFormat) {
_imageAspectRatioToFormat = @{}.mutableCopy;
}
return _imageAspectRatioToFormat;
}
- (BOOL)removeImageForEntity:(id<EAImageCacheEntity>)entity
inFormatFamily:(NSString *)formatFamily {
NSUInteger count = 0;
NSArray *formats = [self formatsWithFamily:formatFamily];
for (EAImageCacheFormat *format in formats) {
[self deleteImageForEntity:entity withFormatName:format.name];
count++;
}
return count > 0;
}
@end
//
// EAImageCacheFormat.h
// Pods
//
// Created by Don Holly on 3/4/15.
//
//
#import "FICImageFormat.h"
typedef NS_OPTIONS(NSUInteger, EAImageCacheFormatDevices) {
EAImageCacheFormatDevicePhone = 1 << UIUserInterfaceIdiomPhone,
EAImageCacheFormatDevicePad = 1 << UIUserInterfaceIdiomPad,
};
typedef NS_ENUM(NSUInteger, EAImageCacheFormatStyle) {
EAImageCacheFormatStyle32BitBGRA,
EAImageCacheFormatStyle32BitBGR,
EAImageCacheFormatStyle16BitBGR,
EAImageCacheFormatStyle8BitGrayscale,
};
static inline CGFloat roundedTrucatedAspectRatio(CGFloat aspectRatio) {
CGFloat truncated = truncf(round(100 * aspectRatio)) / 100; // round to 2 decimal places;
return truncated;
};
static inline CGFloat roundedAspectRatio(CGFloat width, CGFloat height) {
return roundedTrucatedAspectRatio((width/height));
};
@interface EAImageCacheFormat : FICImageFormat
@property (nonatomic, copy, readonly) NSString *entityAspectRatio;
@property (nonatomic) BOOL cacheInMemory;
@property (nonatomic) BOOL cacheInFastDisk;
@property (nonatomic) BOOL cacheOnDisk;
+ (instancetype)formatWithFamily:(NSString *)family
entityAspectRatio:(CGFloat)entityAspectRatio
imageSize:(CGSize)imageSize
style:(EAImageCacheFormatStyle)style
cacheInMemory:(BOOL)cacheInMemory
cacheInFastDisk:(BOOL)cacheInFastDisk
cacheOnDisk:(BOOL)cacheOnDisk
maximumCount:(NSInteger)maximumCount
devices:(EAImageCacheFormatDevices)devices;
@end
//
// EAImageCacheFormat.m
// Pods
//
// Created by Don Holly on 3/4/15.
//
//
#import "EAImageCacheFormat.h"
#import "EAFastDiskImageCache.h"
@implementation EAImageCacheFormat
@synthesize entityAspectRatio = _entityAspectRatio;
- (id)initWithFamily:(NSString *)family
entityAspectRatio:(CGFloat)entityAspectRatio
imageSize:(CGSize)imageSize
style:(EAImageCacheFormatStyle)style
cacheInMemory:(BOOL)cacheInMemory
cacheInFastDisk:(BOOL)cacheInFastDisk
cacheOnDisk:(BOOL)cacheOnDisk
maximumCount:(NSInteger)maximumCount
devices:(EAImageCacheFormatDevices)devices {
if (self = [super init]) {
CGFloat roundedAspectRatio = roundedTrucatedAspectRatio(entityAspectRatio);
self.name = [EAImageCacheFormat formatNameWithFormatFamily:family
aspectRatio:roundedAspectRatio];
self.family = family;
self.entityAspectRatio = [NSString stringWithFormat:@"%.2f", roundedAspectRatio];
self.imageSize = imageSize;
self.style = [EAImageCacheFormat FICImageFormatStyleFromEAImageCacheFormatStyle:style];
self.maximumCount = maximumCount;
self.devices = [EAImageCacheFormat FICImageFormatDevicesFromEAImageCacheFormatDevices:devices];
self.protectionMode = FICImageFormatProtectionModeNone;
_cacheInMemory = cacheInMemory;
_cacheInFastDisk = cacheInFastDisk;
_cacheOnDisk = cacheOnDisk;
}
return self;
}
+ (NSString *)formatNameWithFormatFamily:(NSString *)formatFamily
aspectRatio:(CGFloat)aspectRatio {
NSString *name = [NSString stringWithFormat:@"%@_%.2f", formatFamily, aspectRatio];
return name;
}
+ (instancetype)formatWithFamily:(NSString *)family
entityAspectRatio:(CGFloat)entityAspectRatio
imageSize:(CGSize)imageSize
style:(EAImageCacheFormatStyle)style
cacheInMemory:(BOOL)cacheInMemory
cacheInFastDisk:(BOOL)cacheInFastDisk
cacheOnDisk:(BOOL)cacheOnDisk
maximumCount:(NSInteger)maximumCount
devices:(EAImageCacheFormatDevices)devices {
// See if we have an existing format that matches the same aspect ratio
NSString *name = [self formatNameWithFormatFamily:family aspectRatio:entityAspectRatio];
EAImageCacheFormat *existingFormat = [[EAFastDiskImageCache sharedImageCache] formatWithName:name];
if (existingFormat) {
return existingFormat;
}
EAImageCacheFormat *format =
[[EAImageCacheFormat alloc] initWithFamily:family
entityAspectRatio:entityAspectRatio
imageSize:imageSize
style:style
cacheInMemory:cacheInMemory
cacheInFastDisk:cacheInFastDisk
cacheOnDisk:cacheOnDisk
maximumCount:maximumCount
devices:devices];
return format;
}
+ (FICImageFormatStyle)FICImageFormatStyleFromEAImageCacheFormatStyle:(EAImageCacheFormatStyle)format {
switch (format) {
case EAImageCacheFormatStyle32BitBGRA: return FICImageFormatStyle32BitBGRA;
case EAImageCacheFormatStyle32BitBGR: return FICImageFormatStyle32BitBGR;
case EAImageCacheFormatStyle16BitBGR: return FICImageFormatStyle16BitBGR;
case EAImageCacheFormatStyle8BitGrayscale: return FICImageFormatStyle8BitGrayscale;
default: return FICImageFormatStyle16BitBGR;
}
}
+ (FICImageFormatDevices)FICImageFormatDevicesFromEAImageCacheFormatDevices:(EAImageCacheFormatDevices)devices {
FICImageFormatDevices ficDevices = 0;
if (devices & EAImageCacheFormatDevicePad) {
ficDevices |= FICImageFormatDevicePad;
}
if (devices & EAImageCacheFormatDevicePhone) {
ficDevices |= FICImageFormatDevicePhone;
}
return ficDevices;
}
#pragma mark - Working with Dictionary Representations
- (NSDictionary *)dictionaryRepresentation {
NSMutableDictionary *dictionaryRepresentation = [[super dictionaryRepresentation] mutableCopy];
dictionaryRepresentation[@"entityAspectRatio"] = self.entityAspectRatio;
dictionaryRepresentation[@"cacheInMemory"] = @(self.cacheInMemory);
dictionaryRepresentation[@"cacheInFastDisk"] = @(self.cacheInFastDisk);
dictionaryRepresentation[@"cacheOnDisk"] = @(self.cacheOnDisk);
return dictionaryRepresentation;
}
+ (EAImageCacheFormat *)formatWithDictionaryRepresentation:(NSDictionary *)dictionaryRepresentation {
CGSize imageSize = CGSizeMake([dictionaryRepresentation[@"width"] unsignedIntegerValue],
[dictionaryRepresentation[@"height"] unsignedIntegerValue]);
EAImageCacheFormat *format =
[EAImageCacheFormat formatWithFamily:dictionaryRepresentation[@"family"]
entityAspectRatio:[dictionaryRepresentation[@"entityAspectRatio"] floatValue]
imageSize:imageSize
style:[dictionaryRepresentation[@"style"] intValue]
cacheInMemory:[dictionaryRepresentation[@"cacheInMemory"] boolValue]
cacheInFastDisk:[dictionaryRepresentation[@"cacheInFastDisk"] boolValue]
cacheOnDisk:[dictionaryRepresentation[@"cacheOnDisk"] boolValue]
maximumCount:[dictionaryRepresentation[@"maximumCount"] unsignedIntegerValue]
devices:[dictionaryRepresentation[@"devices"] intValue]];
return format;
}
#pragma mark - Protocol Implementations
#pragma mark - NSObject (NSCopying)
- (id)copyWithZone:(NSZone *)zone {
EAImageCacheFormat *imageFormatCopy = [[EAImageCacheFormat alloc] init];
[imageFormatCopy setName:[self name]];
[imageFormatCopy setFamily:[self family]];
[imageFormatCopy setImageSize:[self imageSize]];
[imageFormatCopy setStyle:[self style]];
[imageFormatCopy setMaximumCount:[self maximumCount]];
[imageFormatCopy setDevices:[self devices]];
[imageFormatCopy setProtectionMode:[self protectionMode]];
[imageFormatCopy setCacheInMemory:self.cacheInMemory];
[imageFormatCopy setCacheInFastDisk:self.cacheInFastDisk];
[imageFormatCopy setCacheOnDisk:self.cacheOnDisk];
return imageFormatCopy;
}
#pragma mark - Internal Getters / Setters -
- (void)setEntityAspectRatio:(NSString *)entityAspectRatio {
_entityAspectRatio = [entityAspectRatio copy];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment