From 9c4fcfa844181d94a6f1bb916038e67f90f8be2a Mon Sep 17 00:00:00 2001 From: Martin Oppetit Date: Mon, 1 Feb 2016 15:19:59 +0000 Subject: [PATCH] Added API to save image NSData to disk cache - exposing new `- (void)storeImageDataToDisk:(NSData *)imageData forKey:(NSString *)key` function on SDImageCache - added unit tests for this new API - added file extension to kImageTestKey to ensure cache path is valid for creating NSData --- SDWebImage/SDImageCache.h | 8 ++++ SDWebImage/SDImageCache.m | 39 +++++++++++-------- .../project.pbxproj | 16 ++++++++ Tests/Tests/SDImageCacheTests.m | 32 +++++++++++++-- 4 files changed, 74 insertions(+), 21 deletions(-) diff --git a/SDWebImage/SDImageCache.h b/SDWebImage/SDImageCache.h index 95777267..6704541e 100644 --- a/SDWebImage/SDImageCache.h +++ b/SDWebImage/SDImageCache.h @@ -134,6 +134,14 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot */ - (void)storeImage:(UIImage *)image recalculateFromImage:(BOOL)recalculate imageData:(NSData *)imageData forKey:(NSString *)key toDisk:(BOOL)toDisk; +/** + * Store image NSData into disk cache at the given key. + * + * @param imageData The image data to store + * @param key The unique image cache key, usually it's image absolute URL + */ +- (void)storeImageDataToDisk:(NSData *)imageData forKey:(NSString *)key; + /** * Query the disk cache asynchronously. * diff --git a/SDWebImage/SDImageCache.m b/SDWebImage/SDImageCache.m index aa0ff6c9..fdda5cf3 100644 --- a/SDWebImage/SDImageCache.m +++ b/SDWebImage/SDImageCache.m @@ -241,23 +241,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { #endif } - if (data) { - if (![_fileManager fileExistsAtPath:_diskCachePath]) { - [_fileManager createDirectoryAtPath:_diskCachePath withIntermediateDirectories:YES attributes:nil error:NULL]; - } - - // get cache Path for image key - NSString *cachePathForKey = [self defaultCachePathForKey:key]; - // transform to NSUrl - NSURL *fileURL = [NSURL fileURLWithPath:cachePathForKey]; - - [_fileManager createFileAtPath:cachePathForKey contents:data attributes:nil]; - - // disable iCloud backup - if (self.shouldDisableiCloud) { - [fileURL setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:nil]; - } - } + [self storeImageDataToDisk:data forKey:key]; }); } } @@ -270,6 +254,27 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { [self storeImage:image recalculateFromImage:YES imageData:nil forKey:key toDisk:toDisk]; } +- (void)storeImageDataToDisk:(NSData *)imageData forKey:(NSString *)key { + + if (!imageData) return; + + if (![_fileManager fileExistsAtPath:_diskCachePath]) { + [_fileManager createDirectoryAtPath:_diskCachePath withIntermediateDirectories:YES attributes:nil error:NULL]; + } + + // get cache Path for image key + NSString *cachePathForKey = [self defaultCachePathForKey:key]; + // transform to NSUrl + NSURL *fileURL = [NSURL fileURLWithPath:cachePathForKey]; + + [_fileManager createFileAtPath:cachePathForKey contents:imageData attributes:nil]; + + // disable iCloud backup + if (self.shouldDisableiCloud) { + [fileURL setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:nil]; + } +} + - (BOOL)diskImageExistsWithKey:(NSString *)key { BOOL exists = NO; diff --git a/Tests/SDWebImage Tests.xcodeproj/project.pbxproj b/Tests/SDWebImage Tests.xcodeproj/project.pbxproj index 34a8e11b..e1328a2b 100644 --- a/Tests/SDWebImage Tests.xcodeproj/project.pbxproj +++ b/Tests/SDWebImage Tests.xcodeproj/project.pbxproj @@ -122,6 +122,7 @@ DA248D50195472AA00390AB0 /* Frameworks */, DA248D51195472AA00390AB0 /* Resources */, D6347736BDF64FC5A4D078A4 /* Copy Pods Resources */, + 4B51E412BA3594400947AC71 /* Embed Pods Frameworks */, ); buildRules = ( ); @@ -170,6 +171,21 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 4B51E412BA3594400947AC71 /* Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ios/Pods-ios-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; D6347736BDF64FC5A4D078A4 /* Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; diff --git a/Tests/Tests/SDImageCacheTests.m b/Tests/Tests/SDImageCacheTests.m index 8edbdbd6..d1c64489 100644 --- a/Tests/Tests/SDImageCacheTests.m +++ b/Tests/Tests/SDImageCacheTests.m @@ -14,7 +14,7 @@ #import "SDImageCache.h" -NSString *kImageTestKey = @"TestImageKey"; +NSString *kImageTestKey = @"TestImageKey.jpg"; @interface SDImageCacheTests : XCTestCase @property (strong, nonatomic) SDImageCache *sharedImageCache; @@ -185,6 +185,25 @@ NSString *kImageTestKey = @"TestImageKey"; expect(path).notTo.beNil; } +// TODO -- Testing image data insertion + +- (void)testInsertionOfImageData { + + NSData *imageData = [NSData dataWithContentsOfFile:[self testImagePath]]; + [self.sharedImageCache storeImageDataToDisk:imageData forKey:kImageTestKey]; + + UIImage *storedImageFromMemory = [self.sharedImageCache imageFromMemoryCacheForKey:kImageTestKey]; + expect(storedImageFromMemory).to.equal(nil); + + NSString *cachePath = [self.sharedImageCache defaultCachePathForKey:kImageTestKey]; + NSData *storedImageData = [NSData dataWithContentsOfFile:cachePath]; + expect([storedImageData isEqualToData:imageData]).will.beTruthy; + + [self.sharedImageCache diskImageExistsWithKey:kImageTestKey completion:^(BOOL isInCache) { + expect(isInCache).to.equal(YES); + }]; +} + #pragma mark Helper methods - (void)clearAllCaches{ @@ -193,9 +212,14 @@ NSString *kImageTestKey = @"TestImageKey"; } - (UIImage *)imageForTesting{ - NSBundle *testBundle=[NSBundle bundleForClass:[self class]]; - NSString *testBundlePath=[testBundle pathForResource:@"TestImage" ofType:@"jpg"]; - return [UIImage imageWithContentsOfFile:testBundlePath]; + + return [UIImage imageWithContentsOfFile:[self testImagePath]]; +} + +- (NSString *)testImagePath { + + NSBundle *testBundle = [NSBundle bundleForClass:[self class]]; + return [testBundle pathForResource:@"TestImage" ofType:@"jpg"]; } @end \ No newline at end of file