Revert "Merge pull request #1898 from walkline/master into 5.x"
This commit is contained in:
parent
db646df3f1
commit
e1d96e7812
|
@ -56,8 +56,6 @@ typedef void(^SDWebImageCheckCacheCompletionBlock)(BOOL isInCache);
|
|||
|
||||
typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger totalSize);
|
||||
|
||||
typedef void(^SDWebImageCompletionWithPossibleErrorBlock)(NSError * _Nullable error);
|
||||
|
||||
typedef NSString * _Nullable (^SDImageCacheAdditionalCachePathBlock)(NSString * _Nonnull key);
|
||||
|
||||
/**
|
||||
|
@ -140,7 +138,7 @@ typedef NSString * _Nullable (^SDImageCacheAdditionalCachePathBlock)(NSString *
|
|||
*/
|
||||
- (void)storeImage:(nullable UIImage *)image
|
||||
forKey:(nullable NSString *)key
|
||||
completion:(nullable SDWebImageCompletionWithPossibleErrorBlock)completionBlock;
|
||||
completion:(nullable SDWebImageNoParamsBlock)completionBlock;
|
||||
|
||||
/**
|
||||
* Asynchronously store an image into memory and disk cache at the given key.
|
||||
|
@ -153,7 +151,7 @@ typedef NSString * _Nullable (^SDImageCacheAdditionalCachePathBlock)(NSString *
|
|||
- (void)storeImage:(nullable UIImage *)image
|
||||
forKey:(nullable NSString *)key
|
||||
toDisk:(BOOL)toDisk
|
||||
completion:(nullable SDWebImageCompletionWithPossibleErrorBlock)completionBlock;
|
||||
completion:(nullable SDWebImageNoParamsBlock)completionBlock;
|
||||
|
||||
/**
|
||||
* Asynchronously store an image into memory and disk cache at the given key.
|
||||
|
@ -170,18 +168,16 @@ typedef NSString * _Nullable (^SDImageCacheAdditionalCachePathBlock)(NSString *
|
|||
imageData:(nullable NSData *)imageData
|
||||
forKey:(nullable NSString *)key
|
||||
toDisk:(BOOL)toDisk
|
||||
completion:(nullable SDWebImageCompletionWithPossibleErrorBlock)completionBlock;
|
||||
completion:(nullable SDWebImageNoParamsBlock)completionBlock;
|
||||
|
||||
/**
|
||||
* Synchronously 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
|
||||
* @param error NSError pointer, for possible file I/O errors, See FoundationErrors.h
|
||||
*/
|
||||
- (BOOL)storeImageDataToDisk:(nullable NSData *)imageData
|
||||
forKey:(nullable NSString *)key
|
||||
error:(NSError * _Nullable * _Nullable)error;
|
||||
- (void)storeImageDataToDisk:(nullable NSData *)imageData
|
||||
forKey:(nullable NSString *)key;
|
||||
|
||||
|
||||
#pragma mark - Query and Retrieve Ops
|
||||
|
|
|
@ -252,14 +252,14 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
|
||||
- (void)storeImage:(nullable UIImage *)image
|
||||
forKey:(nullable NSString *)key
|
||||
completion:(nullable SDWebImageCompletionWithPossibleErrorBlock)completionBlock {
|
||||
completion:(nullable SDWebImageNoParamsBlock)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 SDWebImageCompletionWithPossibleErrorBlock)completionBlock {
|
||||
completion:(nullable SDWebImageNoParamsBlock)completionBlock {
|
||||
[self storeImage:image imageData:nil forKey:key toDisk:toDisk completion:completionBlock];
|
||||
}
|
||||
|
||||
|
@ -267,10 +267,10 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
imageData:(nullable NSData *)imageData
|
||||
forKey:(nullable NSString *)key
|
||||
toDisk:(BOOL)toDisk
|
||||
completion:(nullable SDWebImageCompletionWithPossibleErrorBlock)completionBlock {
|
||||
completion:(nullable SDWebImageNoParamsBlock)completionBlock {
|
||||
if (!image || !key) {
|
||||
if (completionBlock) {
|
||||
completionBlock(nil);
|
||||
completionBlock();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -282,7 +282,6 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
|
||||
if (toDisk) {
|
||||
dispatch_async(self.ioQueue, ^{
|
||||
NSError * writeError = nil;
|
||||
@autoreleasepool {
|
||||
NSData *data = imageData;
|
||||
if (!data && image) {
|
||||
|
@ -295,50 +294,41 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
}
|
||||
data = [[SDWebImageCodersManager sharedManager] encodedDataWithImage:image format:format options:nil];
|
||||
}
|
||||
[self _storeImageDataToDisk:data forKey:key error:&writeError];
|
||||
[self _storeImageDataToDisk:data forKey:key];
|
||||
}
|
||||
|
||||
if (completionBlock) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
completionBlock(writeError);
|
||||
completionBlock();
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (completionBlock) {
|
||||
completionBlock(nil);
|
||||
completionBlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)storeImageDataToDisk:(nullable NSData *)imageData
|
||||
forKey:(nullable NSString *)key
|
||||
error:(NSError * _Nullable __autoreleasing * _Nullable)error {
|
||||
- (void)storeImageDataToDisk:(nullable NSData *)imageData
|
||||
forKey:(nullable NSString *)key {
|
||||
if (!imageData || !key) {
|
||||
return NO;
|
||||
}
|
||||
__autoreleasing NSError *fileError;
|
||||
if (!error) {
|
||||
error = &fileError;
|
||||
return;
|
||||
}
|
||||
|
||||
__block BOOL success = YES;
|
||||
void(^storeImageDataBlock)(void) = ^{
|
||||
success = [self _storeImageDataToDisk:imageData forKey:key error:error];
|
||||
};
|
||||
dispatch_sync(self.ioQueue, storeImageDataBlock);
|
||||
|
||||
return success;
|
||||
dispatch_sync(self.ioQueue, ^{
|
||||
[self _storeImageDataToDisk:imageData forKey:key];
|
||||
});
|
||||
}
|
||||
|
||||
// Make sure to call form io queue by caller
|
||||
- (BOOL)_storeImageDataToDisk:(nullable NSData *)imageData forKey:(nullable NSString *)key error:(NSError * _Nullable __autoreleasing * _Nonnull)error {
|
||||
- (void)_storeImageDataToDisk:(nullable NSData *)imageData forKey:(nullable NSString *)key {
|
||||
if (!imageData || !key) {
|
||||
return NO;
|
||||
return;
|
||||
}
|
||||
if (![self.fileManager fileExistsAtPath:_diskCachePath]) {
|
||||
if (![self.fileManager createDirectoryAtPath:_diskCachePath withIntermediateDirectories:YES attributes:nil error:error]) {
|
||||
return NO;
|
||||
if (![self.fileManager createDirectoryAtPath:_diskCachePath withIntermediateDirectories:YES attributes:nil error:nil]) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -349,8 +339,8 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
|
||||
// NSFileManager's `createFileAtPath:` is used just for old code compatibility and will not trigger any delegate methods, so it's useless for custom NSFileManager at all.
|
||||
// And also, NSFileManager's `createFileAtPath:` can only grab underlying POSIX errno, but NSData can grab errors defined in NSCocoaErrorDomain, which is better for user to check.
|
||||
if (![imageData writeToURL:fileURL options:self.config.diskCacheWritingOptions error:error]) {
|
||||
return NO;
|
||||
if (![imageData writeToURL:fileURL options:self.config.diskCacheWritingOptions error:nil]) {
|
||||
return;
|
||||
}
|
||||
|
||||
// disable iCloud backup
|
||||
|
@ -358,8 +348,6 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
// ignore iCloud backup resource value error
|
||||
[fileURL setResourceValue:@YES forKey:NSURLIsExcludedFromBackupKey error:nil];
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
#pragma mark - Query and Retrieve Ops
|
||||
|
@ -452,7 +440,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
}
|
||||
}
|
||||
|
||||
return nil;
|
||||
return data;
|
||||
}
|
||||
|
||||
- (nullable UIImage *)diskImageForKey:(nullable NSString *)key {
|
||||
|
|
|
@ -57,8 +57,7 @@ NSString *kImageTestKey = @"TestImageKey.jpg";
|
|||
- (void)test05ClearMemoryCache{
|
||||
XCTestExpectation *expectation = [self expectationWithDescription:@"Clear memory cache"];
|
||||
|
||||
[[SDImageCache sharedImageCache] storeImage:[self imageForTesting] forKey:kImageTestKey completion:^(NSError * _Nullable error) {
|
||||
expect(error).to.beNil();
|
||||
[[SDImageCache sharedImageCache] storeImage:[self imageForTesting] forKey:kImageTestKey completion:^{
|
||||
[[SDImageCache sharedImageCache] clearMemory];
|
||||
expect([[SDImageCache sharedImageCache] imageFromMemoryCacheForKey:kImageTestKey]).to.beNil;
|
||||
[[SDImageCache sharedImageCache] diskImageExistsWithKey:kImageTestKey completion:^(BOOL isInCache) {
|
||||
|
@ -185,8 +184,7 @@ NSString *kImageTestKey = @"TestImageKey.jpg";
|
|||
|
||||
- (void)test21InitialDiskCount{
|
||||
XCTestExpectation *expectation = [self expectationWithDescription:@"getDiskCount"];
|
||||
[[SDImageCache sharedImageCache] storeImage:[self imageForTesting] forKey:kImageTestKey completion:^(NSError * _Nullable error) {
|
||||
expect(error).to.beNil();
|
||||
[[SDImageCache sharedImageCache] storeImage:[self imageForTesting] forKey:kImageTestKey completion:^{
|
||||
expect([[SDImageCache sharedImageCache] getDiskCount]).to.equal(1);
|
||||
[[SDImageCache sharedImageCache] removeImageForKey:kImageTestKey withCompletion:^{
|
||||
[expectation fulfill];
|
||||
|
@ -207,8 +205,7 @@ NSString *kImageTestKey = @"TestImageKey.jpg";
|
|||
|
||||
- (void)test33CachePathForExistingKey{
|
||||
XCTestExpectation *expectation = [self expectationWithDescription:@"cachePathForKey inPath"];
|
||||
[[SDImageCache sharedImageCache] storeImage:[self imageForTesting] forKey:kImageTestKey completion:^(NSError * _Nullable error) {
|
||||
expect(error).to.beNil();
|
||||
[[SDImageCache sharedImageCache] storeImage:[self imageForTesting] forKey:kImageTestKey completion:^{
|
||||
NSString *path = [[SDImageCache sharedImageCache] cachePathForKey:kImageTestKey];
|
||||
expect(path).notTo.beNil;
|
||||
[[SDImageCache sharedImageCache] removeImageForKey:kImageTestKey withCompletion:^{
|
||||
|
@ -237,7 +234,7 @@ NSString *kImageTestKey = @"TestImageKey.jpg";
|
|||
|
||||
UIImage *image = [[UIImage alloc] initWithContentsOfFile:[self testImagePath]];
|
||||
NSData *imageData = UIImageJPEGRepresentation(image, 1.0);
|
||||
[[SDImageCache sharedImageCache] storeImageDataToDisk:imageData forKey:kImageTestKey error:nil];
|
||||
[[SDImageCache sharedImageCache] storeImageDataToDisk:imageData forKey:kImageTestKey];
|
||||
|
||||
UIImage *storedImageFromMemory = [[SDImageCache sharedImageCache] imageFromMemoryCacheForKey:kImageTestKey];
|
||||
expect(storedImageFromMemory).to.equal(nil);
|
||||
|
@ -269,7 +266,7 @@ NSString *kImageTestKey = @"TestImageKey.jpg";
|
|||
UIImage *image = [[UIImage alloc] initWithContentsOfFile:testImagePath];
|
||||
NSString *key = @"TestPNGImageEncodedToDataAndRetrieveToJPEG";
|
||||
|
||||
[cache storeImage:image imageData:nil forKey:key toDisk:YES completion:^(NSError * _Nullable error) {
|
||||
[cache storeImage:image imageData:nil forKey:key toDisk:YES completion:^{
|
||||
[cache clearMemory];
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wundeclared-selector"
|
||||
|
@ -309,35 +306,19 @@ NSString *kImageTestKey = @"TestImageKey.jpg";
|
|||
}
|
||||
#endif
|
||||
|
||||
- (void)test41StoreImageDataToDiskWithError {
|
||||
- (void)test41StoreImageDataToDiskWithCustomFileManager {
|
||||
NSData *imageData = [NSData dataWithContentsOfFile:[self testImagePath]];
|
||||
NSError *targetError = [NSError errorWithDomain:NSCocoaErrorDomain code:NSFileWriteNoPermissionError userInfo:nil];
|
||||
NSError *error = nil;
|
||||
|
||||
SDMockFileManager *fileManager = [[SDMockFileManager alloc] init];
|
||||
fileManager.mockSelectors = @{NSStringFromSelector(@selector(createDirectoryAtPath:withIntermediateDirectories:attributes:error:)) : targetError};
|
||||
SDImageCache *cache = [[SDImageCache alloc] initWithNamespace:@"test"
|
||||
diskCacheDirectory:@"/"
|
||||
fileManager:fileManager];
|
||||
[cache storeImageDataToDisk:imageData
|
||||
forKey:kImageTestKey
|
||||
error:&error];
|
||||
expect(fileManager.lastError).to.beNil();
|
||||
|
||||
XCTAssertEqual(error.code, NSFileWriteNoPermissionError);
|
||||
}
|
||||
|
||||
- (void)test42StoreImageDataToDiskWithoutError {
|
||||
NSData *imageData = [NSData dataWithContentsOfFile:[self testImagePath]];
|
||||
NSError *error = nil;
|
||||
SDMockFileManager *fileManager = [[SDMockFileManager alloc] init];
|
||||
fileManager.mockSelectors = @{NSStringFromSelector(@selector(createDirectoryAtPath:withIntermediateDirectories:attributes:error:)) : [NSNull null]};
|
||||
SDImageCache *cache = [[SDImageCache alloc] initWithNamespace:@"test"
|
||||
diskCacheDirectory:@"/"
|
||||
fileManager:fileManager];
|
||||
// This disk cache path creation will be mocked with error.
|
||||
SDImageCache *cache = [[SDImageCache alloc] initWithNamespace:@"test" diskCacheDirectory:@"/" fileManager:fileManager];
|
||||
[cache storeImageDataToDisk:imageData
|
||||
forKey:kImageTestKey
|
||||
error:&error];
|
||||
|
||||
XCTAssertNil(error);
|
||||
forKey:kImageTestKey];
|
||||
expect(fileManager.lastError).equal(targetError);
|
||||
}
|
||||
|
||||
#pragma mark Helper methods
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
// This is a mock class to provide custom error for methods
|
||||
@interface SDMockFileManager : NSFileManager
|
||||
|
||||
@property (nonatomic, strong, readonly, nullable) NSError *lastError;
|
||||
|
||||
@property (nonatomic, copy, nullable) NSDictionary<NSString *, NSError *> *mockSelectors; // used to specify mocked selectors which will return NO with specify error instead of normal process. If you specify a NSNull, will use nil instead.
|
||||
|
||||
@end
|
||||
|
|
|
@ -10,11 +10,14 @@
|
|||
|
||||
@interface SDMockFileManager ()
|
||||
|
||||
@property (nonatomic, strong, nullable) NSError *lastError;
|
||||
|
||||
@end
|
||||
|
||||
@implementation SDMockFileManager
|
||||
|
||||
- (BOOL)createDirectoryAtPath:(NSString *)path withIntermediateDirectories:(BOOL)createIntermediates attributes:(NSDictionary<NSFileAttributeKey,id> *)attributes error:(NSError * _Nullable __autoreleasing *)error {
|
||||
self.lastError = nil;
|
||||
NSError *mockError = [self.mockSelectors objectForKey:NSStringFromSelector(_cmd)];
|
||||
if ([mockError isEqual:[NSNull null]]) {
|
||||
if (error) {
|
||||
|
@ -25,6 +28,7 @@
|
|||
if (error) {
|
||||
*error = mockError;
|
||||
}
|
||||
self.lastError = mockError;
|
||||
return NO;
|
||||
} else {
|
||||
return [super createDirectoryAtPath:path withIntermediateDirectories:createIntermediates attributes:attributes error:error];
|
||||
|
|
Loading…
Reference in New Issue