From 43cb5b2c7de946a666a7c6c2bb8dd7eb92b7239b Mon Sep 17 00:00:00 2001 From: Yang Chao Date: Sun, 18 Jun 2023 11:15:23 +0800 Subject: [PATCH 1/2] fix: always use specified processors to recreate animated image representation --- Sources/General/KingfisherManager.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/General/KingfisherManager.swift b/Sources/General/KingfisherManager.swift index b0b9db1da..45e166864 100644 --- a/Sources/General/KingfisherManager.swift +++ b/Sources/General/KingfisherManager.swift @@ -562,7 +562,7 @@ public class KingfisherManager { if image.kf.imageFrameCount != nil && image.kf.imageFrameCount != 1, let data = image.kf.animatedImageData { // Always recreate animated image representation since it is possible to be loaded in different options. // https://github.com/onevcat/Kingfisher/issues/1923 - image = KingfisherWrapper.animatedImage(data: data, options: options.imageCreatingOptions) ?? .init() + image = options.processor.process(item: .data(data), options: options) ?? .init() } if let modifier = options.imageModifier { image = modifier.modify(image) From 4fb16b203017bb18af91f780073927121622f15b Mon Sep 17 00:00:00 2001 From: Yang Chao Date: Sun, 18 Jun 2023 12:20:21 +0800 Subject: [PATCH 2/2] add test --- .../KingfisherManagerTests.swift | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/Tests/KingfisherTests/KingfisherManagerTests.swift b/Tests/KingfisherTests/KingfisherManagerTests.swift index 95e6093cc..afcd4709f 100644 --- a/Tests/KingfisherTests/KingfisherManagerTests.swift +++ b/Tests/KingfisherTests/KingfisherManagerTests.swift @@ -1186,6 +1186,35 @@ class KingfisherManagerTests: XCTestCase { waitForExpectations(timeout: 3, handler: nil) } + + // https://github.com/onevcat/Kingfisher/issues/1923 + func testAnimatedImageShouldRecreateFromCache() { + let exp = expectation(description: #function) + let url = testURLs[0] + let data = testImageGIFData + stub(url, data: data) + let p = SimpleProcessor() + manager.retrieveImage(with: url, options: [.processor(p), .onlyLoadFirstFrame]) { result in + XCTAssertTrue(p.processed) + XCTAssertTrue(result.value!.image.creatingOptions!.onlyFirstFrame) + p.processed = false + self.manager.retrieveImage(with: url, options: [.processor(p)]) { result in + XCTAssertTrue(p.processed) + XCTAssertFalse(result.value!.image.creatingOptions!.onlyFirstFrame) + exp.fulfill() + } + } + waitForExpectations(timeout: 3, handler: nil) + } +} + +private var imageCreatingOptionsKey: Void? + +extension KFCrossPlatformImage { + var creatingOptions: ImageCreatingOptions? { + get { return getAssociatedObject(self, &imageCreatingOptionsKey) } + set { setRetainedAssociatedObject(self, &imageCreatingOptionsKey, newValue) } + } } class SimpleProcessor: ImageProcessor { @@ -1208,7 +1237,10 @@ class SimpleProcessor: ImageProcessor { case .image(let image): return image case .data(let data): - return KingfisherWrapper.image(data: data, options: options.imageCreatingOptions) + let creatingOptions = options.imageCreatingOptions + let image = KingfisherWrapper.image(data: data, options: creatingOptions) + image?.creatingOptions = creatingOptions + return image } } }