From a2f760c7bebbec253bf7a921715c2d270307d57e Mon Sep 17 00:00:00 2001 From: DreamPiggy Date: Tue, 23 Jan 2018 20:45:31 +0800 Subject: [PATCH] Pass the context arg from the top level to the bottom level to allow specify logic in the future --- SDWebImage/SDImageCache.h | 12 ++++++++++++ SDWebImage/SDImageCache.m | 8 ++++++-- SDWebImage/SDWebImageDownloader.h | 22 ++++++++++++++++++++++ SDWebImage/SDWebImageDownloader.m | 7 ++++++- SDWebImage/SDWebImageDownloaderOperation.h | 14 +++++++++++--- SDWebImage/SDWebImageDownloaderOperation.m | 2 ++ SDWebImage/SDWebImageManager.h | 18 ++++++++++++++++++ SDWebImage/SDWebImageManager.m | 17 +++++++++++------ SDWebImage/UIView+WebCache.m | 2 +- 9 files changed, 89 insertions(+), 13 deletions(-) diff --git a/SDWebImage/SDImageCache.h b/SDWebImage/SDImageCache.h index cce20261..17ec5af4 100644 --- a/SDWebImage/SDImageCache.h +++ b/SDWebImage/SDImageCache.h @@ -204,6 +204,18 @@ typedef void(^SDWebImageCompletionWithPossibleErrorBlock)(NSError * _Nullable er */ - (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key options:(SDImageCacheOptions)options done:(nullable SDCacheQueryCompletedBlock)doneBlock; +/** + * Asynchronously queries the cache with operation and call the completion when done. + * + * @param key The unique key used to store the wanted image + * @param options A mask to specify options to use for this cache query + * @param doneBlock The completion block. Will not get called if the operation is cancelled + * @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. + * + * @return a NSOperation instance containing the cache op + */ +- (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key options:(SDImageCacheOptions)options done:(nullable SDCacheQueryCompletedBlock)doneBlock context:(nullable SDWebImageContext *)context; + /** * Synchronously query the memory cache. * diff --git a/SDWebImage/SDImageCache.m b/SDWebImage/SDImageCache.m index 4c027083..25e75c27 100644 --- a/SDWebImage/SDImageCache.m +++ b/SDWebImage/SDImageCache.m @@ -385,11 +385,15 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { return SDScaledImageForKey(key, image); } -- (NSOperation *)queryCacheOperationForKey:(NSString *)key done:(SDCacheQueryCompletedBlock)doneBlock { +- (nullable NSOperation *)queryCacheOperationForKey:(NSString *)key done:(SDCacheQueryCompletedBlock)doneBlock { return [self queryCacheOperationForKey:key options:0 done:doneBlock]; } -- (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key options:(SDImageCacheOptions)options done:(nullable SDCacheQueryCompletedBlock)doneBlock { +- (nullable NSOperation *)queryCacheOperationForKey:(NSString *)key options:(SDImageCacheOptions)options done:(SDCacheQueryCompletedBlock)doneBlock { + return [self queryCacheOperationForKey:key options:options done:doneBlock context:nil]; +} + +- (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key options:(SDImageCacheOptions)options done:(nullable SDCacheQueryCompletedBlock)doneBlock context:(nullable SDWebImageContext *)context { if (!key) { if (doneBlock) { doneBlock(nil, nil, SDImageCacheTypeNone); diff --git a/SDWebImage/SDWebImageDownloader.h b/SDWebImage/SDWebImageDownloader.h index 3f88a41d..b1d18aa6 100644 --- a/SDWebImage/SDWebImageDownloader.h +++ b/SDWebImage/SDWebImageDownloader.h @@ -227,6 +227,28 @@ typedef SDHTTPHeadersDictionary * _Nullable (^SDWebImageDownloaderHeadersFilterB progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock; +/** + * Creates a SDWebImageDownloader async downloader instance with a given URL + * + * The delegate will be informed when the image is finish downloaded or an error has happen. + * + * @see SDWebImageDownloaderDelegate + * + * @param url The URL to the image to download + * @param options The options to be used for this download + * @param progressBlock A block called repeatedly while the image is downloading + * @note the progress block is executed on a background queue + * @param completedBlock A block called once the download is completed. + * @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. + * + * @return A token (SDWebImageDownloadToken) that can be passed to -cancel: to cancel this operation + */ +- (nullable SDWebImageDownloadToken *)downloadImageWithURL:(nullable NSURL *)url + options:(SDWebImageDownloaderOptions)options + progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock + completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock + context:(nullable SDWebImageContext *)context; + /** * Cancels a download that was previously queued using -downloadImageWithURL:options:progress:completed: * diff --git a/SDWebImage/SDWebImageDownloader.m b/SDWebImage/SDWebImageDownloader.m index 12c66748..ec3837d0 100644 --- a/SDWebImage/SDWebImageDownloader.m +++ b/SDWebImage/SDWebImageDownloader.m @@ -174,10 +174,14 @@ } } +- (nullable SDWebImageDownloadToken *)downloadImageWithURL:(NSURL *)url options:(SDWebImageDownloaderOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageDownloaderCompletedBlock)completedBlock { + return [self downloadImageWithURL:url options:options progress:progressBlock completed:completedBlock context:nil]; +} + - (nullable SDWebImageDownloadToken *)downloadImageWithURL:(nullable NSURL *)url options:(SDWebImageDownloaderOptions)options progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock - completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock { + completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock context:(nullable SDWebImageContext *)context { __weak SDWebImageDownloader *wself = self; return [self addProgressCallback:progressBlock completedBlock:completedBlock forURL:url createCallback:^SDWebImageDownloaderOperation *{ @@ -203,6 +207,7 @@ } SDWebImageDownloaderOperation *operation = [[sself.operationClass alloc] initWithRequest:request inSession:sself.session options:options]; operation.shouldDecompressImages = sself.shouldDecompressImages; + operation.context = context; if (sself.urlCredential) { operation.credential = sself.urlCredential; diff --git a/SDWebImage/SDWebImageDownloaderOperation.h b/SDWebImage/SDWebImageDownloaderOperation.h index a21d02ea..32d116b0 100644 --- a/SDWebImage/SDWebImageDownloaderOperation.h +++ b/SDWebImage/SDWebImageDownloaderOperation.h @@ -36,6 +36,9 @@ FOUNDATION_EXPORT NSString * _Nonnull const SDWebImageDownloadFinishNotification - (nullable NSURLCredential *)credential; - (void)setCredential:(nullable NSURLCredential *)value; +- (nullable SDWebImageContext *)context; +- (void)setContext:(nullable SDWebImageContext *)context; + - (BOOL)cancel:(nullable id)token; @end @@ -67,19 +70,24 @@ FOUNDATION_EXPORT NSString * _Nonnull const SDWebImageDownloadFinishNotification @property (nonatomic, strong, nullable) NSURLCredential *credential; /** - * The SDWebImageDownloaderOptions for the receiver. + * The options for the receiver. */ @property (assign, nonatomic, readonly) SDWebImageDownloaderOptions options; +/** + * The context for the receiver. + */ +@property (copy, nonatomic, nullable) SDWebImageContext *context; + /** * The expected size of data. */ -@property (assign, nonatomic) NSInteger expectedSize; +@property (assign, nonatomic, readonly) NSInteger expectedSize; /** * The response returned by the operation's connection. */ -@property (strong, nonatomic, nullable) NSURLResponse *response; +@property (strong, nonatomic, nullable, readonly) NSURLResponse *response; /** * Initializes a `SDWebImageDownloaderOperation` object diff --git a/SDWebImage/SDWebImageDownloaderOperation.m b/SDWebImage/SDWebImageDownloaderOperation.m index cffb1a86..252d0f21 100644 --- a/SDWebImage/SDWebImageDownloaderOperation.m +++ b/SDWebImage/SDWebImageDownloaderOperation.m @@ -29,6 +29,8 @@ typedef NSMutableDictionary SDCallbacksDictionary; @property (assign, nonatomic, getter = isFinished) BOOL finished; @property (strong, nonatomic, nullable) NSMutableData *imageData; @property (copy, nonatomic, nullable) NSData *cachedData; +@property (assign, nonatomic, readwrite) NSInteger expectedSize; +@property (strong, nonatomic, nullable, readwrite) NSURLResponse *response; // This is weak because it is injected by whoever manages this session. If this gets nil-ed out, we won't be able to run // the task associated with this operation diff --git a/SDWebImage/SDWebImageManager.h b/SDWebImage/SDWebImageManager.h index 16bd05a2..42ee508f 100644 --- a/SDWebImage/SDWebImageManager.h +++ b/SDWebImage/SDWebImageManager.h @@ -241,6 +241,24 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager]; progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock completed:(nonnull SDInternalCompletionBlock)completedBlock; +/** + * Downloads the image at the given URL if not present in cache or return the cached version otherwise. + * + * @param url The URL to the image + * @param options A mask to specify options to use for this request + * @param progressBlock A block called while image is downloading + * @note the progress block is executed on a background queue + * @param completedBlock A block called when operation has been completed. + * @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold. + * + * @return Returns an NSObject conforming to SDWebImageOperation. Should be an instance of SDWebImageDownloaderOperation + */ +- (nullable id )loadImageWithURL:(nullable NSURL *)url + options:(SDWebImageOptions)options + progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock + completed:(nonnull SDInternalCompletionBlock)completedBlock + context:(nullable SDWebImageContext *)context; + /** * Saves image to cache for given URL * diff --git a/SDWebImage/SDWebImageManager.m b/SDWebImage/SDWebImageManager.m index 92b29826..90643930 100644 --- a/SDWebImage/SDWebImageManager.m +++ b/SDWebImage/SDWebImageManager.m @@ -107,10 +107,15 @@ }]; } -- (id )loadImageWithURL:(nullable NSURL *)url - options:(SDWebImageOptions)options - progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock - completed:(nonnull SDInternalCompletionBlock)completedBlock { +- (id)loadImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDInternalCompletionBlock)completedBlock { + return [self loadImageWithURL:url options:options progress:progressBlock completed:completedBlock context:nil]; +} + +- (id)loadImageWithURL:(nullable NSURL *)url + options:(SDWebImageOptions)options + progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock + completed:(nonnull SDInternalCompletionBlock)completedBlock + context:(nullable SDWebImageContext *)context { // Invoking this method without a completedBlock is pointless NSAssert(completedBlock != nil, @"If you mean to prefetch the image, use -[SDWebImagePrefetcher prefetchURLs] instead"); @@ -250,7 +255,7 @@ if (finished) { [self safelyRemoveOperationFromRunning:strongSubOperation]; } - }]; + } context:context]; } else if (cachedImage) { [self callCompletionBlockForOperation:strongOperation completion:completedBlock image:cachedImage data:cachedData error:nil cacheType:cacheType finished:YES url:url]; [self safelyRemoveOperationFromRunning:strongOperation]; @@ -259,7 +264,7 @@ [self callCompletionBlockForOperation:strongOperation completion:completedBlock image:nil data:nil error:nil cacheType:SDImageCacheTypeNone finished:YES url:url]; [self safelyRemoveOperationFromRunning:strongOperation]; } - }]; + } context:context]; return operation; } diff --git a/SDWebImage/UIView+WebCache.m b/SDWebImage/UIView+WebCache.m index 613a5cd5..8461a65d 100644 --- a/SDWebImage/UIView+WebCache.m +++ b/SDWebImage/UIView+WebCache.m @@ -161,7 +161,7 @@ static char TAG_ACTIVITY_SHOW; callCompletedBlockClojure(); }); } - }]; + } context:context]; [self sd_setImageLoadOperation:operation forKey:validOperationKey]; } else { dispatch_main_async_safe(^{