Skip to content

Updated YYImage//YYCache bridge to match the latest 5.19.2 behavior #16

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cartfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
github "SDWebImage/SDWebImage" ~> 5.15
github "SDWebImage/SDWebImage" ~> 5.18
github "ibireme/YYCache" ~> 1.0
github "ibireme/YYImage" ~> 1.0
2 changes: 1 addition & 1 deletion SDWebImageYYPlugin.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ TODO: Add long description of the pod here.
s.source_files = 'SDWebImageYYPlugin/Module/SDWebImageYYPlugin.h'
s.module_map = 'SDWebImageYYPlugin/Module/SDWebImageYYPlugin.modulemap'

s.dependency 'SDWebImage/Core', '~> 5.15'
s.dependency 'SDWebImage/Core', '~> 5.18'

s.subspec 'YYCache' do |ss|
ss.dependency 'YYCache'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@
/// YYCache category to support `SDImageCache` protocol. This allow user who prefer YYCache to be used as SDWebImage's custom image cache
@interface YYCache (SDAdditions) <SDImageCache>

/// Cache Config object - storing all kind of settings.
@property (nonatomic, strong, readonly, nonnull) SDImageCacheConfig *config;

@end
114 changes: 84 additions & 30 deletions SDWebImageYYPlugin/Classes/YYCache/YYCacheBridge/YYCache+SDAdditions.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,76 @@
#import "YYCache+SDAdditions.h"
#import "YYMemoryCache+SDAdditions.h"
#import "YYDiskCache+SDAdditions.h"
#import "SDImageTransformer.h" // TODO, remove this
#import <objc/runtime.h>

