Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fade transition still occurs when cache is used with downsampling enabled #2226

Open
3 tasks done
bohdany-cricut opened this issue Mar 25, 2024 · 1 comment
Open
3 tasks done

Comments

@bohdany-cricut
Copy link

bohdany-cricut commented Mar 25, 2024

Check List

Issue Description

What

The documentation for the fade transition says that

The transition will not happen when the image is retrieved from either memory or disk cache by default

But in one particular case it seems to still being applied - when it's used with downsampling.
I noticed that my snapshot tests started to fail after I added downsampling to the KFImage I use. Upon closer look, it turned out to be that images now don't appear instantly but with a slight delay and a fade transition animation.
Here's the image setup:

KFImage
  .url(url)
  .downsampling(size: customSize)
  .fade(duration: 0.2)

And here is the cache setup:

func setup() {
    let cache = ImageCache(name: name)

    imagesToCache.forEach { (image, url) in
        let data = image.loadFromResources(.png)
        cache.store(.init(data: data)!, forKey: url, options: .init(nil))
    }

    KingfisherManager.shared.defaultOptions = [
        .onlyFromCache,
        .targetCache(cache),
    ]
}

Reproduce

Use KFImage with fade and downsampling applied along with cache being set up.
Upon retrieval images from the cache fade transition is still being applied.

Other Comment

I did try using .cacheOriginalImage but it did not make any difference.

@CraigSiemens
Copy link

CraigSiemens commented Jul 26, 2024

I just ran into this as well.

It appears to be caused in KingfisherManager.retrieveImageFromCache

  • looks for a cached processed image and fails
  • then looks for the original image and succeeds
  • then processes the image
  • stores the processed image in the cache
  • returns the cacheType as .none since the processed image was missing from the cache

It fails to find the processed image since kingfisher appends the processor identifier to the cache key when saving and restoring.

This is probably expected behaviour since the final image wasn't found in the cache so retrieving it could take long enough that the fade is needed.


My current workaround is to make a MockImageCache for use in the tests, which always discards the options when retrieving an image since the options are used to modify the cache key.

The one downside with this approach is it'll bypass running any processor on the image, so your snapshots wont accurately test whether the correct processor is being used.

private final class MockImageCache: ImageCache {
    override func imageCachedType(
        forKey key: String,
        processorIdentifier identifier: String = DefaultImageProcessor.default.identifier
    ) -> CacheType {
        .memory
    }
    
    override func retrieveImage(
        forKey key: String,
        options: KingfisherParsedOptionsInfo,
        callbackQueue: CallbackQueue = .mainCurrentOrAsync,
        completionHandler: ((Result<ImageCacheResult, KingfisherError>) -> Void)?
    ) {
        var options = options
        options.processor = DefaultImageProcessor.default

        super.retrieveImage(
            forKey: key,
            options: options,
            callbackQueue: callbackQueue,
            completionHandler: completionHandler
        )
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants