diff --git a/Sources/Nuke/Internal/ImageRequestKeys.swift b/Sources/Nuke/Internal/ImageRequestKeys.swift index 40f44cd9a..cf12e1e53 100644 --- a/Sources/Nuke/Internal/ImageRequestKeys.swift +++ b/Sources/Nuke/Internal/ImageRequestKeys.swift @@ -40,23 +40,26 @@ extension ImageRequest { final class CacheKey: Hashable, Sendable { // Using a reference type turned out to be significantly faster private let imageId: String? + private let scale: Float private let thumbnail: ImageRequest.ThumbnailOptions? private let processors: [any ImageProcessing] init(_ request: ImageRequest) { self.imageId = request.preferredImageId + self.scale = request.scale ?? 1 self.thumbnail = request.thumbnail self.processors = request.processors } func hash(into hasher: inout Hasher) { hasher.combine(imageId) + hasher.combine(scale) hasher.combine(thumbnail) hasher.combine(processors.count) } static func == (lhs: CacheKey, rhs: CacheKey) -> Bool { - lhs.imageId == rhs.imageId && lhs.thumbnail == rhs.thumbnail && lhs.processors == rhs.processors + lhs.imageId == rhs.imageId && lhs.scale == rhs.scale && lhs.thumbnail == rhs.thumbnail && lhs.processors == rhs.processors } } @@ -86,10 +89,12 @@ final class ImageLoadKey: Hashable, Sendable { /// Uniquely identifies a task of retrieving the decoded image. struct DecodedImageLoadKey: Hashable { let dataLoadKey: DataLoadKey + let scale: Float let thumbnail: ImageRequest.ThumbnailOptions? init(_ request: ImageRequest) { self.dataLoadKey = DataLoadKey(request) + self.scale = request.scale ?? 1 self.thumbnail = request.thumbnail } } diff --git a/Tests/NukeTests/ImagePipelineTests/ImagePipelineCoalescingTests.swift b/Tests/NukeTests/ImagePipelineTests/ImagePipelineCoalescingTests.swift index 09b6d76d5..4e3966f48 100644 --- a/Tests/NukeTests/ImagePipelineTests/ImagePipelineCoalescingTests.swift +++ b/Tests/NukeTests/ImagePipelineTests/ImagePipelineCoalescingTests.swift @@ -127,6 +127,34 @@ class ImagePipelineCoalescingTests: XCTestCase { } } + // MARK: - Scale + + func testOverridingImageScale() throws { + dataLoader.queue.isSuspended = true + + // GIVEN requests with the same URLs but one accesses thumbnail + let request1 = ImageRequest(url: Test.url, userInfo: [.scaleKey: 2]) + let request2 = ImageRequest(url: Test.url, userInfo: [.scaleKey: 3]) + + // WHEN loading images for those requests + expect(pipeline).toLoadImage(with: request1) { result in + // THEN + guard let image = result.value?.image else { return XCTFail() } + XCTAssertEqual(image.scale, 2) + } + expect(pipeline).toLoadImage(with: request2) { result in + // THEN + guard let image = result.value?.image else { return XCTFail() } + XCTAssertEqual(image.scale, 3) + } + + dataLoader.queue.isSuspended = false + + wait() + + XCTAssertEqual(self.dataLoader.createdTaskCount, 1) + } + // MARK: - Thumbnail func testDeduplicationGivenSameURLButDifferentThumbnailOptions() {