Преглед изворни кода

Add the feature, to migrate the disk cache from 4.x version to the new location of cache path.

DreamPiggy пре 7 година
родитељ
комит
d9d0b7d4bf
4 измењених фајлова са 75 додато и 1 уклоњено
  1. 11 0
      SDWebImage/SDDiskCache.h
  2. 29 0
      SDWebImage/SDDiskCache.m
  3. 14 0
      SDWebImage/SDImageCache.m
  4. 21 1
      Tests/Tests/SDImageCacheTests.m

+ 11 - 0
SDWebImage/SDDiskCache.h

@@ -104,4 +104,15 @@
 
 - (nonnull instancetype)init NS_UNAVAILABLE;
 
+/**
+ Move the cache directory from old location to new location, the old location will be removed after finish.
+ If the old location does not exist, does nothing.
+ If the new location does not exist, only do a movement of directory.
+ If the new location does exist, will move and merge the files from old location.
+
+ @param srcPath old location of cache directory
+ @param dstPath new location of cache directory
+ */
+- (void)moveCacheDirectoryFromPath:(nonnull NSString *)srcPath toPath:(nonnull NSString *)dstPath;
+
 @end

+ 29 - 0
SDWebImage/SDDiskCache.m

@@ -228,6 +228,35 @@
     return [path stringByAppendingPathComponent:filename];
 }
 
+- (void)moveCacheDirectoryFromPath:(nonnull NSString *)srcPath toPath:(nonnull NSString *)dstPath {
+    NSParameterAssert(srcPath);
+    NSParameterAssert(dstPath);
+    BOOL isDirectory;
+    // Check if old path is directory
+    if (![self.fileManager fileExistsAtPath:srcPath isDirectory:&isDirectory] || !isDirectory) {
+        return;
+    }
+    // Check if new path is directory
+    if (![self.fileManager fileExistsAtPath:dstPath isDirectory:&isDirectory]) {
+        // New directory does not exist, rename directory
+        [self.fileManager moveItemAtPath:srcPath toPath:dstPath error:nil];
+    } else {
+        if (!isDirectory) {
+            // New path is not directory, remove directory
+            [self.fileManager removeItemAtPath:dstPath error:nil];
+        }
+        // New directory exist, merge the files
+        NSDirectoryEnumerator *dirEnumerator = [self.fileManager enumeratorAtPath:srcPath];
+        NSString *file;
+        while ((file = [dirEnumerator nextObject])) {
+            // Don't handle error, just try to move.
+            [self.fileManager moveItemAtPath:[srcPath stringByAppendingPathComponent:file] toPath:[dstPath stringByAppendingPathComponent:file] error:nil];
+        }
+    }
+    // Remove the old path
+    [self.fileManager removeItemAtPath:srcPath error:nil];
+}
+
 #pragma mark - Hash
 
 static inline NSString * _Nullable SDDiskCacheFileNameForKey(NSString * _Nullable key) {

+ 14 - 0
SDWebImage/SDImageCache.m

@@ -86,6 +86,7 @@
         
         NSAssert([config.diskCacheClass conformsToProtocol:@protocol(SDDiskCache)], @"Custom disk cache class must conform to `SDDiskCache` protocol");
         _diskCache = [[config.diskCacheClass alloc] initWithCachePath:_diskCachePath config:_config];
+        [self migrateDiskCacheDirectory];
 
 #if SD_UIKIT
         // Subscribe to app events
@@ -128,6 +129,19 @@
     return [paths[0] stringByAppendingPathComponent:fullNamespace];
 }
 
+- (void)migrateDiskCacheDirectory {
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        if ([self.diskCache isKindOfClass:[SDDiskCache class]]) {
+            NSString *newDefaultPath = [[self makeDiskCachePath:@"default"] stringByAppendingPathComponent:@"com.hackemist.SDImageCache.default"];
+            NSString *oldDefaultPath = [[self makeDiskCachePath:@"default"] stringByAppendingPathComponent:@"com.hackemist.SDWebImageCache.default"];
+            dispatch_async(self.ioQueue, ^{
+                [((SDDiskCache *)self.diskCache) moveCacheDirectoryFromPath:oldDefaultPath toPath:newDefaultPath];
+            });
+        }
+    });
+}
+
 #pragma mark - Store Ops
 
 - (void)storeImage:(nullable UIImage *)image

+ 21 - 1
Tests/Tests/SDImageCacheTests.m

@@ -21,7 +21,8 @@ static NSString *kTestImageKeyPNG = @"TestImageKey.png";
 
 @end
 
-@interface SDImageCacheTests : SDTestCase
+@interface SDImageCacheTests : SDTestCase <NSFileManagerDelegate>
+
 @end
 
 @implementation SDImageCacheTests
@@ -359,6 +360,25 @@ static NSString *kTestImageKeyPNG = @"TestImageKey.png";
     expect([diskCache isKindOfClass:[SDWebImageTestDiskCache class]]).to.beTruthy();
 }
 
+- (void)test44DiskCacheMigrationFromOldVersion {
+    SDImageCacheConfig *config = [[SDImageCacheConfig alloc] init];
+    NSFileManager *fileManager = [[NSFileManager alloc] init];
+    config.fileManager = fileManager;
+    
+    // Fake to store a.png into old path
+    NSString *newDefaultPath = [[self makeDiskCachePath:@"default"] stringByAppendingPathComponent:@"com.hackemist.SDImageCache.default"];
+    NSString *oldDefaultPath = [[self makeDiskCachePath:@"default"] stringByAppendingPathComponent:@"com.hackemist.SDWebImageCache.default"];
+    [fileManager createDirectoryAtPath:oldDefaultPath withIntermediateDirectories:YES attributes:nil error:nil];
+    [fileManager createFileAtPath:[oldDefaultPath stringByAppendingPathComponent:@"a.png"] contents:[NSData dataWithContentsOfFile:[self testPNGPath]] attributes:nil];
+    // Call migration
+    SDDiskCache *diskCache = [[SDDiskCache alloc] initWithCachePath:newDefaultPath config:config];
+    [diskCache moveCacheDirectoryFromPath:oldDefaultPath toPath:newDefaultPath];
+    
+    // Expect a.png into new path
+    BOOL exist = [fileManager fileExistsAtPath:[newDefaultPath stringByAppendingPathComponent:@"a.png"]];
+    expect(exist).beTruthy();
+}
+
 #pragma mark - SDImageCache & SDImageCachesManager
 - (void)test50SDImageCacheQueryOp {
     XCTestExpectation *expectation = [self expectationWithDescription:@"SDImageCache query op works"];