Răsfoiți Sursa

Merge pull request #963 from zeplin/wait-for-cache

Add `waitForCache` option for waiting caching before returning the retrieved image
Wei Wang 7 ani în urmă
părinte
comite
33b090913e

+ 20 - 5
Sources/KingfisherManager.swift

@@ -170,7 +170,13 @@ public class KingfisherManager {
                                       processorIdentifier:options.processor.identifier,
                                       cacheSerializer: options.cacheSerializer,
                                       toDisk: !options.cacheMemoryOnly,
-                                      completionHandler: nil)
+                                      completionHandler: {
+                                        guard options.waitForCache else { return }
+                                        
+                                        let cacheType = targetCache.imageCachedType(forKey: key, processorIdentifier: options.processor.identifier)
+                                        completionHandler?(image, nil, cacheType, url)
+                    })
+                    
                     if options.cacheOriginalImage && options.processor != DefaultImageProcessor.default {
                         let originalCache = options.originalCache
                         let defaultProcessor = DefaultImageProcessor.default
@@ -186,8 +192,9 @@ public class KingfisherManager {
                     }
                 }
 
-                completionHandler?(image, error, .none, url)
-
+                if options.waitForCache == false {
+                    completionHandler?(image, error, .none, url)
+                }
             })
     }
     
@@ -257,8 +264,16 @@ public class KingfisherManager {
                                   processorIdentifier:options.processor.identifier,
                                   cacheSerializer: options.cacheSerializer,
                                   toDisk: !options.cacheMemoryOnly,
-                                  completionHandler: nil)
-                diskTaskCompletionHandler(processedImage, nil, .none, url)
+                                  completionHandler: {
+                                    guard options.waitForCache else { return }
+                                    
+                                    let cacheType = targetCache.imageCachedType(forKey: key, processorIdentifier: options.processor.identifier)
+                                    diskTaskCompletionHandler(processedImage, nil, cacheType, url)
+                })
+                
+                if options.waitForCache == false {
+                    diskTaskCompletionHandler(processedImage, nil, .none, url)
+                }
             }
         }
     }

+ 9 - 0
Sources/KingfisherOptionsInfo.swift

@@ -80,6 +80,9 @@ public enum KingfisherOptionsInfoItem {
     ///  If set, `Kingfisher` will only cache the value in memory but not in disk.
     case cacheMemoryOnly
     
+    ///  If set, `Kingfisher` will wait for caching operation to be completed before calling the completion block.
+    case waitForCache
+    
     /// If set, `Kingfisher` will only try to retrieve the image from cache not from network.
     case onlyFromCache
     
@@ -165,6 +168,7 @@ func <== (lhs: KingfisherOptionsInfoItem, rhs: KingfisherOptionsInfoItem) -> Boo
     case (.fromMemoryCacheOrRefresh, .fromMemoryCacheOrRefresh): return true
     case (.forceTransition, .forceTransition): return true
     case (.cacheMemoryOnly, .cacheMemoryOnly): return true
+    case (.waitForCache, .waitForCache): return true
     case (.onlyFromCache, .onlyFromCache): return true
     case (.backgroundDecode, .backgroundDecode): return true
     case (.callbackDispatchQueue(_), .callbackDispatchQueue(_)): return true
@@ -264,6 +268,11 @@ public extension Collection where Iterator.Element == KingfisherOptionsInfoItem
         return contains{ $0 <== .cacheMemoryOnly }
     }
     
+    /// Whether the caching operation will be waited or not.
+    public var waitForCache: Bool {
+        return contains{ $0 <== .waitForCache }
+    }
+    
     /// Whether only load the images from cache or not.
     public var onlyFromCache: Bool {
         return contains{ $0 <== .onlyFromCache }

+ 39 - 0
Tests/KingfisherTests/KingfisherManagerTests.swift

@@ -459,6 +459,45 @@ class KingfisherManagerTests: XCTestCase {
         
         waitForExpectations(timeout: 5, handler: nil)
     }
+    
+    func testWaitForCacheOnRetrieveImage() {
+        cleanDefaultCache()
+        let expectation = self.expectation(description: "wait for caching image on retrieve image")
+        let URLString = testKeys[0]
+        _ = stubRequest("GET", URLString).andReturn(200)?.withBody(testImageData)
+        
+        let url = URL(string: URLString)!
+        
+        self.manager.retrieveImage(with: url, options: [.waitForCache], progressBlock: nil) {
+            image, error, cacheType, imageURL in
+            XCTAssertNotNil(image)
+            XCTAssertEqual(cacheType, .memory)
+            
+            expectation.fulfill()
+        }
+        
+        waitForExpectations(timeout: 5, handler: nil)
+    }
+    
+    func testWaitForCacheOnRetrieveImageWithProcessor() {
+        cleanDefaultCache()
+        let expectation = self.expectation(description: "wait for caching image on retrieve image with processor")
+        let URLString = testKeys[0]
+        _ = stubRequest("GET", URLString).andReturn(200)?.withBody(testImageData)
+        
+        let url = URL(string: URLString)!
+        
+        let p = RoundCornerImageProcessor(cornerRadius: 20)
+        self.manager.retrieveImage(with: url, options: [.processor(p), .waitForCache], progressBlock: nil) {
+            image, error, cacheType, imageURL in
+            XCTAssertNotNil(image)
+            XCTAssertEqual(cacheType, .memory)
+            
+            expectation.fulfill()
+        }
+        
+        waitForExpectations(timeout: 5, handler: nil)
+    }
 
     func testImageShouldOnlyFromMemoryCacheOrRefreshCanBeGotFromMemory() {
         let expectation = self.expectation(description: "only from memory cache or refresh")