Sfoglia il codice sorgente

Add option to supply default path extension

Especially useful when using Kingfisher on macOS and wanting to add
drag-drop. Most web input fields won't accept files without a path
extension (like .jpg).

Currently only supports a single default path extension. Could later
be expanded to include a path extension per image.
Boy van Amstel 9 anni fa
parent
commit
440a5b5d52
2 ha cambiato i file con 52 aggiunte e 1 eliminazioni
  1. 7 1
      Sources/ImageCache.swift
  2. 45 0
      Tests/KingfisherTests/ImageCacheTests.swift

+ 7 - 1
Sources/ImageCache.swift

@@ -87,6 +87,9 @@ open class ImageCache {
     
     ///The disk cache location.
     open let diskCachePath: String
+  
+    /// The default file extension appended to cached files.
+    open var pathExtension: String?
     
     /// The longest time duration in second of the cache being stored in disk. 
     /// Default is 1 week (60 * 60 * 24 * 7 seconds).
@@ -621,7 +624,7 @@ extension ImageCache {
 
 // MARK: - Internal Helper
 extension ImageCache {
-    
+  
     func diskImage(forComputedKey key: String, serializer: CacheSerializer, options: KingfisherOptionsInfo) -> Image? {
         if let data = diskImageData(forComputedKey: key) {
             return serializer.image(with: data, options: options)
@@ -636,6 +639,9 @@ extension ImageCache {
     }
     
     func cacheFileName(forComputedKey key: String) -> String {
+        if let ext = self.pathExtension {
+          return (key.kf.md5 as NSString).appendingPathExtension(ext)!
+        }
         return key.kf.md5
     }
 }

+ 45 - 0
Tests/KingfisherTests/ImageCacheTests.swift

@@ -200,6 +200,51 @@ class ImageCacheTests: XCTestCase {
         XCTAssertFalse(exists)
     }
 
+    func testCachedFileWithCustomPathExtensionExists() {
+        cache.pathExtension = "jpg"
+        let expectation = self.expectation(description: "cache with custom path extension does contain image")
+        
+        let URLString = testKeys[0]
+        let url = URL(string: URLString)!
+        
+        let exists = cache.isImageCached(forKey: url.cacheKey).cached
+        XCTAssertFalse(exists)
+        
+        cache.retrieveImage(forKey: URLString, options: nil, completionHandler: { (image, type) -> () in
+            XCTAssertNil(image, "Should not be cached yet")
+            
+            XCTAssertEqual(type, .none)
+            
+            self.cache.store(testImage, forKey: URLString, toDisk: true) { () -> () in
+                self.cache.retrieveImage(forKey: URLString, options: nil, completionHandler: { (image, type) -> () in
+                    XCTAssertNotNil(image, "Should be cached (memory or disk)")
+                    XCTAssertEqual(type, .memory)
+                    
+                    let exists = self.cache.isImageCached(forKey: url.cacheKey).cached
+                    XCTAssertTrue(exists, "Image should exist in the cache (memory or disk)")
+                    
+                    self.cache.clearMemoryCache()
+                    self.cache.retrieveImage(forKey: URLString, options: nil, completionHandler: { (image, type) -> () in
+                        XCTAssertNotNil(image, "Should be cached (disk)")
+                        XCTAssertEqual(type, CacheType.disk)
+                        
+                        let exists = self.cache.isImageCached(forKey: url.cacheKey).cached
+                        XCTAssertTrue(exists, "Image should exist in the cache (disk)")
+                        
+                        let cachePath = self.cache.cachePath(forKey: url.cacheKey)
+                        let hasExtension = cachePath.hasSuffix(".jpg")
+                        XCTAssert(hasExtension, "Should have .jpg file extension")
+                        
+                        expectation.fulfill()
+                    })
+                })
+            }
+        })
+        
+        waitForExpectations(timeout: 5, handler: nil)
+    }
+
+  
     func testCachedImageIsFetchedSyncronouslyFromTheMemoryCache() {
         cache.store(testImage, forKey: testKeys[0], toDisk: false) { () -> () in
             // do nothing