Merge pull request #3066 from dreampiggy/feature_default_cache_path

Supports the user to customize the default disk cache directory, which can be used to share cache for App && App Extension
This commit is contained in:
DreamPiggy 2020-08-13 10:40:38 +08:00 committed by GitHub
commit 09aee5f534
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 52 additions and 11 deletions

View File

@ -103,8 +103,18 @@ typedef NS_OPTIONS(NSUInteger, SDImageCacheOptions) {
*/
@property (nonatomic, class, readonly, nonnull) SDImageCache *sharedImageCache;
/**
* Control the default disk cache directory. This will effect all the SDImageCache instance created after modification, even for shared image cache.
* This can be used to share the same disk cache with the App and App Extension (Today/Notification Widget) using `- [NSFileManager.containerURLForSecurityApplicationGroupIdentifier:]`.
* @note If you pass nil, the value will be reset to `~/Library/Caches/com.hackemist.SDImageCache`.
* @note We still preserve the `namespace` arg, which means, if you change this property into `/path/to/use`, the `SDImageCache.sharedImageCache.diskCachePath` should be `/path/to/use/default` because shared image cache use `default` as namespace.
* Defaults to nil.
*/
@property (nonatomic, class, readwrite, null_resettable) NSString *defaultDiskCacheDirectory;
/**
* Init a new cache store with a specific namespace
* The final disk cache directory should looks like ($directory/$namespace). And the default config of shared cache, should result in (~/Library/Caches/com.hackemist.SDImageCache/default/)
*
* @param ns The namespace to use for this cache store
*/
@ -112,7 +122,7 @@ typedef NS_OPTIONS(NSUInteger, SDImageCacheOptions) {
/**
* Init a new cache store with a specific namespace and directory.
* If you don't provide the disk cache directory, we will use the User Cache directory with prefix (~/Library/Caches/com.hackemist.SDImageCache/).
* The final disk cache directory should looks like ($directory/$namespace). And the default config of shared cache, should result in (~/Library/Caches/com.hackemist.SDImageCache/default/)
*
* @param ns The namespace to use for this cache store
* @param directory Directory to cache disk images in
@ -121,7 +131,7 @@ typedef NS_OPTIONS(NSUInteger, SDImageCacheOptions) {
diskCacheDirectory:(nullable NSString *)directory;
/**
* Init a new cache store with a specific namespace, directory and file manager
* Init a new cache store with a specific namespace, directory and config.
* The final disk cache directory should looks like ($directory/$namespace). And the default config of shared cache, should result in (~/Library/Caches/com.hackemist.SDImageCache/default/)
*
* @param ns The namespace to use for this cache store

View File

@ -15,6 +15,8 @@
#import "UIImage+Metadata.h"
#import "UIImage+ExtendedCacheData.h"
static NSString * _defaultDiskCacheDirectory;
@interface SDImageCache ()
#pragma mark - Properties
@ -40,6 +42,17 @@
return instance;
}
+ (NSString *)defaultDiskCacheDirectory {
if (!_defaultDiskCacheDirectory) {
_defaultDiskCacheDirectory = [[self userCacheDirectory] stringByAppendingPathComponent:@"com.hackemist.SDImageCache"];
}
return _defaultDiskCacheDirectory;
}
+ (void)setDefaultDiskCacheDirectory:(NSString *)defaultDiskCacheDirectory {
_defaultDiskCacheDirectory = [defaultDiskCacheDirectory copy];
}
- (instancetype)init {
return [self initWithNamespace:@"default"];
}
@ -72,12 +85,11 @@
_memoryCache = [[config.memoryCacheClass alloc] initWithConfig:_config];
// Init the disk cache
if (directory != nil) {
_diskCachePath = [directory stringByAppendingPathComponent:ns];
} else {
NSString *path = [[[self userCacheDirectory] stringByAppendingPathComponent:@"com.hackemist.SDImageCache"] stringByAppendingPathComponent:ns];
_diskCachePath = path;
if (!directory) {
// Use default disk cache directory
directory = [self.class defaultDiskCacheDirectory];
}
_diskCachePath = [directory stringByAppendingPathComponent:ns];
NSAssert([config.diskCacheClass conformsToProtocol:@protocol(SDDiskCache)], @"Custom disk cache class must conform to `SDDiskCache` protocol");
_diskCache = [[config.diskCacheClass alloc] initWithCachePath:_diskCachePath config:_config];
@ -121,7 +133,7 @@
return [self.diskCache cachePathForKey:key];
}
- (nullable NSString *)userCacheDirectory {
+ (nullable NSString *)userCacheDirectory {
NSArray<NSString *> *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
return paths.firstObject;
}
@ -131,9 +143,9 @@
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// ~/Library/Caches/com.hackemist.SDImageCache/default/
NSString *newDefaultPath = [[[self userCacheDirectory] stringByAppendingPathComponent:@"com.hackemist.SDImageCache"] stringByAppendingPathComponent:@"default"];
NSString *newDefaultPath = [[[self.class userCacheDirectory] stringByAppendingPathComponent:@"com.hackemist.SDImageCache"] stringByAppendingPathComponent:@"default"];
// ~/Library/Caches/default/com.hackemist.SDWebImageCache.default/
NSString *oldDefaultPath = [[[self userCacheDirectory] stringByAppendingPathComponent:@"default"] stringByAppendingPathComponent:@"com.hackemist.SDWebImageCache.default"];
NSString *oldDefaultPath = [[[self.class userCacheDirectory] stringByAppendingPathComponent:@"default"] stringByAppendingPathComponent:@"com.hackemist.SDWebImageCache.default"];
dispatch_async(self.ioQueue, ^{
[((SDDiskCache *)self.diskCache) moveCacheDirectoryFromPath:oldDefaultPath toPath:newDefaultPath];
});

View File

@ -484,6 +484,25 @@ static NSString *kTestImageKeyPNG = @"TestImageKey.png";
[self waitForExpectationsWithCommonTimeout];
}
- (void)test43CustomDefaultCacheDirectory {
NSArray<NSString *> *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *testDirectory = [paths.firstObject stringByAppendingPathComponent:@"CustomDefaultCacheDirectory"];
NSString *defaultDirectory = [paths.firstObject stringByAppendingPathComponent:@"com.hackemist.SDImageCache"];
NSString *namespace = @"Test";
// Default cache path
expect(SDImageCache.defaultDiskCacheDirectory).equal(defaultDirectory);
SDImageCache *cache1 = [[SDImageCache alloc] initWithNamespace:namespace];
expect(cache1.diskCachePath).equal([defaultDirectory stringByAppendingPathComponent:namespace]);
// Custom cache path
SDImageCache.defaultDiskCacheDirectory = testDirectory;
SDImageCache *cache2 = [[SDImageCache alloc] initWithNamespace:namespace];
expect(cache2.diskCachePath).equal([testDirectory stringByAppendingPathComponent:namespace]);
// Check reset
SDImageCache.defaultDiskCacheDirectory = nil;
expect(SDImageCache.defaultDiskCacheDirectory).equal(defaultDirectory);
}
#pragma mark - SDMemoryCache & SDDiskCache
- (void)test42CustomMemoryCache {
SDImageCacheConfig *config = [[SDImageCacheConfig alloc] init];

View File

@ -203,7 +203,7 @@
}
- (void)test16ThatHEICAnimatedWorks {
if (@available(iOS 11, tvOS 11, macOS 10.13, *)) {
if (@available(iOS 13, tvOS 13, macOS 10.15, *)) {
NSURL *heicURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"TestImageAnimated" withExtension:@"heic"];
#if SD_UIKIT
BOOL isAnimatedImage = YES;