Przeglądaj źródła

Conceptual prove of side effect option

onevcat 6 lat temu
rodzic
commit
4c44023f55

+ 26 - 4
Sources/Extensions/ImageView+Kingfisher.swift

@@ -31,6 +31,8 @@ import AppKit
 import UIKit
 #endif
 
+extension ImageView: ImageSettable {}
+
 extension KingfisherWrapper where Base: ImageView {
 
     // MARK: Setting Image
@@ -105,6 +107,30 @@ extension KingfisherWrapper where Base: ImageView {
             options.preloadAllAnimationData = true
         }
 
+        if let progressBlock = progressBlock {
+            options.onDataReceived = (options.onDataReceived ?? []) + [ImageLoadingProgressSideEffect(progressBlock)]
+        }
+
+        if let progressive = options.progressiveJPEG {
+
+            let p = ImageProgressiveProvider(
+                options,
+                isContinue: { () -> Bool in
+                    issuedIdentifier == self.taskIdentifier
+                },
+                isFinished: { () -> Bool in
+                    mutatingSelf.imageTask != nil
+                },
+                refreshImage: { (image) in
+                    //self.base.image = image
+                }
+            )
+
+            p.imageSettable = base
+
+            options.onDataReceived = (options.onDataReceived ?? []) + [p]
+        }
+
         options.onDataReceived?.forEach {
             $0.onShouldApply = { issuedIdentifier == self.taskIdentifier }
         }
@@ -112,10 +138,6 @@ extension KingfisherWrapper where Base: ImageView {
         let task = KingfisherManager.shared.retrieveImage(
             with: source,
             options: options,
-            progressBlock: { receivedSize, totalSize in
-                guard issuedIdentifier == self.taskIdentifier else { return }
-                progressBlock?(receivedSize, totalSize)
-            },
             completionHandler: { result in
                 CallbackQueue.mainCurrentOrAsync.execute {
                     maybeIndicator?.stopAnimatingView()

+ 17 - 7
Sources/Image/ImageProgressive.swift

@@ -60,8 +60,20 @@ public struct ImageProgressive {
     }
 }
 
-final class ImageProgressiveProvider {
-    
+protocol ImageSettable: AnyObject {
+    var image: Image? { get set }
+}
+
+final class ImageProgressiveProvider: DataReceivingSideEffect {
+
+    weak var imageSettable: ImageSettable?
+
+    func onDataReceived(_ session: URLSession, task: SessionDataTask, data: Data) {
+        update(data: task.mutableData, with: task.callbacks)
+    }
+
+    var onShouldApply: () -> Bool = { return true }
+
     private let options: KingfisherParsedOptionsInfo
     private let refreshClosure: (Image) -> Void
     private let isContinueClosure: () -> Bool
@@ -95,14 +107,12 @@ final class ImageProgressiveProvider {
                     completion()
                     return
                 }
-                
                 self.decoder.decode(data, with: callbacks) { image in
                     defer { completion() }
-                    guard self.isContinueClosure() else { return }
-                    guard self.isWait || !self.isFinishedClosure() else { return }
+                    // guard self.isContinueClosure() else { return }
+                    // guard self.isWait || !self.isFinishedClosure() else { return }
                     guard let image = image else { return }
-                    
-                    self.refreshClosure(image)
+                    self.imageSettable?.image = image
                 }
             }
         }

+ 26 - 4
Tests/KingfisherTests/DataReceivingSideEffectTests.swift

@@ -29,18 +29,40 @@ import XCTest
 
 class DataReceivingSideEffectTests: XCTestCase {
 
+    var manager: KingfisherManager!
+
+    override class func setUp() {
+        super.setUp()
+        LSNocilla.sharedInstance().start()
+    }
+
+    override class func tearDown() {
+        LSNocilla.sharedInstance().stop()
+        super.tearDown()
+    }
+
     override func setUp() {
+        super.setUp()
         // Put setup code here. This method is called before the invocation of each test method in the class.
+        let uuid = UUID()
+        let downloader = ImageDownloader(name: "test.manager.\(uuid.uuidString)")
+        let cache = ImageCache(name: "test.cache.\(uuid.uuidString)")
+
+        manager = KingfisherManager(downloader: downloader, cache: cache)
     }
 
     override func tearDown() {
-        // Put teardown code here. This method is called after the invocation of each test method in the class.
+        LSNocilla.sharedInstance().clearStubs()
+        clearCaches([manager.cache])
+        cleanDefaultCache()
+        manager = nil
+        super.tearDown()
     }
 
     func testDataReceivingSideEffectBlockCanBeCalled() {
         let exp = expectation(description: #function)
         let url = testURLs[0]
-        stub(url, data: testImageData)
+        stub(url, data: testImageData, length: 123)
 
         let receiver = DataReceivingStub()
 
@@ -56,7 +78,7 @@ class DataReceivingSideEffectTests: XCTestCase {
     func testDataReceivingSideEffectBlockCanBeCalledButNotApply() {
         let exp = expectation(description: #function)
         let url = testURLs[0]
-        stub(url, data: testImageData)
+        stub(url, data: testImageData, length: 123)
 
         let receiver = DataReceivingNotAppyStub()
 
@@ -75,7 +97,7 @@ class DataReceivingStub: DataReceivingSideEffect {
     var called: Bool = false
     var onShouldApply: () -> Bool = { return true }
     func onDataReceived(_ session: URLSession, task: SessionDataTask, data: Data) {
-        called = true
+        self.called = true
     }
 }