Sdwebimage: Images were not downloading for static URL's

Created on 7 Nov 2014  Â·  26Comments  Â·  Source: SDWebImage/SDWebImage

Hi,

In my app,User having profile page with photo and the user details, here with using SDWebImage framework ,download and cache the image its working perfectly.The user has an option to change profile photo, when user changes the pic, I was posting the updated image to server .When the user come back to the profile page ,the framework not downloading the updated image showing the previous image.The issue was back end people providing the static Url's but with updated content ,so I used SDWebImageRefreshCached, for refresh but no use.Please can you sort of this issue?.Thank you very much.

NSURLCache bug

Most helpful comment

@sourcebits-mahesh @tbrknt
go to SDWebImageManager.m file inside the downloadImageWithURL method from line 176 and change this

            if (image && options & SDWebImageRefreshCached) {
                // force progressive off if image already cached but forced refreshing
                downloaderOptions &= ~SDWebImageDownloaderProgressiveDownload;
                // ignore image read from NSURLCache if image if cached but force refreshing
                downloaderOptions |= SDWebImageDownloaderIgnoreCachedResponse;
            }

to this:

            if (image && options & SDWebImageRefreshCached) {
                // force progressive off if image already cached but forced refreshing
                downloaderOptions &= ~SDWebImageDownloaderProgressiveDownload;
                // remove SDWebImageDownloaderUseNSURLCache flag
                downloaderOptions &= ~SDWebImageDownloaderUseNSURLCache;
                // ignore image read from NSURLCache if image is cached but force refreshing
                downloaderOptions |= SDWebImageDownloaderIgnoreCachedResponse;
            }

i tried it and i got it working.
let me know how it turns out

All 26 comments

Did you try to give the parameter mentioned in here: https://github.com/rs/SDWebImage#handle-image-refresh? That is, calling _setImageWithURL: placeholderImage:_ with also the parameter/argument _options:SDWebImageRefreshCached_.

Even though you give that option, does it still load the previous image?

Yes, even though I used the option,its loading the previous image.

@sourcebits-mahesh @tbrknt
go to SDWebImageManager.m file inside the downloadImageWithURL method from line 176 and change this

            if (image && options & SDWebImageRefreshCached) {
                // force progressive off if image already cached but forced refreshing
                downloaderOptions &= ~SDWebImageDownloaderProgressiveDownload;
                // ignore image read from NSURLCache if image if cached but force refreshing
                downloaderOptions |= SDWebImageDownloaderIgnoreCachedResponse;
            }

to this:

            if (image && options & SDWebImageRefreshCached) {
                // force progressive off if image already cached but forced refreshing
                downloaderOptions &= ~SDWebImageDownloaderProgressiveDownload;
                // remove SDWebImageDownloaderUseNSURLCache flag
                downloaderOptions &= ~SDWebImageDownloaderUseNSURLCache;
                // ignore image read from NSURLCache if image is cached but force refreshing
                downloaderOptions |= SDWebImageDownloaderIgnoreCachedResponse;
            }

i tried it and i got it working.
let me know how it turns out

Thank you ,its working fine.Can you explain a bit what you added?

On Mon, Nov 10, 2014 at 2:45 PM, Konstantinos K. [email protected]
wrote:

@tbrknt https://github.com/tbrknt
go to SDWebImageManager.m file inside the downloadImageWithURL method and
change this

        if (image && options & SDWebImageRefreshCached) {
            // force progressive off if image already cached but forced refreshing
            downloaderOptions &= ~SDWebImageDownloaderProgressiveDownload;
            // ignore image read from NSURLCache if image if cached but force refreshing
            downloaderOptions |= SDWebImageDownloaderIgnoreCachedResponse;
        }

to this:

        if (image && options & SDWebImageRefreshCached) {
            // force progressive off if image already cached but forced refreshing
            downloaderOptions &= ~SDWebImageDownloaderProgressiveDownload;
            // remove SDWebImageDownloaderUseNSURLCache flag
            downloaderOptions &= ~SDWebImageDownloaderUseNSURLCache;
            // ignore image read from NSURLCache if image if cached but force refreshing
            downloaderOptions |= SDWebImageDownloaderIgnoreCachedResponse;
        }

i tried it and i got it working.
let me know how it turns out

—
Reply to this email directly or view it on GitHub
https://github.com/rs/SDWebImage/issues/951#issuecomment-62358369.

@sourcebits-mahesh
what i did is add this

                // remove SDWebImageDownloaderUseNSURLCache flag
                downloaderOptions &= ~SDWebImageDownloaderUseNSURLCache;

this removes the SDWebImageDownloaderUseNSURLCache option only when the user has enabled the SDWebImageRefreshCached flag

Thank you , but I am every time enabling the SDWebImageRefreshCached flag,so
how it going to work in my case.

On Mon, Nov 10, 2014 at 6:05 PM, Konstantinos K. [email protected]
wrote:

@sourcebits-mahesh https://github.com/sourcebits-mahesh
what i did is add this

            // remove SDWebImageDownloaderUseNSURLCache flag
            downloaderOptions &= ~SDWebImageDownloaderUseNSURLCache;

this removes the SDWebImageDownloaderUseNSURLCache option only when the
user has enabled the SDWebImageRefreshCached flag

—
Reply to this email directly or view it on GitHub
https://github.com/rs/SDWebImage/issues/951#issuecomment-62378404.

