Explorar el Código

Extract image task and identifier to setter

onevcat hace 1 año
padre
commit
ebe47431bc
Se han modificado 1 ficheros con 37 adiciones y 20 borrados
  1. 37 20
      Sources/Extensions/HasImageComponent+Kingfisher.swift

+ 37 - 20
Sources/Extensions/HasImageComponent+Kingfisher.swift

@@ -92,6 +92,12 @@ struct ImagePropertyAccessor<ImageType>: Sendable {
     let getImage: @Sendable @MainActor () -> ImageType?
 }
 
+struct TaskPropertyAccessor<TaskIdentifierKey>: Sendable {
+    let setTaskIdentifier: @Sendable @MainActor (TaskIdentifierKey?, Source.Identifier.Value?) -> Void
+    let getTaskIdentifier: @Sendable @MainActor (TaskIdentifierKey?) -> Source.Identifier.Value?
+    let setTask: @Sendable @MainActor (DownloadTask?) -> Void
+}
+
 @MainActor
 extension KingfisherWrapper where Base: KingfisherImageSettable {
 
@@ -360,6 +366,19 @@ extension KingfisherWrapper where Base: KingfisherImageSettable {
                 setImage: { base.setImage($0, options: $1) },
                 getImage: { base.getImage() }
             ),
+            taskAccessor: TaskPropertyAccessor<Void>(
+                setTaskIdentifier: { _, value in
+                    var mutatingSelf = self
+                    mutatingSelf.taskIdentifier = value
+                },
+                getTaskIdentifier: { _ in
+                    self.taskIdentifier
+                }, 
+                setTask: { task in
+                    var mutatingSelf = self
+                    mutatingSelf.imageTask = task
+                }
+            ),
             placeholder: placeholder,
             parsedOptions: parsedOptions,
             progressBlock: progressBlock,
@@ -370,19 +389,19 @@ extension KingfisherWrapper where Base: KingfisherImageSettable {
 
 @MainActor
 extension KingfisherWrapper {
-    func setImage(
+    func setImage<TaskIdentifierKey>(
         with source: Source?,
         imageAccessor: ImagePropertyAccessor<KFCrossPlatformImage>,
+        taskAccessor: TaskPropertyAccessor<TaskIdentifierKey>,
         placeholder: KFCrossPlatformImage? = nil,
         parsedOptions: KingfisherParsedOptionsInfo,
         progressBlock: DownloadProgressBlock? = nil,
         completionHandler: (@MainActor @Sendable (Result<RetrieveImageResult, KingfisherError>) -> Void)? = nil
     ) -> DownloadTask?
     {
-        var mutatingSelf = self
         guard let source = source else {
             imageAccessor.setImage(placeholder, parsedOptions)
-            mutatingSelf.taskIdentifier = nil
+            taskAccessor.setTaskIdentifier(nil, nil)
             completionHandler?(.failure(KingfisherError.imageSettingError(reason: .emptySource)))
             return nil
         }
@@ -400,7 +419,7 @@ extension KingfisherWrapper {
         }
 
         let issuedIdentifier = Source.Identifier.next()
-        mutatingSelf.taskIdentifier = issuedIdentifier
+        taskAccessor.setTaskIdentifier(nil, issuedIdentifier)
 
         if let block = progressBlock {
             options.onDataReceived = (options.onDataReceived ?? []) + [ImageLoadingProgressSideEffect(block)]
@@ -410,13 +429,13 @@ extension KingfisherWrapper {
             with: source,
             options: options,
             downloadTaskUpdated: { task in
-                Task { @MainActor in mutatingSelf.imageTask = task }
+                Task { @MainActor in taskAccessor.setTask(task) }
             },
             progressiveImageSetter: { imageAccessor.setImage($0, options) },
-            referenceTaskIdentifierChecker: { issuedIdentifier == self.taskIdentifier },
+            referenceTaskIdentifierChecker: { issuedIdentifier == taskAccessor.getTaskIdentifier(nil) },
             completionHandler: { result in
                 CallbackQueueMain.currentOrAsync {
-                    guard issuedIdentifier == self.taskIdentifier else {
+                    guard issuedIdentifier == taskAccessor.getTaskIdentifier(nil) else {
                         let reason: KingfisherError.ImageSettingErrorReason
                         do {
                             let value = try result.get()
@@ -429,8 +448,8 @@ extension KingfisherWrapper {
                         return
                     }
 
-                    mutatingSelf.imageTask = nil
-                    mutatingSelf.taskIdentifier = nil
+                    taskAccessor.setTask(nil)
+                    taskAccessor.setTaskIdentifier(nil, nil)
 
                     switch result {
                     case .success(let value):
@@ -444,18 +463,9 @@ extension KingfisherWrapper {
                 }
             }
         )
-        mutatingSelf.imageTask = task
+        taskAccessor.setTask(task)
         return task
     }
-
-    // MARK: Cancelling Downloading Task
-
-    /// Cancels the image download task of the image view if it is running.
-    ///
-    /// Nothing will happen if the downloading has already finished.
-    public func cancelDownloadTask() {
-        imageTask?.cancel()
-    }
 }
 
 // MARK: - Associated Object
@@ -463,7 +473,7 @@ extension KingfisherWrapper {
 @MainActor private var imageTaskKey: Void?
 
 @MainActor
-extension KingfisherWrapper {
+extension KingfisherWrapper where Base: KingfisherImageSettable {
 
     // MARK: Properties
     public private(set) var taskIdentifier: Source.Identifier.Value? {
@@ -481,4 +491,11 @@ extension KingfisherWrapper {
         get { return getAssociatedObject(base, &imageTaskKey) }
         set { setRetainedAssociatedObject(base, &imageTaskKey, newValue)}
     }
+    
+    /// Cancels the image download task of the image view if it is running.
+    ///
+    /// Nothing will happen if the downloading has already finished.
+    public func cancelDownloadTask() {
+        imageTask?.cancel()
+    }
 }