mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 06:35:51 +00:00
Addressing comments
This commit is contained in:
@@ -51,7 +51,7 @@ Pod::Spec.new do |spec|
|
|||||||
|
|
||||||
spec.subspec 'PINRemoteImage' do |pin|
|
spec.subspec 'PINRemoteImage' do |pin|
|
||||||
pin.xcconfig = { 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) PIN_REMOTE_IMAGE=1' }
|
pin.xcconfig = { 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) PIN_REMOTE_IMAGE=1' }
|
||||||
pin.dependency 'PINRemoteImage', '>= 2'
|
pin.dependency 'PINRemoteImage/iOS', '>= 2'
|
||||||
pin.dependency 'AsyncDisplayKit/ASDealloc2MainObject'
|
pin.dependency 'AsyncDisplayKit/ASDealloc2MainObject'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -48,8 +48,8 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
|
|||||||
{
|
{
|
||||||
@private
|
@private
|
||||||
// Core.
|
// Core.
|
||||||
id<ASImageCacheProtocol> _cache;
|
id<ASImageCacheProtocol, ASImageCacheProtocolDeprecated> _cache;
|
||||||
id<ASImageDownloaderProtocol> _downloader;
|
id<ASImageDownloaderProtocol, ASImageDownloaderProtocolDeprecated> _downloader;
|
||||||
|
|
||||||
__weak id<ASMultiplexImageNodeDelegate> _delegate;
|
__weak id<ASMultiplexImageNodeDelegate> _delegate;
|
||||||
struct {
|
struct {
|
||||||
@@ -85,7 +85,8 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
|
|||||||
BOOL _downloaderSupportsNewProtocol;
|
BOOL _downloaderSupportsNewProtocol;
|
||||||
BOOL _downloaderImplementsSetProgress;
|
BOOL _downloaderImplementsSetProgress;
|
||||||
BOOL _downloaderImplementsSetPriority;
|
BOOL _downloaderImplementsSetPriority;
|
||||||
BOOL _cacherSupportsNewProtocol;
|
BOOL _cacheSupportsNewProtocol;
|
||||||
|
BOOL _cacheSupportsClearing;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! @abstract Read-write redeclaration of property declared in ASMultiplexImageNode.h.
|
//! @abstract Read-write redeclaration of property declared in ASMultiplexImageNode.h.
|
||||||
@@ -156,13 +157,6 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
|
|||||||
*/
|
*/
|
||||||
- (void)_downloadImageWithIdentifier:(id)imageIdentifier URL:(NSURL *)imageURL completion:(void (^)(UIImage *image, NSError *error))completionBlock;
|
- (void)_downloadImageWithIdentifier:(id)imageIdentifier URL:(NSURL *)imageURL completion:(void (^)(UIImage *image, NSError *error))completionBlock;
|
||||||
|
|
||||||
/**
|
|
||||||
@abstract Returns a Boolean value indicating whether the downloaded image should be removed when clearing fetched data
|
|
||||||
@discussion Downloaded image data should only be cleared out if a cache is present
|
|
||||||
@return YES if an image cache is available; otherwise, NO.
|
|
||||||
*/
|
|
||||||
- (BOOL)_shouldClearFetchedImageData;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation ASMultiplexImageNode
|
@implementation ASMultiplexImageNode
|
||||||
@@ -176,16 +170,17 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
|
|||||||
_cache = cache;
|
_cache = cache;
|
||||||
_downloader = downloader;
|
_downloader = downloader;
|
||||||
|
|
||||||
NSAssert([downloader respondsToSelector:@selector(downloadImageWithURL:callbackQueue:downloadProgress:completion:)] || [downloader respondsToSelector:@selector(downloadImageWithURL:callbackQueue:downloadProgressBlock:completion:)], @"downloader must respond to either downloadImageWithURL:callbackQueue:downloadProgress:completion: or downloadImageWithURL:callbackQueue:downloadProgressBlock:completion:.");
|
ASDisplayNodeAssert([downloader respondsToSelector:@selector(downloadImageWithURL:callbackQueue:downloadProgress:completion:)] || [downloader respondsToSelector:@selector(downloadImageWithURL:callbackQueue:downloadProgressBlock:completion:)], @"downloader must respond to either downloadImageWithURL:callbackQueue:downloadProgress:completion: or downloadImageWithURL:callbackQueue:downloadProgressBlock:completion:.");
|
||||||
|
|
||||||
_downloaderSupportsNewProtocol = [downloader respondsToSelector:@selector(downloadImageWithURL:callbackQueue:downloadProgress:completion:)] ? YES : NO;
|
_downloaderSupportsNewProtocol = [downloader respondsToSelector:@selector(downloadImageWithURL:callbackQueue:downloadProgress:completion:)];
|
||||||
|
|
||||||
NSAssert(cache == nil || [cache respondsToSelector:@selector(cachedImageWithURL:callbackQueue:completion:)] || [cache respondsToSelector:@selector(fetchCachedImageWithURL:callbackQueue:completion:)], @"cacher must respond to either cachedImageWithURL:callbackQueue:completion: or fetchCachedImageWithURL:callbackQueue:completion:");
|
ASDisplayNodeAssert(cache == nil || [cache respondsToSelector:@selector(cachedImageWithURL:callbackQueue:completion:)] || [cache respondsToSelector:@selector(fetchCachedImageWithURL:callbackQueue:completion:)], @"cacher must respond to either cachedImageWithURL:callbackQueue:completion: or fetchCachedImageWithURL:callbackQueue:completion:");
|
||||||
|
|
||||||
_downloaderImplementsSetProgress = [downloader respondsToSelector:@selector(setProgressImageBlock:callbackQueue:withDownloadIdentifier:)] ? YES : NO;
|
_downloaderImplementsSetProgress = [downloader respondsToSelector:@selector(setProgressImageBlock:callbackQueue:withDownloadIdentifier:)];
|
||||||
_downloaderImplementsSetPriority = [downloader respondsToSelector:@selector(setPriority:withDownloadIdentifier:)] ? YES : NO;
|
_downloaderImplementsSetPriority = [downloader respondsToSelector:@selector(setPriority:withDownloadIdentifier:)];
|
||||||
|
|
||||||
_cacherSupportsNewProtocol = [cache respondsToSelector:@selector(cachedImageWithURL:callbackQueue:completion:)] ? YES : NO;
|
_cacheSupportsNewProtocol = [cache respondsToSelector:@selector(cachedImageWithURL:callbackQueue:completion:)];
|
||||||
|
_cacheSupportsClearing = [cache respondsToSelector:@selector(clearFetchedImageFromCacheWithURL:)];
|
||||||
|
|
||||||
self.shouldBypassEnsureDisplay = YES;
|
self.shouldBypassEnsureDisplay = YES;
|
||||||
|
|
||||||
@@ -220,16 +215,17 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
|
|||||||
{
|
{
|
||||||
[super clearFetchedData];
|
[super clearFetchedData];
|
||||||
|
|
||||||
if ([self _shouldClearFetchedImageData]) {
|
|
||||||
|
|
||||||
[_phImageRequestOperation cancel];
|
[_phImageRequestOperation cancel];
|
||||||
|
|
||||||
[self _setDownloadIdentifier:nil];
|
[self _setDownloadIdentifier:nil];
|
||||||
|
|
||||||
|
if (_cacheSupportsClearing) {
|
||||||
|
[_cache clearFetchedImageFromCacheWithURL:[_dataSource multiplexImageNode:self URLForImageIdentifier:self.loadedImageIdentifier]];
|
||||||
|
}
|
||||||
|
|
||||||
// setting this to nil makes the node fetch images the next time its display starts
|
// setting this to nil makes the node fetch images the next time its display starts
|
||||||
_loadedImageIdentifier = nil;
|
_loadedImageIdentifier = nil;
|
||||||
self.image = nil;
|
self.image = nil;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)fetchData
|
- (void)fetchData
|
||||||
@@ -266,6 +262,8 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* displayWillStart in ASNetworkImageNode has a very similar implementation. Changes here are likely necessary
|
||||||
|
in ASNetworkImageNode as well. */
|
||||||
- (void)displayWillStart
|
- (void)displayWillStart
|
||||||
{
|
{
|
||||||
[super displayWillStart];
|
[super displayWillStart];
|
||||||
@@ -276,19 +274,37 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
|
|||||||
{
|
{
|
||||||
ASDN::MutexLocker l(_downloadIdentifierLock);
|
ASDN::MutexLocker l(_downloadIdentifierLock);
|
||||||
if (_downloadIdentifier != nil) {
|
if (_downloadIdentifier != nil) {
|
||||||
[_downloader setPriority:ASImageDownloaderPriorityDisplay withDownloadIdentifier:_downloadIdentifier];
|
[_downloader setPriority:ASImageDownloaderPriorityImminent withDownloadIdentifier:_downloadIdentifier];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* visibilityDidChange in ASNetworkImageNode has a very similar implementation. Changes here are likely necessary
|
||||||
|
in ASNetworkImageNode as well. */
|
||||||
|
- (void)visibilityDidChange:(BOOL)isVisible
|
||||||
|
{
|
||||||
|
[super visibilityDidChange:isVisible];
|
||||||
|
|
||||||
|
if (_downloaderImplementsSetPriority) {
|
||||||
|
ASDN::MutexLocker l(_downloadIdentifierLock);
|
||||||
|
if (_downloadIdentifier != nil) {
|
||||||
|
if (isVisible) {
|
||||||
|
[_downloader setPriority:ASImageDownloaderPriorityVisible withDownloadIdentifier:_downloadIdentifier];
|
||||||
|
} else {
|
||||||
|
[_downloader setPriority:ASImageDownloaderPriorityPreload withDownloadIdentifier:_downloadIdentifier];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self.image == nil) {
|
|
||||||
if (_downloaderImplementsSetProgress) {
|
if (_downloaderImplementsSetProgress) {
|
||||||
{
|
|
||||||
ASDN::MutexLocker l(_downloadIdentifierLock);
|
ASDN::MutexLocker l(_downloadIdentifierLock);
|
||||||
|
|
||||||
if (_downloadIdentifier != nil) {
|
if (_downloadIdentifier != nil) {
|
||||||
__weak __typeof__(self) weakSelf = self;
|
__weak __typeof__(self) weakSelf = self;
|
||||||
[_downloader setProgressImageBlock:^(UIImage * _Nonnull progressImage, id _Nullable downloadIdentifier) {
|
ASImageDownloaderProgressImage progress = nil;
|
||||||
|
if (isVisible) {
|
||||||
|
progress = ^(UIImage * _Nonnull progressImage, id _Nullable downloadIdentifier) {
|
||||||
__typeof__(self) strongSelf = weakSelf;
|
__typeof__(self) strongSelf = weakSelf;
|
||||||
if (strongSelf == nil) {
|
if (strongSelf == nil) {
|
||||||
return;
|
return;
|
||||||
@@ -296,14 +312,15 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
|
|||||||
|
|
||||||
ASDN::MutexLocker l(strongSelf->_downloadIdentifierLock);
|
ASDN::MutexLocker l(strongSelf->_downloadIdentifierLock);
|
||||||
//Getting a result back for a different download identifier, download must not have been successfully canceled
|
//Getting a result back for a different download identifier, download must not have been successfully canceled
|
||||||
if (![strongSelf->_downloadIdentifier isEqual:downloadIdentifier] && downloadIdentifier != nil) {
|
if (ASObjectIsEqual(strongSelf->_downloadIdentifier, downloadIdentifier) == NO && downloadIdentifier != nil) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
strongSelf.image = progressImage;
|
strongSelf.image = progressImage;
|
||||||
} callbackQueue:dispatch_get_main_queue() withDownloadIdentifier:_downloadIdentifier];
|
};
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[_downloader setProgressImageBlock:progress callbackQueue:dispatch_get_main_queue() withDownloadIdentifier:_downloadIdentifier];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -695,7 +712,7 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
|
|||||||
ASDisplayNodeAssertNotNil(completionBlock, @"completionBlock is required");
|
ASDisplayNodeAssertNotNil(completionBlock, @"completionBlock is required");
|
||||||
|
|
||||||
if (_cache) {
|
if (_cache) {
|
||||||
if (_cacherSupportsNewProtocol) {
|
if (_cacheSupportsNewProtocol) {
|
||||||
[_cache cachedImageWithURL:imageURL callbackQueue:dispatch_get_main_queue() completion:^(UIImage *imageFromCache) {
|
[_cache cachedImageWithURL:imageURL callbackQueue:dispatch_get_main_queue() completion:^(UIImage *imageFromCache) {
|
||||||
completionBlock(imageFromCache);
|
completionBlock(imageFromCache);
|
||||||
}];
|
}];
|
||||||
@@ -746,7 +763,7 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
|
|||||||
|
|
||||||
ASDN::MutexLocker l(_downloadIdentifierLock);
|
ASDN::MutexLocker l(_downloadIdentifierLock);
|
||||||
//Getting a result back for a different download identifier, download must not have been successfully canceled
|
//Getting a result back for a different download identifier, download must not have been successfully canceled
|
||||||
if (![_downloadIdentifier isEqual:downloadIdentifier] && downloadIdentifier != nil) {
|
if (ASObjectIsEqual(_downloadIdentifier, downloadIdentifier) == NO && downloadIdentifier != nil) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -811,10 +828,6 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
|
|||||||
[self _loadNextImage];
|
[self _loadNextImage];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)_shouldClearFetchedImageData {
|
|
||||||
return _cache != nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
#if TARGET_OS_IOS
|
#if TARGET_OS_IOS
|
||||||
@implementation NSURL (ASPhotosFrameworkURLs)
|
@implementation NSURL (ASPhotosFrameworkURLs)
|
||||||
|
|||||||
@@ -45,19 +45,19 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
/**
|
/**
|
||||||
* The delegate, which must conform to the <ASNetworkImageNodeDelegate> protocol.
|
* The delegate, which must conform to the <ASNetworkImageNodeDelegate> protocol.
|
||||||
*/
|
*/
|
||||||
@property (nonatomic, weak, readwrite) id<ASNetworkImageNodeDelegate> delegate;
|
@property (atomic, weak, readwrite) id<ASNetworkImageNodeDelegate> delegate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A placeholder image to display while the URL is loading.
|
* A placeholder image to display while the URL is loading.
|
||||||
*/
|
*/
|
||||||
@property (nullable, nonatomic, strong, readwrite) UIImage *defaultImage;
|
@property (nullable, atomic, strong, readwrite) UIImage *defaultImage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The URL of a new image to download and display.
|
* The URL of a new image to download and display.
|
||||||
*
|
*
|
||||||
* @discussion Changing this property will reset the displayed image to a placeholder (<defaultImage>) while loading.
|
* @discussion Changing this property will reset the displayed image to a placeholder (<defaultImage>) while loading.
|
||||||
*/
|
*/
|
||||||
@property (nullable, nonatomic, strong, readwrite) NSURL *URL;
|
@property (nullable, atomic, strong, readwrite) NSURL *URL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Download and display a new image.
|
* Download and display a new image.
|
||||||
|
|||||||
@@ -21,8 +21,8 @@
|
|||||||
@interface ASNetworkImageNode ()
|
@interface ASNetworkImageNode ()
|
||||||
{
|
{
|
||||||
ASDN::RecursiveMutex _lock;
|
ASDN::RecursiveMutex _lock;
|
||||||
__weak id<ASImageCacheProtocol> _cache;
|
__weak id<ASImageCacheProtocol, ASImageCacheProtocolDeprecated> _cache;
|
||||||
__weak id<ASImageDownloaderProtocol> _downloader;
|
__weak id<ASImageDownloaderProtocol, ASImageDownloaderProtocolDeprecated> _downloader;
|
||||||
|
|
||||||
// Only access any of these with _lock.
|
// Only access any of these with _lock.
|
||||||
__weak id<ASNetworkImageNodeDelegate> _delegate;
|
__weak id<ASNetworkImageNodeDelegate> _delegate;
|
||||||
@@ -39,7 +39,8 @@
|
|||||||
BOOL _downloaderSupportsNewProtocol;
|
BOOL _downloaderSupportsNewProtocol;
|
||||||
BOOL _downloaderImplementsSetProgress;
|
BOOL _downloaderImplementsSetProgress;
|
||||||
BOOL _downloaderImplementsSetPriority;
|
BOOL _downloaderImplementsSetPriority;
|
||||||
BOOL _cacherSupportsNewProtocol;
|
BOOL _cacheSupportsNewProtocol;
|
||||||
|
BOOL _cacheSupportsClearing;
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@@ -53,16 +54,17 @@
|
|||||||
_cache = cache;
|
_cache = cache;
|
||||||
_downloader = downloader;
|
_downloader = downloader;
|
||||||
|
|
||||||
NSAssert([downloader respondsToSelector:@selector(downloadImageWithURL:callbackQueue:downloadProgress:completion:)] || [downloader respondsToSelector:@selector(downloadImageWithURL:callbackQueue:downloadProgressBlock:completion:)], @"downloader must respond to either downloadImageWithURL:callbackQueue:downloadProgress:completion: or downloadImageWithURL:callbackQueue:downloadProgressBlock:completion:.");
|
ASDisplayNodeAssert([downloader respondsToSelector:@selector(downloadImageWithURL:callbackQueue:downloadProgress:completion:)] || [downloader respondsToSelector:@selector(downloadImageWithURL:callbackQueue:downloadProgressBlock:completion:)], @"downloader must respond to either downloadImageWithURL:callbackQueue:downloadProgress:completion: or downloadImageWithURL:callbackQueue:downloadProgressBlock:completion:.");
|
||||||
|
|
||||||
_downloaderSupportsNewProtocol = [downloader respondsToSelector:@selector(downloadImageWithURL:callbackQueue:downloadProgress:completion:)] ? YES : NO;
|
_downloaderSupportsNewProtocol = [downloader respondsToSelector:@selector(downloadImageWithURL:callbackQueue:downloadProgress:completion:)];
|
||||||
|
|
||||||
NSAssert([cache respondsToSelector:@selector(cachedImageWithURL:callbackQueue:completion:)] || [cache respondsToSelector:@selector(fetchCachedImageWithURL:callbackQueue:completion:)], @"cacher must respond to either cachedImageWithURL:callbackQueue:completion: or fetchCachedImageWithURL:callbackQueue:completion:");
|
ASDisplayNodeAssert([cache respondsToSelector:@selector(cachedImageWithURL:callbackQueue:completion:)] || [cache respondsToSelector:@selector(fetchCachedImageWithURL:callbackQueue:completion:)], @"cacher must respond to either cachedImageWithURL:callbackQueue:completion: or fetchCachedImageWithURL:callbackQueue:completion:");
|
||||||
|
|
||||||
_downloaderImplementsSetProgress = [downloader respondsToSelector:@selector(setProgressImageBlock:callbackQueue:withDownloadIdentifier:)] ? YES : NO;
|
_downloaderImplementsSetProgress = [downloader respondsToSelector:@selector(setProgressImageBlock:callbackQueue:withDownloadIdentifier:)];
|
||||||
_downloaderImplementsSetPriority = [downloader respondsToSelector:@selector(setPriority:withDownloadIdentifier:)] ? YES : NO;
|
_downloaderImplementsSetPriority = [downloader respondsToSelector:@selector(setPriority:withDownloadIdentifier:)];
|
||||||
|
|
||||||
_cacherSupportsNewProtocol = [cache respondsToSelector:@selector(cachedImageWithURL:callbackQueue:completion:)] ? YES : NO;
|
_cacheSupportsNewProtocol = [cache respondsToSelector:@selector(cachedImageWithURL:callbackQueue:completion:)];
|
||||||
|
_cacheSupportsClearing = [cache respondsToSelector:@selector(clearFetchedImageFromCacheWithURL:)];
|
||||||
|
|
||||||
_shouldCacheImage = YES;
|
_shouldCacheImage = YES;
|
||||||
self.shouldBypassEnsureDisplay = YES;
|
self.shouldBypassEnsureDisplay = YES;
|
||||||
@@ -150,29 +152,45 @@
|
|||||||
return _delegate;
|
return _delegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* displayWillStart in ASMultiplexImageNode has a very similar implementation. Changes here are likely necessary
|
||||||
|
in ASMultiplexImageNode as well. */
|
||||||
- (void)displayWillStart
|
- (void)displayWillStart
|
||||||
{
|
{
|
||||||
[super displayWillStart];
|
[super displayWillStart];
|
||||||
|
|
||||||
[self fetchData];
|
[self fetchData];
|
||||||
|
|
||||||
if (self.image == nil) {
|
if (self.image == nil && _downloaderImplementsSetPriority) {
|
||||||
if (_downloaderImplementsSetPriority) {
|
|
||||||
{
|
|
||||||
ASDN::MutexLocker l(_lock);
|
ASDN::MutexLocker l(_lock);
|
||||||
if (_downloadIdentifier != nil) {
|
if (_downloadIdentifier != nil) {
|
||||||
[_downloader setPriority:ASImageDownloaderPriorityDisplay withDownloadIdentifier:_downloadIdentifier];
|
[_downloader setPriority:ASImageDownloaderPriorityImminent withDownloadIdentifier:_downloadIdentifier];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* visibilityDidChange in ASMultiplexImageNode has a very similar implementation. Changes here are likely necessary
|
||||||
|
in ASMultiplexImageNode as well. */
|
||||||
|
- (void)visibilityDidChange:(BOOL)isVisible
|
||||||
|
{
|
||||||
|
if (_downloaderImplementsSetPriority) {
|
||||||
|
ASDN::MutexLocker l(_lock);
|
||||||
|
if (_downloadIdentifier != nil) {
|
||||||
|
if (isVisible) {
|
||||||
|
[_downloader setPriority:ASImageDownloaderPriorityVisible withDownloadIdentifier:_downloadIdentifier];
|
||||||
|
} else {
|
||||||
|
[_downloader setPriority:ASImageDownloaderPriorityPreload withDownloadIdentifier:_downloadIdentifier];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_downloaderImplementsSetProgress) {
|
if (_downloaderImplementsSetProgress) {
|
||||||
{
|
|
||||||
ASDN::MutexLocker l(_lock);
|
ASDN::MutexLocker l(_lock);
|
||||||
|
|
||||||
if (_downloadIdentifier != nil) {
|
if (_downloadIdentifier != nil) {
|
||||||
__weak __typeof__(self) weakSelf = self;
|
__weak __typeof__(self) weakSelf = self;
|
||||||
[_downloader setProgressImageBlock:^(UIImage * _Nonnull progressImage, id _Nullable downloadIdentifier) {
|
ASImageDownloaderProgressImage progress = nil;
|
||||||
|
if (isVisible) {
|
||||||
|
progress = ^(UIImage * _Nonnull progressImage, id _Nullable downloadIdentifier) {
|
||||||
__typeof__(self) strongSelf = weakSelf;
|
__typeof__(self) strongSelf = weakSelf;
|
||||||
if (strongSelf == nil) {
|
if (strongSelf == nil) {
|
||||||
return;
|
return;
|
||||||
@@ -180,14 +198,14 @@
|
|||||||
|
|
||||||
ASDN::MutexLocker l(_lock);
|
ASDN::MutexLocker l(_lock);
|
||||||
//Getting a result back for a different download identifier, download must not have been successfully canceled
|
//Getting a result back for a different download identifier, download must not have been successfully canceled
|
||||||
if (![strongSelf->_downloadIdentifier isEqual:downloadIdentifier] && downloadIdentifier != nil) {
|
if (ASObjectIsEqual(strongSelf->_downloadIdentifier, downloadIdentifier) == NO && downloadIdentifier != nil) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
strongSelf.image = progressImage;
|
strongSelf.image = progressImage;
|
||||||
} callbackQueue:dispatch_get_main_queue() withDownloadIdentifier:_downloadIdentifier];
|
};
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
[_downloader setProgressImageBlock:progress callbackQueue:dispatch_get_main_queue() withDownloadIdentifier:_downloadIdentifier];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -202,6 +220,9 @@
|
|||||||
[self _cancelImageDownload];
|
[self _cancelImageDownload];
|
||||||
self.image = _defaultImage;
|
self.image = _defaultImage;
|
||||||
_imageLoaded = NO;
|
_imageLoaded = NO;
|
||||||
|
if (_cacheSupportsClearing) {
|
||||||
|
[_cache clearFetchedImageFromCacheWithURL:_URL];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,7 +315,7 @@
|
|||||||
ASDN::MutexLocker l(strongSelf->_lock);
|
ASDN::MutexLocker l(strongSelf->_lock);
|
||||||
|
|
||||||
//Getting a result back for a different download identifier, download must not have been successfully canceled
|
//Getting a result back for a different download identifier, download must not have been successfully canceled
|
||||||
if (![strongSelf->_downloadIdentifier isEqual:downloadIdentifier] && downloadIdentifier != nil) {
|
if (ASObjectIsEqual(strongSelf->_downloadIdentifier, downloadIdentifier) == NO && downloadIdentifier != nil) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,18 +354,16 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (_cacherSupportsNewProtocol) {
|
if (_cacheSupportsNewProtocol) {
|
||||||
[_cache cachedImageWithURL:_URL
|
[_cache cachedImageWithURL:_URL
|
||||||
callbackQueue:dispatch_get_main_queue()
|
callbackQueue:dispatch_get_main_queue()
|
||||||
completion:cacheCompletion];
|
completion:cacheCompletion];
|
||||||
} else {
|
} else {
|
||||||
void (^oldCacheCompletion)(CGImageRef) = ^(CGImageRef image) {
|
|
||||||
cacheCompletion([UIImage imageWithCGImage:image]);
|
|
||||||
};
|
|
||||||
|
|
||||||
[_cache fetchCachedImageWithURL:_URL
|
[_cache fetchCachedImageWithURL:_URL
|
||||||
callbackQueue:dispatch_get_main_queue()
|
callbackQueue:dispatch_get_main_queue()
|
||||||
completion:oldCacheCompletion];
|
completion:^(CGImageRef image) {
|
||||||
|
cacheCompletion([UIImage imageWithCGImage:image]);
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
[self _downloadImageWithCompletion:finished];
|
[self _downloadImageWithCompletion:finished];
|
||||||
|
|||||||
@@ -16,12 +16,6 @@ typedef void(^ASImageCacherCompletion)(UIImage * _Nullable imageFromCache);
|
|||||||
@protocol ASImageCacheProtocol <NSObject>
|
@protocol ASImageCacheProtocol <NSObject>
|
||||||
|
|
||||||
@optional
|
@optional
|
||||||
/**
|
|
||||||
@deprecated This method is deprecated @see cachedImageWithURL:callbackQueue:completion: instead
|
|
||||||
*/
|
|
||||||
- (void)fetchCachedImageWithURL:(nullable NSURL *)URL
|
|
||||||
callbackQueue:(nullable dispatch_queue_t)callbackQueue
|
|
||||||
completion:(void (^)(CGImageRef _Nullable imageFromCache))completion;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@abstract Attempts to fetch an image with the given URL from the cache.
|
@abstract Attempts to fetch an image with the given URL from the cache.
|
||||||
@@ -33,10 +27,17 @@ typedef void(^ASImageCacherCompletion)(UIImage * _Nullable imageFromCache);
|
|||||||
@discussion If `URL` is nil, `completion` will be invoked immediately with a nil image. This method should not block
|
@discussion If `URL` is nil, `completion` will be invoked immediately with a nil image. This method should not block
|
||||||
the calling thread as it is likely to be called from the main thread.
|
the calling thread as it is likely to be called from the main thread.
|
||||||
*/
|
*/
|
||||||
- (void)cachedImageWithURL:(nullable NSURL *)URL
|
- (void)cachedImageWithURL:(NSURL *)URL
|
||||||
callbackQueue:(nullable dispatch_queue_t)callbackQueue
|
callbackQueue:(dispatch_queue_t)callbackQueue
|
||||||
completion:(ASImageCacherCompletion)completion;
|
completion:(ASImageCacherCompletion)completion;
|
||||||
|
|
||||||
|
/**
|
||||||
|
@abstract Called during clearFetchedData. Allows the cache to optionally trim items.
|
||||||
|
@note Depending on your caches implementation you may *not* wish to respond to this method. It is however useful
|
||||||
|
if you have a memory and disk cache in which case you'll likely want to clear out the memory cache.
|
||||||
|
*/
|
||||||
|
- (void)clearFetchedImageFromCacheWithURL:(NSURL *)URL;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
typedef void(^ASImageDownloaderCompletion)(UIImage * _Nullable image, NSError * _Nullable error, id _Nullable downloadIdentifier);
|
typedef void(^ASImageDownloaderCompletion)(UIImage * _Nullable image, NSError * _Nullable error, id _Nullable downloadIdentifier);
|
||||||
@@ -44,8 +45,9 @@ typedef void(^ASImageDownloaderProgress)(CGFloat progress);
|
|||||||
typedef void(^ASImageDownloaderProgressImage)(UIImage *progressImage, id _Nullable downloadIdentifier);
|
typedef void(^ASImageDownloaderProgressImage)(UIImage *progressImage, id _Nullable downloadIdentifier);
|
||||||
|
|
||||||
typedef NS_ENUM(NSUInteger, ASImageDownloaderPriority) {
|
typedef NS_ENUM(NSUInteger, ASImageDownloaderPriority) {
|
||||||
ASImageDownloaderPriorityNormal = 0,
|
ASImageDownloaderPriorityPreload = 0,
|
||||||
ASImageDownloaderPriorityDisplay,
|
ASImageDownloaderPriorityImminent,
|
||||||
|
ASImageDownloaderPriorityVisible
|
||||||
};
|
};
|
||||||
|
|
||||||
@protocol ASImageDownloaderProtocol <NSObject>
|
@protocol ASImageDownloaderProtocol <NSObject>
|
||||||
@@ -62,15 +64,7 @@ typedef NS_ENUM(NSUInteger, ASImageDownloaderPriority) {
|
|||||||
|
|
||||||
@optional
|
@optional
|
||||||
|
|
||||||
//You must implement one of the two following methods
|
//You must implement the following method OR the deprecated method at the bottom
|
||||||
|
|
||||||
/**
|
|
||||||
@deprecated This method is deprecated @see downloadImageWithURL:callbackQueue:downloadProgress:completion: instead
|
|
||||||
*/
|
|
||||||
- (nullable id)downloadImageWithURL:(NSURL *)URL
|
|
||||||
callbackQueue:(nullable dispatch_queue_t)callbackQueue
|
|
||||||
downloadProgressBlock:(void (^ _Nullable)(CGFloat progress))downloadProgressBlock
|
|
||||||
completion:(void (^ _Nullable)(CGImageRef _Nullable image, NSError * _Nullable error))completion;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@abstract Downloads an image with the given URL.
|
@abstract Downloads an image with the given URL.
|
||||||
@@ -113,4 +107,29 @@ withDownloadIdentifier:(id)downloadIdentifier;
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@protocol ASImageDownloaderProtocolDeprecated <ASImageDownloaderProtocol>
|
||||||
|
|
||||||
|
@optional
|
||||||
|
/**
|
||||||
|
@deprecated This method is deprecated @see downloadImageWithURL:callbackQueue:downloadProgress:completion: instead
|
||||||
|
*/
|
||||||
|
- (nullable id)downloadImageWithURL:(NSURL *)URL
|
||||||
|
callbackQueue:(nullable dispatch_queue_t)callbackQueue
|
||||||
|
downloadProgressBlock:(void (^ _Nullable)(CGFloat progress))downloadProgressBlock
|
||||||
|
completion:(void (^ _Nullable)(CGImageRef _Nullable image, NSError * _Nullable error))completion;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@protocol ASImageCacheProtocolDeprecated <ASImageCacheProtocol>
|
||||||
|
|
||||||
|
@optional
|
||||||
|
/**
|
||||||
|
@deprecated This method is deprecated @see cachedImageWithURL:callbackQueue:completion: instead
|
||||||
|
*/
|
||||||
|
- (void)fetchCachedImageWithURL:(nullable NSURL *)URL
|
||||||
|
callbackQueue:(nullable dispatch_queue_t)callbackQueue
|
||||||
|
completion:(void (^)(CGImageRef _Nullable imageFromCache))completion;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
|||||||
@@ -8,6 +8,9 @@
|
|||||||
|
|
||||||
#ifdef PIN_REMOTE_IMAGE
|
#ifdef PIN_REMOTE_IMAGE
|
||||||
#import "ASPINRemoteImageDownloader.h"
|
#import "ASPINRemoteImageDownloader.h"
|
||||||
|
|
||||||
|
#import "ASAssert.h"
|
||||||
|
|
||||||
#import <PINRemoteImage/PINRemoteImageManager.h>
|
#import <PINRemoteImage/PINRemoteImageManager.h>
|
||||||
#import <PINCache/PINCache.h>
|
#import <PINCache/PINCache.h>
|
||||||
|
|
||||||
@@ -29,28 +32,18 @@
|
|||||||
callbackQueue:(dispatch_queue_t)callbackQueue
|
callbackQueue:(dispatch_queue_t)callbackQueue
|
||||||
completion:(void (^)(CGImageRef imageFromCache))completion
|
completion:(void (^)(CGImageRef imageFromCache))completion
|
||||||
{
|
{
|
||||||
NSString *key = [[PINRemoteImageManager sharedImageManager] cacheKeyForURL:URL processorKey:nil];
|
//We do not check the cache here and instead check it in downloadImageWithURL to avoid checking the cache twice.
|
||||||
UIImage *image = [[[[PINRemoteImageManager sharedImageManager] cache] memoryCache] objectForKey:key];
|
|
||||||
|
|
||||||
dispatch_async(callbackQueue, ^{
|
dispatch_async(callbackQueue, ^{
|
||||||
completion([image CGImage]);
|
completion(nil);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
- (void)clearFetchedImageFromCacheWithURL:(NSURL *)URL
|
||||||
@abstract Downloads an image with the given URL.
|
{
|
||||||
@param URL The URL of the image to download.
|
NSString *key = [[PINRemoteImageManager sharedImageManager] cacheKeyForURL:URL processorKey:nil];
|
||||||
@param callbackQueue The queue to call `downloadProgressBlock` and `completion` on. If this value is nil, both blocks
|
[[[[PINRemoteImageManager sharedImageManager] cache] memoryCache] removeObjectForKey:key];
|
||||||
will be invoked on the main-queue.
|
}
|
||||||
@param downloadProgressBlock The block to be invoked when the download of `URL` progresses.
|
|
||||||
@param progress The progress of the download, in the range of (0.0, 1.0), inclusive.
|
|
||||||
@param completion The block to be invoked when the download has completed, or has failed.
|
|
||||||
@param image The image that was downloaded, if the image could be successfully downloaded; nil otherwise.
|
|
||||||
@param error An error describing why the download of `URL` failed, if the download failed; nil otherwise.
|
|
||||||
@discussion This method is likely to be called on the main thread, so any custom implementations should make sure to background any expensive download operations.
|
|
||||||
@result An opaque identifier to be used in canceling the download, via `cancelImageDownloadForIdentifier:`. You must
|
|
||||||
retain the identifier if you wish to use it later.
|
|
||||||
*/
|
|
||||||
- (nullable id)downloadImageWithURL:(NSURL *)URL
|
- (nullable id)downloadImageWithURL:(NSURL *)URL
|
||||||
callbackQueue:(dispatch_queue_t)callbackQueue
|
callbackQueue:(dispatch_queue_t)callbackQueue
|
||||||
downloadProgress:(void (^)(CGFloat progress))downloadProgressBlock
|
downloadProgress:(void (^)(CGFloat progress))downloadProgressBlock
|
||||||
@@ -63,21 +56,15 @@
|
|||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
@abstract Cancels an image download.
|
|
||||||
@param downloadIdentifier The opaque download identifier object returned from
|
|
||||||
`downloadImageWithURL:callbackQueue:downloadProgressBlock:completion:`.
|
|
||||||
@discussion This method has no effect if `downloadIdentifier` is nil.
|
|
||||||
*/
|
|
||||||
- (void)cancelImageDownloadForIdentifier:(id)downloadIdentifier
|
- (void)cancelImageDownloadForIdentifier:(id)downloadIdentifier
|
||||||
{
|
{
|
||||||
NSAssert([downloadIdentifier isKindOfClass:[NSUUID class]], @"downloadIdentifier must be NSUUID");
|
ASDisplayNodeAssert([downloadIdentifier isKindOfClass:[NSUUID class]], @"downloadIdentifier must be NSUUID");
|
||||||
[[PINRemoteImageManager sharedImageManager] cancelTaskWithUUID:downloadIdentifier];
|
[[PINRemoteImageManager sharedImageManager] cancelTaskWithUUID:downloadIdentifier];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setProgressImageBlock:(ASImageDownloaderProgressImage)progressBlock callbackQueue:(dispatch_queue_t)callbackQueue withDownloadIdentifier:(id)downloadIdentifier
|
- (void)setProgressImageBlock:(ASImageDownloaderProgressImage)progressBlock callbackQueue:(dispatch_queue_t)callbackQueue withDownloadIdentifier:(id)downloadIdentifier
|
||||||
{
|
{
|
||||||
NSAssert([downloadIdentifier isKindOfClass:[NSUUID class]], @"downloadIdentifier must be NSUUID");
|
ASDisplayNodeAssert([downloadIdentifier isKindOfClass:[NSUUID class]], @"downloadIdentifier must be NSUUID");
|
||||||
|
|
||||||
[[PINRemoteImageManager sharedImageManager] setProgressCallback:^(PINRemoteImageManagerResult * _Nonnull result) {
|
[[PINRemoteImageManager sharedImageManager] setProgressCallback:^(PINRemoteImageManagerResult * _Nonnull result) {
|
||||||
dispatch_async(callbackQueue, ^{
|
dispatch_async(callbackQueue, ^{
|
||||||
@@ -88,9 +75,23 @@
|
|||||||
|
|
||||||
- (void)setPriority:(ASImageDownloaderPriority)priority withDownloadIdentifier:(id)downloadIdentifier
|
- (void)setPriority:(ASImageDownloaderPriority)priority withDownloadIdentifier:(id)downloadIdentifier
|
||||||
{
|
{
|
||||||
NSAssert([downloadIdentifier isKindOfClass:[NSUUID class]], @"downloadIdentifier must be NSUUID");
|
ASDisplayNodeAssert([downloadIdentifier isKindOfClass:[NSUUID class]], @"downloadIdentifier must be NSUUID");
|
||||||
|
|
||||||
[[PINRemoteImageManager sharedImageManager] setPriority:PINRemoteImageManagerPriorityHigh ofTaskWithUUID:downloadIdentifier];
|
PINRemoteImageManagerPriority pi_priority = PINRemoteImageManagerPriorityMedium;
|
||||||
|
switch (priority) {
|
||||||
|
case ASImageDownloaderPriorityPreload:
|
||||||
|
pi_priority = PINRemoteImageManagerPriorityMedium;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASImageDownloaderPriorityImminent:
|
||||||
|
pi_priority = PINRemoteImageManagerPriorityHigh;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASImageDownloaderPriorityVisible:
|
||||||
|
pi_priority = PINRemoteImageManagerPriorityVeryHigh;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
[[PINRemoteImageManager sharedImageManager] setPriority:pi_priority ofTaskWithUUID:downloadIdentifier];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
Reference in New Issue
Block a user