@sourcebits-mahesh
based on my understanding, SDWebImageRefreshCached flag is used to get images from urls that you know they might change, e.g like avatars. i do not know if thats a good idea to force refresh for all images.

i also have read about this option NSURLRequestReloadRevalidatingCacheData that actually revalidates the cached image. According to Apple's documentation:

Specifies that the existing cache data may be used provided the origin source confirms its validity,
otherwise the URL is loaded from the origin source *Unimplemented*

Logically, this would mean that the request would respect the cache-control & expiration header for that image and either use the cached one or load from the origin source.

I'm having a similar problem. I am indeed using an URL that does not change but the image change. Not sure when exactly the bug started occuring. Either way, if I check my network trace, I clearly see the request being done to the server and new photo returning.

My request looks like:
[self.profilePicture sd_setImageWithURL:profileImageURL placeholderImage:[UIImage imageNamed:@"default_friend"] options:SDWebImageHandleCookies | SDWebImageRefreshCached];

If I a completed block, I can see that the cache type is of SDImageCacheTypeDisk.

I tried with the solution above and it does not seem to work. The images are loaded at two different places in the app and they both do that. They are both in a UITableViewCell.

Will investigate a bit more.

@GabrielCartier any updates on this? does this still happen on your side?

Haven't got the chance to check it and the project has changed since then. I'll see if I can validate that it works with an updated version.

Anyhow, thanks!

@mythodeia i am facing the same exact problem as @GabrielCartier

@rokridi are you using the SDWebImageRefreshCached option?

@mythodeia yes i am using SDWebImageRefreshCached option.

@rokridi
i used the demo project. removed all example files and added 1 image i uploaded to my server.
on the detailsviewcontroller i added the refreshcached property like this:

        [self.imageView sd_setImageWithURL:self.imageURL
                          placeholderImage:nil
                                   options:SDWebImageProgressiveDownload|SDWebImageRefreshCached
                                  progress:^(NSInteger receivedSize, NSInteger expectedSize) {
                                      if (!activityIndicator) {
                                          [weakImageView addSubview:activityIndicator = [UIActivityIndicatorView.alloc initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]];
                                          activityIndicator.center = weakImageView.center;
                                          [activityIndicator startAnimating];
                                      }
                                  }
                                 completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
                                     [activityIndicator removeFromSuperview];
                                     activityIndicator = nil;
                                 }];

Then i opened the simulator and run the project, tapped the 1st cell to see the details view.
Then i uploaded a new image with the same name as the previous one and replaced the old one online.
I hit back on the nav bar and again tapped on the 1st cell. The new image loaded successfully.

@mythodeia i have checked again and it is working now. Sometimes, the image (with static url) is not refreshed even when using SDWebImageRefreshCached. The cache returns the cached image and then i wait for the download of the new image but i get the old one (may be its is related to backend). I will investigate till i recognize the exact scenario to reproduce this systematically. Thanks for help.

I'm also having this problem. I'm using SDWebImageRefreshCached but I'm not getting the updated image from the server.

is it possible to remove the SDWebImageDownloaderUseNSURLCache option without changing something in SDWebImage? I'm using cocoapods and do not want to make changes to any of the code in the pods.

Also, is there a reason mythodeia's fix hasn't been included? Surely, that how it should be if you use SDWebImageRefreshCached?

@andreaslindahl you can set 0 as options or another value, instead of the UseNSURLCache one.

Closed, based on the comment from @mythodeia

In some cases images are stored to "NSURLCache sharedCache" and it causes problems. To empy it -> call [[NSURLCache sharedURLCache] removeAllCachedResponses]

@mythodeia i had the same issue and adding this
if (image && options & SDWebImageRefreshCached) { // force progressive off if image already cached but forced refreshing downloaderOptions &= ~SDWebImageDownloaderProgressiveDownload; // remove SDWebImageDownloaderUseNSURLCache flag downloaderOptions &= ~SDWebImageDownloaderUseNSURLCache; // ignore image read from NSURLCache if image is cached but force refreshing downloaderOptions |= SDWebImageDownloaderIgnoreCachedResponse; }

didn't do any trick can you help me out please

@nitishmakhija can you replicate it in the demo project?

@mythodeia sure
[self.profilePictureButton sd_setBackgroundImageWithURL:[NSURL URLWithString:imagePath] forState:UIControlStateNormal placeholderImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"placeholder" ofType:@"png"]] options:SDWebImageRefreshCached];

i am doing something like this in my controller, but for some reason i am not getting the updated image i tried this method also
- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock;
Completion block:
typedef void(^SDWebImageCompletionBlock)(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL);
in the completion block i get the same image and the SDImageCacheType = SDImageCacheTypeDisk

I see the same issues as mentioned by others:
Even if specifying SDWebImageRefreshCached, the images are not refreshed even when they have been updated on the backend servers. There are no requests sent to the server to check if the images have actually been updated or not. This was the behaviour in previously projects where we also have used SDWebImage if I remember it correctly.

Previously in this thread, there are suggestions to add a line of code to the method downloadImageWithURL:options:progress:completed.

//remove SDWebImageDownloaderUseNSURLCache flag
downloaderOptions &= ~SDWebImageDownloaderUseNSURLCache;

This seems to cause the images to be refreshed from the server backend, without checking if they have actually been updated or not.

Could it be changes to iOS that cause these problems when it comes to refreshing images based on the date they were updated in the backend?

this is still happening to me

Was this page helpful?
0 / 5 - 0 ratings