Authored by DreamPiggy

Add cacheKeyFilter to allow user provide modified version of data when storing t…

…he disk cache in SDWebImageManager
@@ -122,7 +122,9 @@ typedef void(^SDExternalCompletionBlock)(UIImage * _Nullable image, NSError * _N @@ -122,7 +122,9 @@ typedef void(^SDExternalCompletionBlock)(UIImage * _Nullable image, NSError * _N
122 122
123 typedef void(^SDInternalCompletionBlock)(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL); 123 typedef void(^SDInternalCompletionBlock)(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL);
124 124
125 -typedef NSString * _Nullable (^SDWebImageCacheKeyFilterBlock)(NSURL * _Nullable url); 125 +typedef NSString * _Nullable(^SDWebImageCacheKeyFilterBlock)(NSURL * _Nullable url);
  126 +
  127 +typedef NSData * _Nullable(^SDWebImageCacheSerializerBlock)(UIImage * _Nonnull image, NSData * _Nullable data, NSURL * _Nullable imageURL);
126 128
127 129
128 @class SDWebImageManager; 130 @class SDWebImageManager;
@@ -193,16 +195,36 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager]; @@ -193,16 +195,36 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager];
193 * 195 *
194 * @code 196 * @code
195 197
196 -[[SDWebImageManager sharedManager] setCacheKeyFilter:^(NSURL *url) { 198 +SDWebImageManager.sharedManager.cacheKeyFilter = ^(NSURL * _Nullable url) {
197 url = [[NSURL alloc] initWithScheme:url.scheme host:url.host path:url.path]; 199 url = [[NSURL alloc] initWithScheme:url.scheme host:url.host path:url.path];
198 return [url absoluteString]; 200 return [url absoluteString];
199 -}]; 201 +};
200 202
201 * @endcode 203 * @endcode
202 */ 204 */
203 @property (nonatomic, copy, nullable) SDWebImageCacheKeyFilterBlock cacheKeyFilter; 205 @property (nonatomic, copy, nullable) SDWebImageCacheKeyFilterBlock cacheKeyFilter;
204 206
205 /** 207 /**
  208 + * The cache serializer is a block used to convert the decoded image, the source downloaded data, to the actual data used for storing to the disk cache. If you return nil, means to generate the data from the image instance, see `SDImageCache`.
  209 + * For example, if you are using WebP images and facing the slow decoding time issue when later retriving from disk cache again. You can try to encode the decoded image to JPEG/PNG format to disk cache instead of source downloaded data.
  210 + * @note The `image` arg is nonnull, but when you also provide a image transformer and the image is transformed, the `data` arg may be nil, take attention to this case.
  211 + * @note This method is called from a global queue in order to not to block the main thread.
  212 + * @code
  213 + SDWebImageManager.sharedManager.cacheKeyFilter = ^NSData * _Nullable(UIImage * _Nonnull image, NSData * _Nullable data, NSURL * _Nullable imageURL) {
  214 + SDImageFormat format = [NSData sd_imageFormatForImageData:data];
  215 + switch (format) {
  216 + case SDImageFormatWebP:
  217 + return image.images ? data : nil;
  218 + default:
  219 + return data;
  220 + }
  221 + };
  222 + * @endcode
  223 + * The default value is nil. Means we just store the source downloaded data to disk cache.
  224 + */
  225 +@property (nonatomic, copy, nullable) SDWebImageCacheSerializerBlock cacheSerializer;
  226 +
  227 +/**
206 * Returns global SDWebImageManager instance. 228 * Returns global SDWebImageManager instance.
207 * 229 *
208 * @return SDWebImageManager shared instance 230 * @return SDWebImageManager shared instance
@@ -232,16 +232,29 @@ @@ -232,16 +232,29 @@
232 232
233 if (transformedImage && finished) { 233 if (transformedImage && finished) {
234 BOOL imageWasTransformed = ![transformedImage isEqual:downloadedImage]; 234 BOOL imageWasTransformed = ![transformedImage isEqual:downloadedImage];
  235 + NSData *cacheData;
235 // pass nil if the image was transformed, so we can recalculate the data from the image 236 // pass nil if the image was transformed, so we can recalculate the data from the image
236 - [self.imageCache storeImage:transformedImage imageData:(imageWasTransformed ? nil : downloadedData) forKey:key toDisk:cacheOnDisk completion:nil]; 237 + if (self.cacheSerializer) {
  238 + cacheData = self.cacheSerializer(transformedImage, (imageWasTransformed ? nil : downloadedData), url);
  239 + } else {
  240 + cacheData = (imageWasTransformed ? nil : downloadedData);
  241 + }
  242 + [self.imageCache storeImage:transformedImage imageData:cacheData forKey:key toDisk:cacheOnDisk completion:nil];
237 } 243 }
238 244
239 [self callCompletionBlockForOperation:strongSubOperation completion:completedBlock image:transformedImage data:downloadedData error:nil cacheType:SDImageCacheTypeNone finished:finished url:url]; 245 [self callCompletionBlockForOperation:strongSubOperation completion:completedBlock image:transformedImage data:downloadedData error:nil cacheType:SDImageCacheTypeNone finished:finished url:url];
240 }); 246 });
241 } else { 247 } else {
242 if (downloadedImage && finished) { 248 if (downloadedImage && finished) {
  249 + if (self.cacheSerializer) {
  250 + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
  251 + NSData *cacheData = self.cacheSerializer(downloadedImage, downloadedData, url);
  252 + [self.imageCache storeImage:downloadedImage imageData:cacheData forKey:key toDisk:cacheOnDisk completion:nil];
  253 + });
  254 + } else {
243 [self.imageCache storeImage:downloadedImage imageData:downloadedData forKey:key toDisk:cacheOnDisk completion:nil]; 255 [self.imageCache storeImage:downloadedImage imageData:downloadedData forKey:key toDisk:cacheOnDisk completion:nil];
244 } 256 }
  257 + }
245 [self callCompletionBlockForOperation:strongSubOperation completion:completedBlock image:downloadedImage data:downloadedData error:nil cacheType:SDImageCacheTypeNone finished:finished url:url]; 258 [self callCompletionBlockForOperation:strongSubOperation completion:completedBlock image:downloadedImage data:downloadedData error:nil cacheType:SDImageCacheTypeNone finished:finished url:url];
246 } 259 }
247 } 260 }