static void SDYYPluginUnarchiveObject(NSData *data, UIImage *image) {
if (!data || !image) {
// TODO, remove this
static BOOL SDIsThumbnailKey(NSString *key) {
if ([key rangeOfString:@"-Thumbnail("].location != NSNotFound) {
return YES;
}
return NO;
}

@implementation YYCache (SDAdditions)

- (SDImageCacheConfig *)config {
// Provided the default one
SDImageCacheConfig *config = objc_getAssociatedObject(self, @selector(config));
if (!config) {
config = SDImageCacheConfig.defaultCacheConfig;
config.shouldDisableiCloud
[self setConfig:config];
}
return config;
}

- (void)setConfig:(SDImageCacheConfig *)config {
objc_setAssociatedObject(self, @selector(config), config, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (void)_syncDiskToMemoryWithImage:(UIImage *)diskImage forKey:(NSString *)key {
// earily check
if (!self.config.shouldCacheImagesInMemory) {
return;
}
if (!diskImage) {
return;
}
// The disk -> memory sync logic, which should only store thumbnail image with thumbnail key
// However, caller (like SDWebImageManager) will query full key, with thumbnail size, and get thubmnail image
// We should add a check here, currently it's a hack
if (diskImage.sd_isThumbnail && !SDIsThumbnailKey(key)) {
SDImageCoderOptions *options = diskImage.sd_decodeOptions;
CGSize thumbnailSize = CGSizeZero;
NSValue *thumbnailSizeValue = options[SDImageCoderDecodeThumbnailPixelSize];
if (thumbnailSizeValue != nil) {
#if SD_MAC
thumbnailSize = thumbnailSizeValue.sizeValue;
#else
thumbnailSize = thumbnailSizeValue.CGSizeValue;
#endif
}
BOOL preserveAspectRatio = YES;
NSNumber *preserveAspectRatioValue = options[SDImageCoderDecodePreserveAspectRatio];
if (preserveAspectRatioValue != nil) {
preserveAspectRatio = preserveAspectRatioValue.boolValue;
}
// Calculate the actual thumbnail key
NSString *thumbnailKey = SDThumbnailedKeyForKey(key, thumbnailSize, preserveAspectRatio);
// Override the sync key
key = thumbnailKey;
}
NSUInteger cost = diskImage.sd_memoryCost;
[self.memoryCache setObject:diskImage forKey:key cost:cost];
}

- (void)_unarchiveObjectWithImage:(UIImage *)image forKey:(NSString *)key {
if (!image || !key) {
return;
}
// Check extended data
NSData *extendedData = [YYDiskCache getExtendedDataFromObject:data];
NSData *extendedData = [self.diskCache extendedDataForKey:key];
if (!extendedData) {
return;
}
Expand All @@ -41,8 +104,8 @@ static void SDYYPluginUnarchiveObject(NSData *data, UIImage *image) {
image.sd_extendedObject = extendedObject;
}

static void SDYYPluginArchiveObject(NSData *data, UIImage *image) {
if (!data || !image) {
- (void)_archivedDataWithImage:(UIImage *)image forKey:(NSString *)key {
if (!image || !key) {
return;
}
// Check extended data
Expand All @@ -68,12 +131,10 @@ static void SDYYPluginArchiveObject(NSData *data, UIImage *image) {
}
}
if (extendedData) {
[YYDiskCache setExtendedData:extendedData toObject:data];
[self.diskCache setExtendedData:extendedData forKey:key];
}
}

@implementation YYCache (SDAdditions)

- (id<SDWebImageOperation>)queryImageForKey:(NSString *)key options:(SDWebImageOptions)options context:(SDWebImageContext *)context completion:(SDImageCacheQueryCompletionBlock)doneBlock {
return [self queryImageForKey:key options:options context:context cacheType:SDImageCacheTypeAll completion:doneBlock];
}
Expand Down Expand Up @@ -102,7 +163,7 @@ @implementation YYCache (SDAdditions)
if (image) {
if (options & SDWebImageDecodeFirstFrameOnly) {
// Ensure static image
if (image.sd_isAnimated) {
if (image.sd_imageFrameCount > 1) {
#if SD_MAC
image = [[NSImage alloc] initWithCGImage:image.CGImage scale:image.scale orientation:kCGImagePropertyOrientationUp];
#else
Expand Down Expand Up @@ -156,30 +217,23 @@ @implementation YYCache (SDAdditions)
// the image is from in-memory cache, but need image data
diskImage = image;
} else if (diskData) {
BOOL shouldCacheToMomery = YES;
BOOL shouldCacheToMemory = YES;
if (context[SDWebImageContextStoreCacheType]) {
SDImageCacheType cacheType = [context[SDWebImageContextStoreCacheType] integerValue];
shouldCacheToMomery = (cacheType == SDImageCacheTypeAll || cacheType == SDImageCacheTypeMemory);
shouldCacheToMemory = (cacheType == SDImageCacheTypeAll || cacheType == SDImageCacheTypeMemory);
}
CGSize thumbnailSize = CGSizeZero;
NSValue *thumbnailSizeValue = context[SDWebImageContextImageThumbnailPixelSize];
if (thumbnailSizeValue != nil) {
#if SD_MAC
thumbnailSize = thumbnailSizeValue.sizeValue;
#else
thumbnailSize = thumbnailSizeValue.CGSizeValue;
#endif
}
if (thumbnailSize.width > 0 && thumbnailSize.height > 0) {
// Query full size cache key which generate a thumbnail, should not write back to full size memory cache
shouldCacheToMomery = NO;
// Special case: If user query image in list for the same URL, to avoid decode and write **same** image object into disk cache multiple times, we query and check memory cache here again.
if (shouldCacheToMemory && self.config.shouldCacheImagesInMemory) {
diskImage = [self.memoryCache objectForKey:key];
}
// decode image data only if in-memory cache missed
diskImage = SDImageCacheDecodeImageData(diskData, key, options, context);
SDYYPluginUnarchiveObject(diskData, diskImage);
if (shouldCacheToMomery && diskImage) {
NSUInteger cost = diskImage.sd_memoryCost;
[self.memoryCache setObject:diskImage forKey:key cost:cost];
if (!diskImage) {
diskImage = SDImageCacheDecodeImageData(diskData, key, options, context);
[self _unarchiveObjectWithImage:diskImage forKey:key];
// check if we need sync logic
if (shouldCacheToMemory) {
[self _syncDiskToMemoryWithImage:diskImage forKey:key];
}
}
}
return diskImage;
Expand Down Expand Up @@ -264,8 +318,8 @@ - (void)storeImage:(UIImage *)image imageData:(NSData *)imageData forKey:(NSStri
}
}
NSData *data = [[SDImageCodersManager sharedManager] encodedDataWithImage:image format:format options:context[SDWebImageContextImageEncodeOptions]];
SDYYPluginArchiveObject(data, image);
[self.diskCache setObject:data forKey:key withBlock:^{
[self _archivedDataWithImage:image forKey:key];
if (completionBlock) {
[(queue ?: SDCallbackQueue.mainQueue) async:^{
completionBlock();
Expand All @@ -274,8 +328,8 @@ - (void)storeImage:(UIImage *)image imageData:(NSData *)imageData forKey:(NSStri
}];
});
} else {
SDYYPluginArchiveObject(data, image);
[self.diskCache setObject:data forKey:key withBlock:^{
[self _archivedDataWithImage:image forKey:key];
if (completionBlock) {
[(queue ?: SDCallbackQueue.mainQueue) async:^{
completionBlock();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,7 @@
/// YYDiskCache category to support `SDDiskCache` protocol. This allow user who prefer YYDiskCache to be used as SDWebImage's custom disk cache
@interface YYDiskCache (SDAdditions) <SDDiskCache>

/// Cache Config object - storing all kind of settings.
@property (nonatomic, strong, readonly, nullable) SDImageCacheConfig *config;

@end
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,29 @@

@interface YYDiskCache ()

@property (nonatomic, strong, nullable) SDImageCacheConfig *sd_config;

// Internal Headers
- (NSString *)_filenameForKey:(NSString *)key;

@end

@implementation YYDiskCache (SDAdditions)

- (SDImageCacheConfig *)sd_config {
return objc_getAssociatedObject(self, @selector(sd_config));
- (SDImageCacheConfig *)config {
return objc_getAssociatedObject(self, @selector(config));
}

- (void)setSd_config:(SDImageCacheConfig *)sd_config {
objc_setAssociatedObject(self, @selector(sd_config), sd_config, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
- (void)setConfig:(SDImageCacheConfig *)config {
objc_setAssociatedObject(self, @selector(config), config, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

#pragma mark - SDDiskCache

- (instancetype)initWithCachePath:(NSString *)cachePath config:(SDImageCacheConfig *)config {
self = [self initWithPath:cachePath inlineThreshold:0];
if (self) {
self.sd_config = config;
self.config = config;
self.ageLimit = config.maxDiskAge;
self.costLimit = config.maxDiskSize;
}
return self;
}
Expand Down Expand Up @@ -78,8 +78,8 @@ - (void)removeAllData {
}

- (void)removeExpiredData {
NSTimeInterval ageLimit = self.sd_config.maxDiskAge;
NSUInteger sizeLimit = self.sd_config.maxDiskSize;
NSTimeInterval ageLimit = self.config.maxDiskAge;
NSUInteger sizeLimit = self.config.maxDiskSize;

[self trimToAge:ageLimit];
[self trimToCost:sizeLimit];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,7 @@
/// YYMemoryCache category to support `SDMemoryCache` protocol. This allow user who prefer YYMemoryCache to be used as SDWebImage's custom memory cache
@interface YYMemoryCache (SDAdditions) <SDMemoryCache>

/// Cache Config object - storing all kind of settings.
@property (nonatomic, strong, readonly, nullable) SDImageCacheConfig *config;

@end
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,22 @@
#import "YYMemoryCache+SDAdditions.h"
#import <objc/runtime.h>

@interface YYMemoryCache ()

@property (nonatomic, strong, nullable) SDImageCacheConfig *sd_config;

@end

@implementation YYMemoryCache (SDAdditions)

- (SDImageCacheConfig *)sd_config {
return objc_getAssociatedObject(self, @selector(sd_config));
- (SDImageCacheConfig *)config {
return objc_getAssociatedObject(self, @selector(config));
}

- (void)setSd_config:(SDImageCacheConfig *)sd_config {
objc_setAssociatedObject(self, @selector(sd_config), sd_config, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
- (void)setConfig:(SDImageCacheConfig *)config {
objc_setAssociatedObject(self, @selector(config), config, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

#pragma mark - SDMemoryCache

- (instancetype)initWithConfig:(SDImageCacheConfig *)config {
self = [self init];
if (self) {
self.sd_config = config;
self.config = config;
self.countLimit = config.maxMemoryCount;
self.costLimit = config.maxMemoryCost;
}
Expand Down
Loading