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

Allow providing a custom cache key which overrides the url in pin_setImage(from: URL?) #630

Open
MilesV64 opened this issue Apr 28, 2023 · 4 comments

Comments

@MilesV64
Copy link

My server sends lots of signed URLs which means the PIN cache downloads new images every time since the signed URL is slightly different. I'd like to use a custom key that I pass in, and then the library would only use the URL for downloading the image, not for use as the cache key.

It could look like this:

// The latest signed url from my server
let myURL = self.imageURL 

// A string uniquing the image; if this changes then it means the image changed. 
// Otherwise it's the same image but could be a different URL due to signed URLs.
let id = self.imageID

// CacheKey would be optional so current library behavior is unchanged
// The library would then use the given id as the cache key, only using `myURL` if it needs to be downloaded
self.imageView.pin_setImage(from: myURL, cacheKey: id) 

Would this be possible? Is there any other way to get around handling lots of signed URLs without redownloading every time?

@garrettmoon
Copy link
Collaborator

Can you override imageFromCacheWithCacheKey?

/**
Returns the cacheKey for a given URL and processorKey. Exposed to be overridden if necessary or to be used with imageFromCacheWithCacheKey
@see imageFromCacheWithCacheKey:completion:
@param url NSURL that was used to download image
@param processorKey An optional key to uniquely identify the processor used to post-process the downloaded image.
@return returns an NSString which is the key used for caching.
*/
- (nonnull NSString *)cacheKeyForURL:(nonnull NSURL *)url processorKey:(nullable NSString *)processorKey;

@MilesV64
Copy link
Author

Thank you for the reply, I think that should be enough to go on! I like the idea of setting the key at the same time as setting the URL because this override method requires additional state management/parsing of the URL (unless I'm missing a better way), but thank you for the suggestion.

To use this properly I would subclass PINRemoteImageManager correct? How would I then ensure that is being used instead of .shared() when calling pin_setImage() on a UIImageView?

@garrettmoon
Copy link
Collaborator

Yes, you'll need to override the class and then call setSharedImageManagerWithConfiguration: on the overridden class (since that method calls [self class] when instantiating the shared image manager, it'll correctly return your subclass when other places call PINRemoteImageManager.shared().

/**
Sets the shared instance of PINRemoteImageManager to an instance with the supplied configuration. If configuration is nil, [NSURLSessionConfiguration ephemeralSessionConfiguration] is used. You specify a custom configuration if you need to configure timeout values, cookie policies, additional HTTP headers, etc. This method should not be used if the shared instance has already been created.
@param configuration The configuration used to create the PINRemoteImageManager.
@note If you provide your own `sessionConfiguration`, please attention `HTTPMaximumConnectionsPerHost` property, it may causes timeout when in conjunction with `maxNumberOfConcurrentDownloads` if you set a larger number to `maxNumberOfConcurrentDownloads` but smaller number to `HTTPMaximumConnectionsPerHost`.
*/
+ (void)setSharedImageManagerWithConfiguration:(nullable NSURLSessionConfiguration *)configuration;

It's certainly not the most elegant solution and annoyingly has to be called before any parts of your code call the .shared() method, but it should work!

@MilesV64
Copy link
Author

Really appreciate the quick responses, thank you! I think this is enough for me to go on, I do think something like what I mentioned in the issue would be pretty slick in the future but this should work!

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

No branches or pull requests

2 participants