Sdwebimage: A second call to SDWebImage.shared().loadImage never returns GIFs as Data.

Created on 8 Nov 2018  路  2Comments  路  Source: SDWebImage/SDWebImage

New Issue Checklist

Issue Info

Info | Value |
-------------------------|-------------------------------------|
Platform Name | ios
Platform Version | 11.0 / 12.1
SDWebImage Version | 4.4.2
Integration Method | cocoapods
Xcode Version | Xcode 10
Repro rate | all the time (100%)
Repro with our demo prj | doesn't apply
Demo project link | private project. Will try to figure out to share the code upon request.

Issue Description and Steps

Sorry for convoluted title. I couldn't think of a better way to describe this. I will explain the issue here.

In my project, I download some GIFs and and display them using the following piece of code:

downloadOperation = SDWebImageManager.shared().loadImage(with: url, options: [.allowInvalidSSLCertificates, .retryFailed, .continueInBackground], progress: { (current, total, url) in
    self.updateProgressLabel(current: current, total: total)
}, completed: { (image, data, error, cacheType, completed, url) in
    /// Show the image using FLAnimatedImaged, show error if appropriate, etc.
    /// I receive the image as Data and not as an Image, which is expected and what I want.
})

And it works well. The gifs are downloaded and show properly in my app.

The problem arises when the user may want to save the GIFs to the camera roll.

Because I know that SDWebImage.shared().loadImage will use the cache by default, I attempt to "redownload" the image hoping to get it from cache:

SDWebImageManager.shared().loadImage(with: url, options: [], progress: nil, completed: { (image, data, error, _, _, _) in
    DispatchQueue.main.async {
        if let error = error {
            print("error: \(error)")
            completion(nil, error)
        } else {
            if let data = data {
                // For some reasons, only gifs seem to return this way. Static images just return as image.
                completion(data, nil)
            } else if let image = image {
                let jpg = image.jpegData(compressionQuality: 1.0)
                completion(jpg, nil)
            } else {
                completion(nil, nil)
            }
        }
    }
})

For whatever reason the moment I call loadImage the second time, the image no longer returns as data but rather as an image, so I cannot treat the image as a gif anymore.

This is happening on Version 4.4.2. But I downgraded the pod to version 4.2.3 and it works correctly on this version.

So as a TLDR:


    1. Call loadImage on a GIF URL. You will get Data and not UIImage which is correct and expect.


    1. Call loadImage for a second time on the same URL. You will get an UIImage and NOT a Data, which incorrect and unexpected.

usage

Most helpful comment

Thanks. I reinstalled 4.4.2 and gave it the SDWebImageQueryDataWhenInMemory option and it works as I intend it now.

All 2 comments

This is a designed behavior. We store the UIImage instance into the memory cache, the original downloaded NSData in disk cache. When a image is cached in memory, we will immediately retrieve it and callback without any disk cache query with NSData.

If you want to ensure always give me back the NSData with disk cache query, you should provide extra options. Using SDWebImageQueryDataWhenInMemory && SDWebImageQueryDiskSync options. See the documentation for the combination of these two options, which will cause little different behavior (sync or async, actually).

Thanks. I reinstalled 4.4.2 and gave it the SDWebImageQueryDataWhenInMemory option and it works as I intend it now.

Was this page helpful?
0 / 5 - 0 ratings