Handle storeImageDataToDisk error.
This commit is contained in:
parent
041842bf08
commit
a581ab1991
|
@ -31,6 +31,7 @@ typedef void(^SDWebImageCheckCacheCompletionBlock)(BOOL isInCache);
|
|||
|
||||
typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger totalSize);
|
||||
|
||||
typedef void(^SDWebImageCompletionWithPossibleErrorBlock)(NSError * _Nullable error);
|
||||
|
||||
/**
|
||||
* SDImageCache maintains a memory cache and an optional disk cache. Disk cache write operations are performed
|
||||
|
@ -103,7 +104,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot
|
|||
*/
|
||||
- (void)storeImage:(nullable UIImage *)image
|
||||
forKey:(nullable NSString *)key
|
||||
completion:(nullable SDWebImageNoParamsBlock)completionBlock;
|
||||
completion:(nullable SDWebImageCompletionWithPossibleErrorBlock)completionBlock;
|
||||
|
||||
/**
|
||||
* Asynchronously store an image into memory and disk cache at the given key.
|
||||
|
@ -116,7 +117,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot
|
|||
- (void)storeImage:(nullable UIImage *)image
|
||||
forKey:(nullable NSString *)key
|
||||
toDisk:(BOOL)toDisk
|
||||
completion:(nullable SDWebImageNoParamsBlock)completionBlock;
|
||||
completion:(nullable SDWebImageCompletionWithPossibleErrorBlock)completionBlock;
|
||||
|
||||
/**
|
||||
* Asynchronously store an image into memory and disk cache at the given key.
|
||||
|
@ -133,7 +134,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot
|
|||
imageData:(nullable NSData *)imageData
|
||||
forKey:(nullable NSString *)key
|
||||
toDisk:(BOOL)toDisk
|
||||
completion:(nullable SDWebImageNoParamsBlock)completionBlock;
|
||||
completion:(nullable SDWebImageCompletionWithPossibleErrorBlock)completionBlock;
|
||||
|
||||
/**
|
||||
* Synchronously store image NSData into disk cache at the given key.
|
||||
|
@ -143,7 +144,36 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot
|
|||
* @param imageData The image data to store
|
||||
* @param key The unique image cache key, usually it's image absolute URL
|
||||
*/
|
||||
- (void)storeImageDataToDisk:(nullable NSData *)imageData forKey:(nullable NSString *)key;
|
||||
- (void)storeImageDataToDisk:(nullable NSData *)imageData
|
||||
forKey:(nullable NSString *)key;
|
||||
|
||||
/**
|
||||
* Synchronously store image NSData into disk cache at the given key.
|
||||
*
|
||||
* @warning This method is synchronous, make sure to call it from the ioQueue
|
||||
*
|
||||
* @param imageData The image data to store
|
||||
* @param key The unique image cache key, usually it's image absolute URL
|
||||
* @param errorPtr NSError pointer. If error occurs then (*errorPtr) != nil.
|
||||
*/
|
||||
- (void)storeImageDataToDisk:(nullable NSData *)imageData
|
||||
forKey:(nullable NSString *)key
|
||||
error:(NSError * _Nullable * _Nullable)errorPtr;
|
||||
|
||||
/**
|
||||
* Synchronously store image NSData into disk cache at the given key.
|
||||
*
|
||||
* @warning This method is synchronous, make sure to call it from the ioQueue
|
||||
*
|
||||
* @param imageData The image data to store
|
||||
* @param key The unique image cache key, usually it's image absolute URL
|
||||
* @param fileManager The file manager for storing image. If nil, then will be used local object.
|
||||
* @param errorPtr NSError pointer. If error occurs then (*errorPtr) != nil.
|
||||
*/
|
||||
- (void)storeImageDataToDisk:(nullable NSData *)imageData
|
||||
forKey:(nullable NSString *)key
|
||||
fileManager:(nullable NSFileManager *)fileManager
|
||||
error:(NSError * _Nullable * _Nullable)errorPtr;
|
||||
|
||||
#pragma mark - Query and Retrieve Ops
|
||||
|
||||
|
|
|
@ -187,14 +187,14 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
|
||||
- (void)storeImage:(nullable UIImage *)image
|
||||
forKey:(nullable NSString *)key
|
||||
completion:(nullable SDWebImageNoParamsBlock)completionBlock {
|
||||
completion:(nullable SDWebImageCompletionWithPossibleErrorBlock)completionBlock {
|
||||
[self storeImage:image imageData:nil forKey:key toDisk:YES completion:completionBlock];
|
||||
}
|
||||
|
||||
- (void)storeImage:(nullable UIImage *)image
|
||||
forKey:(nullable NSString *)key
|
||||
toDisk:(BOOL)toDisk
|
||||
completion:(nullable SDWebImageNoParamsBlock)completionBlock {
|
||||
completion:(nullable SDWebImageCompletionWithPossibleErrorBlock)completionBlock {
|
||||
[self storeImage:image imageData:nil forKey:key toDisk:toDisk completion:completionBlock];
|
||||
}
|
||||
|
||||
|
@ -202,10 +202,10 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
imageData:(nullable NSData *)imageData
|
||||
forKey:(nullable NSString *)key
|
||||
toDisk:(BOOL)toDisk
|
||||
completion:(nullable SDWebImageNoParamsBlock)completionBlock {
|
||||
completion:(nullable SDWebImageCompletionWithPossibleErrorBlock)completionBlock {
|
||||
if (!image || !key) {
|
||||
if (completionBlock) {
|
||||
completionBlock();
|
||||
completionBlock(nil);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -217,37 +217,52 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
|
||||
if (toDisk) {
|
||||
dispatch_async(self.ioQueue, ^{
|
||||
NSError * writeError = nil;
|
||||
@autoreleasepool {
|
||||
NSData *data = imageData;
|
||||
if (!data && image) {
|
||||
SDImageFormat imageFormatFromData = [NSData sd_imageFormatForImageData:data];
|
||||
data = [image sd_imageDataAsFormat:imageFormatFromData];
|
||||
}
|
||||
[self storeImageDataToDisk:data forKey:key];
|
||||
[self storeImageDataToDisk:data forKey:key error:&writeError];
|
||||
}
|
||||
|
||||
if (completionBlock) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
completionBlock();
|
||||
completionBlock(writeError);
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (completionBlock) {
|
||||
completionBlock();
|
||||
completionBlock(nil);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)storeImageDataToDisk:(nullable NSData *)imageData forKey:(nullable NSString *)key {
|
||||
- (void)storeImageDataToDisk:(nullable NSData *)imageData
|
||||
forKey:(nullable NSString *)key {
|
||||
[self storeImageDataToDisk:imageData forKey:key fileManager:_fileManager error:nil];
|
||||
}
|
||||
|
||||
- (void)storeImageDataToDisk:(nullable NSData *)imageData
|
||||
forKey:(nullable NSString *)key
|
||||
error:(NSError * _Nullable * _Nullable)errorPtr {
|
||||
[self storeImageDataToDisk:imageData forKey:key fileManager:_fileManager error:errorPtr];
|
||||
}
|
||||
|
||||
- (void)storeImageDataToDisk:(nullable NSData *)imageData
|
||||
forKey:(nullable NSString *)key
|
||||
fileManager:(nullable NSFileManager *)fileManager
|
||||
error:(NSError * _Nullable * _Nullable)errorPtr {
|
||||
if (!imageData || !key) {
|
||||
return;
|
||||
}
|
||||
|
||||
[self checkIfQueueIsIOQueue];
|
||||
|
||||
if (![_fileManager fileExistsAtPath:_diskCachePath]) {
|
||||
[_fileManager createDirectoryAtPath:_diskCachePath withIntermediateDirectories:YES attributes:nil error:NULL];
|
||||
if (![fileManager fileExistsAtPath:_diskCachePath]) {
|
||||
[fileManager createDirectoryAtPath:_diskCachePath withIntermediateDirectories:YES attributes:nil error:NULL];
|
||||
}
|
||||
|
||||
// get cache Path for image key
|
||||
|
@ -255,7 +270,9 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
// transform to NSUrl
|
||||
NSURL *fileURL = [NSURL fileURLWithPath:cachePathForKey];
|
||||
|
||||
[_fileManager createFileAtPath:cachePathForKey contents:imageData attributes:nil];
|
||||
if (![fileManager createFileAtPath:cachePathForKey contents:imageData attributes:nil] && errorPtr) {
|
||||
*errorPtr = [[NSError alloc] initWithDomain:NSPOSIXErrorDomain code:errno userInfo:nil];
|
||||
}
|
||||
|
||||
// disable iCloud backup
|
||||
if (self.config.shouldDisableiCloud) {
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
/* Begin PBXBuildFile section */
|
||||
1E3C51E919B46E370092B5E6 /* SDWebImageDownloaderTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E3C51E819B46E370092B5E6 /* SDWebImageDownloaderTests.m */; };
|
||||
37D122881EC48B5E00D98CEB /* MockFileManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 37D122871EC48B5E00D98CEB /* MockFileManager.m */; };
|
||||
433BBBB51D7EF5C00086B6E9 /* SDWebImageDecoderTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 433BBBB41D7EF5C00086B6E9 /* SDWebImageDecoderTests.m */; };
|
||||
433BBBB71D7EF8200086B6E9 /* TestImage.gif in Resources */ = {isa = PBXBuildFile; fileRef = 433BBBB61D7EF8200086B6E9 /* TestImage.gif */; };
|
||||
433BBBB91D7EF8260086B6E9 /* TestImage.png in Resources */ = {isa = PBXBuildFile; fileRef = 433BBBB81D7EF8260086B6E9 /* TestImage.png */; };
|
||||
|
@ -29,6 +30,8 @@
|
|||
/* Begin PBXFileReference section */
|
||||
1DAAA77E3CA7387F702040D9 /* Pods_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
1E3C51E819B46E370092B5E6 /* SDWebImageDownloaderTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDWebImageDownloaderTests.m; sourceTree = "<group>"; };
|
||||
37D122861EC48B5E00D98CEB /* MockFileManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MockFileManager.h; sourceTree = "<group>"; };
|
||||
37D122871EC48B5E00D98CEB /* MockFileManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MockFileManager.m; sourceTree = "<group>"; };
|
||||
433BBBB41D7EF5C00086B6E9 /* SDWebImageDecoderTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDWebImageDecoderTests.m; sourceTree = "<group>"; };
|
||||
433BBBB61D7EF8200086B6E9 /* TestImage.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = TestImage.gif; sourceTree = "<group>"; };
|
||||
433BBBB81D7EF8260086B6E9 /* TestImage.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = TestImage.png; sourceTree = "<group>"; };
|
||||
|
@ -120,6 +123,8 @@
|
|||
433BBBB41D7EF5C00086B6E9 /* SDWebImageDecoderTests.m */,
|
||||
4369C1D01D97F80F007E863A /* SDWebImagePrefetcherTests.m */,
|
||||
4369C2731D9804B1007E863A /* SDCategoriesTests.m */,
|
||||
37D122861EC48B5E00D98CEB /* MockFileManager.h */,
|
||||
37D122871EC48B5E00D98CEB /* MockFileManager.m */,
|
||||
);
|
||||
path = Tests;
|
||||
sourceTree = "<group>";
|
||||
|
@ -252,6 +257,7 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
1E3C51E919B46E370092B5E6 /* SDWebImageDownloaderTests.m in Sources */,
|
||||
37D122881EC48B5E00D98CEB /* MockFileManager.m in Sources */,
|
||||
4369C2741D9804B1007E863A /* SDCategoriesTests.m in Sources */,
|
||||
4369C1D11D97F80F007E863A /* SDWebImagePrefetcherTests.m in Sources */,
|
||||
DA248D69195475D800390AB0 /* SDImageCacheTests.m in Sources */,
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
//
|
||||
// MockFileManager.h
|
||||
// SDWebImage Tests
|
||||
//
|
||||
// Created by Anton Popovichenko on 11.05.17.
|
||||
//
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface MockFileManager : NSFileManager
|
||||
|
||||
- (id)initWithSendError:(int)errorNumber;
|
||||
|
||||
@end
|
|
@ -0,0 +1,29 @@
|
|||
//
|
||||
// MockFileManager.m
|
||||
// SDWebImage Tests
|
||||
//
|
||||
// Created by Anton Popovichenko on 11.05.17.
|
||||
//
|
||||
//
|
||||
|
||||
#import "MockFileManager.h"
|
||||
|
||||
@implementation MockFileManager {
|
||||
int _errorNumber;
|
||||
}
|
||||
|
||||
- (id)initWithSendError:(int)errorNumber {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_errorNumber = errorNumber;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)createFileAtPath:(NSString *)path contents:(NSData *)data attributes:(NSDictionary<NSString *,id> *)attr {
|
||||
errno = _errorNumber;
|
||||
return !_errorNumber;
|
||||
}
|
||||
|
||||
@end
|
|
@ -13,6 +13,7 @@
|
|||
#import <Expecta/Expecta.h>
|
||||
|
||||
#import <SDWebImage/SDImageCache.h>
|
||||
#import "MockFileManager.h"
|
||||
|
||||
NSString *kImageTestKey = @"TestImageKey.jpg";
|
||||
|
||||
|
@ -215,6 +216,26 @@ NSString *kImageTestKey = @"TestImageKey.jpg";
|
|||
}];
|
||||
}
|
||||
|
||||
- (void)test41StoreImageDataToDistWithError {
|
||||
NSData *imageData = [NSData dataWithContentsOfFile:[self testImagePath]];
|
||||
NSError * error = nil;
|
||||
[self.sharedImageCache storeImageDataToDisk:imageData
|
||||
forKey:kImageTestKey
|
||||
fileManager:[[MockFileManager alloc] initWithSendError:EACCES]
|
||||
error:&error];
|
||||
XCTAssertEqual(error.code, EACCES);
|
||||
}
|
||||
|
||||
- (void)test42StoreImageDataToDiskWithoutError {
|
||||
NSData *imageData = [NSData dataWithContentsOfFile:[self testImagePath]];
|
||||
NSError * error = nil;
|
||||
[self.sharedImageCache storeImageDataToDisk:imageData
|
||||
forKey:kImageTestKey
|
||||
fileManager:[[MockFileManager alloc] initWithSendError:0]
|
||||
error:&error];
|
||||
XCTAssertNil(error);
|
||||
}
|
||||
|
||||
#pragma mark Helper methods
|
||||
|
||||
- (void)clearAllCaches{
|
||||
|
|
Loading…
Reference in New Issue