I'm using SDWebImage
to cache images in my app, however I recently ran into a problem where images that should be cached keep refreshing. Looking into it I found that the full image url from AWS is actually changing due to parameters tacked onto the end of the url. Every time I fetch the object that contains the image url, the image url returns with a dynamic "signature" and "expires" parameter (for security purposes). A different url so far as the image cache is concerned, but notice the same path to the image.
First fetch:
https://myapp.s3.amazonaws.com/path/image123.jpeg?AWSAccessKeyId=SOMEKEY&Signature=vrUFlMFEQ9fqQ%3D&Expires=1441702633
Fetch again 1 second later:
https://myapp.s3.amazonaws.com/path/image123.jpeg?AWSAccessKeyId=SOMEKEY&Signature=2mcMxUJLyJd7E%3D&Expires=1441703105
What's the best way to handle this situation? Sure would be awesome if SDWebImage
had an option to ignore query params beyond the path to the file.
iOS 14 || Swift 5
SDWebImageManager.shared.cacheKeyFilter = SDWebImageCacheKeyFilter { url in
var components = URLComponents(url: url, resolvingAgainstBaseURL: false)
components?.query = nil
print("SDWebImage Cache Key:", components?.url)
return components?.url?.absoluteString ?? ""
}
So configure SDWebImageManager
at launch & then whenever a url
is supplied, it will be stripped of all it's query parameters to generate a common cache key identifier for SDWebImage
cache logic to work properly again.
So something like:
https://bucket.s3.us-east-1.amazonaws.com/public/someAsset.ext?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=TILT&X-Amz-Date=20210602T113954Z&X-Amz-Expires=17999&X-Amz-SignedHeaders=host&X-Amz-Security-Token=TILT&X-Amz-Signature=TILT
will have the cache key:
https://bucket.s3.us-east-1.amazonaws.com/public/someAsset.ext
NOTE: Pay attention to the final url. If the url is dependent on its query parameters for a dynamic output then obviously you will need to modify the logic in SDWebImageCacheKeyFilter
to fit your requirement.
SDWebImage has a method that allows for using a custom key, which helps in this case as AWS changes the query every time it's called.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
SDWebImageManager.sharedManager.cacheKeyFilter = ^(NSURL *url) {
url = [[NSURL alloc] initWithScheme:url.scheme host:url.host path:url.path];
return [url absoluteString];
};
// Your app init code...
return YES;
}
For more reading: SDWebImage | Using the cache key filter
@John 's answer is very good, but I met sometimes crashed.
below is more stable version.
SDWebImageManager.sharedManager.cacheKeyFilter = ^(NSURL *url) {
if( [[url absoluteString] isEqualToString:@""] ){
return @"";
}
url = [[NSURL alloc] initWithScheme:url.scheme host:url.host path:url.path];
return [url absoluteString];
};
This additional code checks if url is valid. [[NSURL alloc] initWithString:@""]
or something like this makes crashes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With