Browse Source

Fix loading cache callback option

onevcat 7 years ago
parent
commit
6a25362030

+ 15 - 10
Sources/General/KingfisherManager.swift

@@ -321,13 +321,16 @@ public class KingfisherManager {
             (options.fromMemoryCacheOrRefresh == false || targetImageCached == .memory)
         if validCache {
             targetCache.retrieveImage(forKey: key, options: options) { result in
-                if let image = result.value?.image {
-                    let value = result.map {
-                        RetrieveImageResult(image: image, cacheType: $0.cacheType, source: source)
+                guard let completionHandler = completionHandler else { return }
+                options.callbackQueue.execute {
+                    if let image = result.value?.image {
+                        let value = result.map {
+                            RetrieveImageResult(image: image, cacheType: $0.cacheType, source: source)
+                        }
+                        completionHandler(value)
+                    } else {
+                        completionHandler(.failure(KingfisherError.cacheError(reason: .imageNotExisting(key: key))))
                     }
-                    completionHandler?(value)
-                } else {
-                    completionHandler?(.failure(KingfisherError.cacheError(reason: .imageNotExisting(key: key))))
                 }
             }
             return true
@@ -356,7 +359,7 @@ public class KingfisherManager {
                         guard let processedImage = processor.process(item: item, options: options) else {
                             let error = KingfisherError.processorError(
                                             reason: .processingFailed(processor: processor, item: item))
-                            completionHandler?(.failure(error))
+                            options.callbackQueue.execute { completionHandler?(.failure(error)) }
                             return
                         }
 
@@ -371,19 +374,21 @@ public class KingfisherManager {
                             _ in
                             if options.waitForCache {
                                 let value = RetrieveImageResult(image: processedImage, cacheType: .none, source: source)
-                                completionHandler?(.success(value))
+                                options.callbackQueue.execute { completionHandler?(.success(value)) }
                             }
                         }
 
                         if !options.waitForCache {
                             let value = RetrieveImageResult(image: processedImage, cacheType: .none, source: source)
-                            completionHandler?(.success(value))
+                            options.callbackQueue.execute { completionHandler?(.success(value)) }
                         }
                     }
                 } else {
                     // This should not happen actually, since we already confirmed `originalImageCached` is `true`.
                     // Just in case...
-                    completionHandler?(.failure(KingfisherError.cacheError(reason: .imageNotExisting(key: key))))
+                    options.callbackQueue.execute {
+                        completionHandler?(.failure(KingfisherError.cacheError(reason: .imageNotExisting(key: key))))
+                    }
                 }
             }
             return true

+ 16 - 0
Tests/KingfisherTests/KingfisherManagerTests.swift

@@ -220,6 +220,22 @@ class KingfisherManagerTests: XCTestCase {
         }
         waitForExpectations(timeout: 3, handler: nil)
     }
+
+    func testLoadCacheCompletionHandlerRunningOnCustomQueue() {
+        let completionExpectation = expectation(description: "completionHandler running on custom queue")
+
+        let url = testURLs[0]
+        manager.cache.store(testImage, forKey: url.cacheKey)
+
+        let customQueue = DispatchQueue(label: "com.kingfisher.testQueue")
+        manager.retrieveImage(with: url, options: [.callbackQueue(.dispatch(customQueue))]) {
+            result in
+            XCTAssertNil(result.error)
+            dispatchPrecondition(condition: .onQueue(customQueue))
+            completionExpectation.fulfill()
+        }
+        waitForExpectations(timeout: 3, handler: nil)
+    }
     
     func testDefaultOptionCouldApply() {
         let exp = expectation(description: #function)