Add support for providing additional info to network image node delegate (#775)

* Add support for piping arbitrary user info from ASImageDownloader to the ASNetworkImageNodeDelegate

* s/source/sourceType

* Fix stuff and take Michael's advice
This commit is contained in:
Adlai Holler 2018-01-30 17:50:38 -05:00 committed by GitHub
parent 196d76d82d
commit fef965f78e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 173 additions and 55 deletions

View File

@ -410,6 +410,9 @@
CCE4F9B51F0DA4F300062E4E /* ASLayoutEngineTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCE4F9B41F0DA4F300062E4E /* ASLayoutEngineTests.mm */; };
CCE4F9BA1F0DBB5000062E4E /* ASLayoutTestNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCE4F9B71F0DBA5000062E4E /* ASLayoutTestNode.mm */; };
CCE4F9BE1F0ECE5200062E4E /* ASTLayoutFixture.mm in Sources */ = {isa = PBXBuildFile; fileRef = CCE4F9BD1F0ECE5200062E4E /* ASTLayoutFixture.mm */; };
CCED5E3E2020D36800395C40 /* ASNetworkImageLoadInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = CCED5E3C2020D36800395C40 /* ASNetworkImageLoadInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
CCED5E3F2020D36800395C40 /* ASNetworkImageLoadInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = CCED5E3D2020D36800395C40 /* ASNetworkImageLoadInfo.m */; };
CCED5E412020D49D00395C40 /* ASNetworkImageLoadInfo+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = CCED5E402020D41600395C40 /* ASNetworkImageLoadInfo+Private.h */; settings = {ATTRIBUTES = (Private, ); }; };
CCF18FF41D2575E300DF5895 /* NSIndexSet+ASHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = CC4981BA1D1C7F65004E13CC /* NSIndexSet+ASHelpers.h */; settings = {ATTRIBUTES = (Private, ); }; };
DB55C2671C641AE4004EDCF5 /* ASContextTransitioning.h in Headers */ = {isa = PBXBuildFile; fileRef = DB55C2651C641AE4004EDCF5 /* ASContextTransitioning.h */; settings = {ATTRIBUTES = (Public, ); }; };
DB7121BCD50849C498C886FB /* libPods-AsyncDisplayKitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EFA731F0396842FF8AB635EE /* libPods-AsyncDisplayKitTests.a */; };
@ -913,6 +916,9 @@
CCE4F9BB1F0EA67F00062E4E /* debugbreak.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = debugbreak.h; sourceTree = "<group>"; };
CCE4F9BC1F0ECE5200062E4E /* ASTLayoutFixture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASTLayoutFixture.h; sourceTree = "<group>"; };
CCE4F9BD1F0ECE5200062E4E /* ASTLayoutFixture.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTLayoutFixture.mm; sourceTree = "<group>"; };
CCED5E3C2020D36800395C40 /* ASNetworkImageLoadInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASNetworkImageLoadInfo.h; sourceTree = "<group>"; };
CCED5E3D2020D36800395C40 /* ASNetworkImageLoadInfo.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASNetworkImageLoadInfo.m; sourceTree = "<group>"; };
CCED5E402020D41600395C40 /* ASNetworkImageLoadInfo+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ASNetworkImageLoadInfo+Private.h"; sourceTree = "<group>"; };
D3779BCFF841AD3EB56537ED /* Pods-AsyncDisplayKitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AsyncDisplayKitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-AsyncDisplayKitTests/Pods-AsyncDisplayKitTests.release.xcconfig"; sourceTree = "<group>"; };
D785F6601A74327E00291744 /* ASScrollNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASScrollNode.h; sourceTree = "<group>"; };
D785F6611A74327E00291744 /* ASScrollNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASScrollNode.mm; sourceTree = "<group>"; };
@ -1074,6 +1080,8 @@
058D09B1195D04C000B7D73C /* Source */ = {
isa = PBXGroup;
children = (
CCED5E3C2020D36800395C40 /* ASNetworkImageLoadInfo.h */,
CCED5E3D2020D36800395C40 /* ASNetworkImageLoadInfo.m */,
CCE04B1D1E313E99006AEBBB /* Collection Data Adapter */,
CC58AA4A1E398E1D002C8CB4 /* ASBlockTypes.h */,
DBDB83921C6E879900D0098C /* ASPagerFlowLayout.h */,
@ -1376,6 +1384,7 @@
058D0A01195D050800B7D73C /* Private */ = {
isa = PBXGroup;
children = (
CCED5E402020D41600395C40 /* ASNetworkImageLoadInfo+Private.h */,
CCA282CE1E9EBF6C0037E8B7 /* ASTipsWindow.h */,
CCA282CF1E9EBF6C0037E8B7 /* ASTipsWindow.m */,
CCA282C61E9EB64B0037E8B7 /* ASDisplayNodeTipState.h */,
@ -1913,6 +1922,7 @@
DE4843DC1C93EAC100A1F33B /* ASLayoutTransition.h in Headers */,
CC57EAF81E3939450034C595 /* ASTableView+Undeprecated.h in Headers */,
254C6B781BF94DF4003EC431 /* ASTextKitContext.h in Headers */,
CCED5E412020D49D00395C40 /* ASNetworkImageLoadInfo+Private.h in Headers */,
9CDC18CD1B910E12004965E2 /* ASLayoutElementPrivate.h in Headers */,
B35062201B010EFD0018CF92 /* ASLayoutController.h in Headers */,
B35062211B010EFD0018CF92 /* ASLayoutRangeType.h in Headers */,
@ -1964,6 +1974,7 @@
B35062391B010EFD0018CF92 /* ASThread.h in Headers */,
2C107F5B1BA9F54500F13DE5 /* AsyncDisplayKit.h in Headers */,
509E68651B3AEDC5009B9150 /* CoreGraphics+ASConvenience.h in Headers */,
CCED5E3E2020D36800395C40 /* ASNetworkImageLoadInfo.h in Headers */,
B350623A1B010EFD0018CF92 /* NSMutableAttributedString+TextKitAdditions.h in Headers */,
044284FF1BAA3BD600D16268 /* UICollectionViewLayout+ASConvenience.h in Headers */,
B35062431B010EFD0018CF92 /* UIView+ASConvenience.h in Headers */,
@ -2292,6 +2303,7 @@
E55D86331CA8A14000A0C26F /* ASLayoutElement.mm in Sources */,
68FC85EC1CE29C7D00EDD713 /* ASVisibilityProtocols.m in Sources */,
CC55A7121E52A0F200594372 /* ASResponderChainEnumerator.m in Sources */,
CCED5E3F2020D36800395C40 /* ASNetworkImageLoadInfo.m in Sources */,
68B8A4E41CBDB958007E4543 /* ASWeakProxy.m in Sources */,
E5775B041F16759F00CAC9BC /* ASCollectionLayoutCache.mm in Sources */,
9C70F20A1CDBE949007D6C76 /* ASTableNode.mm in Sources */,

View File

@ -14,6 +14,9 @@
- [ASCollectionNode] Added support for interactive item movement. [Adlai Holler](https://github.com/Adlai-Holler)
- Added an experimental "no-copy" rendering API. See ASGraphicsContext.h for info. [Adlai Holler](https://github.com/Adlai-Holler)
- Dropped support for iOS 8. [Adlai Holler](https://github.com/Adlai-Holler)
- **Breaking** Changes to ASNetworkImageNode: [Adlai Holler](https://github.com/Adlai-Holler)
- Modified `ASImageDownloaderCompletion` to add an optional `id userInfo` field. Your custom downloader can pass `nil`.
- Modified the last argument to `-[ASNetworkImageNodeDelegate imageNode:didLoadImage:info:]` method from a struct to an object of new class `ASNetworkImageLoadInfo` which includes other metadata about the load operation.
- Removed +load static initializer from ASDisplayNode. [Adlai Holler](https://github.com/Adlai-Holler)
## 2.6

View File

@ -823,7 +823,7 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
[self _setDownloadIdentifier:[_downloader downloadImageWithURL:imageURL
callbackQueue:dispatch_get_main_queue()
downloadProgress:downloadProgressBlock
completion:^(id <ASImageContainerProtocol> imageContainer, NSError *error, id downloadIdentifier) {
completion:^(id <ASImageContainerProtocol> imageContainer, NSError *error, id downloadIdentifier, id userInfo) {
// We dereference iVars directly, so we can't have weakSelf going nil on us.
__typeof__(self) strongSelf = weakSelf;
if (!strongSelf)

View File

@ -0,0 +1,39 @@
//
// ASNetworkImageLoadInfo.h
// AsyncDisplayKit
//
// Created by Adlai on 1/30/18.
// Copyright © 2018 Facebook. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <AsyncDisplayKit/ASBaseDefines.h>
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSInteger, ASNetworkImageSourceType) {
ASNetworkImageSourceUnspecified = 0,
ASNetworkImageSourceSynchronousCache,
ASNetworkImageSourceAsynchronousCache,
ASNetworkImageSourceFileURL,
ASNetworkImageSourceDownload,
};
AS_SUBCLASSING_RESTRICTED
@interface ASNetworkImageLoadInfo : NSObject <NSCopying>
/// The type of source from which the image was loaded.
@property (readonly) ASNetworkImageSourceType sourceType;
/// The image URL that was downloaded.
@property (readonly) NSURL *url;
/// The download identifier, if one was provided.
@property (nullable, readonly) id downloadIdentifier;
/// The userInfo object provided by the downloader, if one was provided.
@property (nullable, readonly) id userInfo;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,32 @@
//
// ASNetworkImageLoadInfo.m
// AsyncDisplayKit
//
// Created by Adlai on 1/30/18.
// Copyright © 2018 Facebook. All rights reserved.
//
#import <AsyncDisplayKit/ASNetworkImageLoadInfo.h>
#import <AsyncDisplayKit/ASNetworkImageLoadInfo+Private.h>
@implementation ASNetworkImageLoadInfo
- (instancetype)initWithURL:(NSURL *)url sourceType:(ASNetworkImageSourceType)sourceType downloadIdentifier:(id)downloadIdentifier userInfo:(id)userInfo
{
if (self = [super init]) {
_url = [url copy];
_sourceType = sourceType;
_downloadIdentifier = downloadIdentifier;
_userInfo = userInfo;
}
return self;
}
#pragma mark - NSCopying
- (id)copyWithZone:(NSZone *)zone
{
return self;
}
@end

View File

@ -20,6 +20,7 @@
NS_ASSUME_NONNULL_BEGIN
@protocol ASNetworkImageNodeDelegate, ASImageCacheProtocol, ASImageDownloaderProtocol;
@class ASNetworkImageLoadInfo;
/**
@ -134,20 +135,6 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark -
typedef NS_ENUM(NSInteger, ASNetworkImageSource) {
ASNetworkImageSourceUnspecified = 0,
ASNetworkImageSourceSynchronousCache,
ASNetworkImageSourceAsynchronousCache,
ASNetworkImageSourceFileURL,
ASNetworkImageSourceDownload,
};
/// A struct that carries details about ASNetworkImageNode's image loads.
typedef struct {
/// The source from which the image was loaded.
ASNetworkImageSource imageSource;
} ASNetworkImageNodeDidLoadInfo;
/**
* The methods declared by the ASNetworkImageNodeDelegate protocol allow the adopting delegate to respond to
* notifications such as finished decoding and downloading an image.
@ -161,11 +148,11 @@ typedef struct {
*
* @param imageNode The sender.
* @param image The newly-loaded image.
* @param info Misc information about the image load.
* @param info Additional information about the image load.
*
* @discussion Called on a background queue.
*/
- (void)imageNode:(ASNetworkImageNode *)imageNode didLoadImage:(UIImage *)image info:(ASNetworkImageNodeDidLoadInfo)info;
- (void)imageNode:(ASNetworkImageNode *)imageNode didLoadImage:(UIImage *)image info:(ASNetworkImageLoadInfo *)info;
/**
* Notification that the image node finished downloading an image.

View File

@ -27,6 +27,7 @@
#import <AsyncDisplayKit/ASImageNode+AnimatedImagePrivate.h>
#import <AsyncDisplayKit/ASImageContainerProtocolCategories.h>
#import <AsyncDisplayKit/ASLog.h>
#import <AsyncDisplayKit/ASNetworkImageLoadInfo+Private.h>
#if AS_PIN_REMOTE_IMAGE
#import <AsyncDisplayKit/ASPINRemoteImageDownloader.h>
@ -334,8 +335,9 @@
if (asynchronously == NO && _cacheFlags.cacheSupportsSynchronousFetch) {
ASDN::MutexLocker l(__instanceLock__);
if (_imageLoaded == NO && _URL && _downloadIdentifier == nil) {
UIImage *result = [[_cache synchronouslyFetchedCachedImageWithURL:_URL] asdk_image];
NSURL *url = _URL;
if (_imageLoaded == NO && url && _downloadIdentifier == nil) {
UIImage *result = [[_cache synchronouslyFetchedCachedImageWithURL:url] asdk_image];
if (result) {
[self _locked_setCurrentImageQuality:1.0];
[self _locked__setImage:result];
@ -344,8 +346,7 @@
// Call out to the delegate.
if (_delegateFlags.delegateDidLoadImageWithInfo) {
ASDN::MutexUnlocker l(__instanceLock__);
ASNetworkImageNodeDidLoadInfo info = {};
info.imageSource = ASNetworkImageSourceSynchronousCache;
auto info = [[ASNetworkImageLoadInfo alloc] initWithURL:url sourceType:ASNetworkImageSourceSynchronousCache downloadIdentifier:nil userInfo:nil];
[_delegate imageNode:self didLoadImage:result info:info];
} else if (_delegateFlags.delegateDidLoadImage) {
ASDN::MutexUnlocker l(__instanceLock__);
@ -553,7 +554,7 @@
_cacheUUID = nil;
}
- (void)_downloadImageWithCompletion:(void (^)(id <ASImageContainerProtocol> imageContainer, NSError*, id downloadIdentifier))finished
- (void)_downloadImageWithCompletion:(void (^)(id <ASImageContainerProtocol> imageContainer, NSError*, id downloadIdentifier, id userInfo))finished
{
ASPerformBlockOnBackgroundThread(^{
NSURL *url;
@ -572,9 +573,9 @@
downloadIdentifier = [_downloader downloadImageWithURL:url
callbackQueue:dispatch_get_main_queue()
downloadProgress:NULL
completion:^(id <ASImageContainerProtocol> _Nullable imageContainer, NSError * _Nullable error, id _Nullable downloadIdentifier) {
completion:^(id <ASImageContainerProtocol> _Nullable imageContainer, NSError * _Nullable error, id _Nullable downloadIdentifier, id _Nullable userInfo) {
if (finished != NULL) {
finished(imageContainer, error, downloadIdentifier);
finished(imageContainer, error, downloadIdentifier, userInfo);
}
}];
as_log_verbose(ASImageLoadingLog(), "Downloading image for %@ url: %@", self, url);
@ -629,15 +630,15 @@
}
if (_shouldCacheImage) {
[self _locked__setImage:[UIImage imageNamed:_URL.path.lastPathComponent]];
[self _locked__setImage:[UIImage imageNamed:URL.path.lastPathComponent]];
} else {
// First try to load the path directly, for efficiency assuming a developer who
// doesn't want caching is trying to be as minimal as possible.
UIImage *nonAnimatedImage = [UIImage imageWithContentsOfFile:_URL.path];
UIImage *nonAnimatedImage = [UIImage imageWithContentsOfFile:URL.path];
if (nonAnimatedImage == nil) {
// If we couldn't find it, execute an -imageNamed:-like search so we can find resources even if the
// extension is not provided in the path. This allows the same path to work regardless of shouldCacheImage.
NSString *filename = [[NSBundle mainBundle] pathForResource:_URL.path.lastPathComponent ofType:nil];
NSString *filename = [[NSBundle mainBundle] pathForResource:URL.path.lastPathComponent ofType:nil];
if (filename != nil) {
nonAnimatedImage = [UIImage imageWithContentsOfFile:filename];
}
@ -646,7 +647,7 @@
// If the file may be an animated gif and then created an animated image.
id<ASAnimatedImageProtocol> animatedImage = nil;
if (_downloaderFlags.downloaderImplementsAnimatedImage) {
NSData *data = [NSData dataWithContentsOfURL:_URL];
NSData *data = [NSData dataWithContentsOfURL:URL];
if (data != nil) {
animatedImage = [_downloader animatedImageWithData:data];
@ -669,8 +670,7 @@
if (_delegateFlags.delegateDidLoadImageWithInfo) {
ASDN::MutexUnlocker u(__instanceLock__);
ASNetworkImageNodeDidLoadInfo info = {};
info.imageSource = ASNetworkImageSourceFileURL;
auto info = [[ASNetworkImageLoadInfo alloc] initWithURL:URL sourceType:ASNetworkImageSourceFileURL downloadIdentifier:nil userInfo:nil];
[delegate imageNode:self didLoadImage:self.image info:info];
} else if (_delegateFlags.delegateDidLoadImage) {
ASDN::MutexUnlocker u(__instanceLock__);
@ -679,7 +679,7 @@
});
} else {
__weak __typeof__(self) weakSelf = self;
auto finished = ^(id <ASImageContainerProtocol>imageContainer, NSError *error, id downloadIdentifier, ASNetworkImageSource imageSource) {
auto finished = ^(id <ASImageContainerProtocol>imageContainer, NSError *error, id downloadIdentifier, ASNetworkImageSourceType imageSource, id userInfo) {
ASPerformBlockOnBackgroundThread(^{
__typeof__(self) strongSelf = weakSelf;
if (strongSelf == nil) {
@ -718,6 +718,9 @@
strongSelf->_downloadIdentifier = nil;
strongSelf->_cacheUUID = nil;
// TODO: Why dispatch to main here?
// The docs say the image node delegate methods
// are called from background.
ASPerformBlockOnMainThread(^{
__typeof__(self) strongSelf = weakSelf;
if (strongSelf == nil) {
@ -730,8 +733,7 @@
if (imageContainer != nil) {
if (strongSelf->_delegateFlags.delegateDidLoadImageWithInfo) {
ASDN::MutexUnlocker u(strongSelf->__instanceLock__);
ASNetworkImageNodeDidLoadInfo info = {};
info.imageSource = imageSource;
auto info = [[ASNetworkImageLoadInfo alloc] initWithURL:URL sourceType:imageSource downloadIdentifier:downloadIdentifier userInfo:userInfo];
[delegate imageNode:strongSelf didLoadImage:strongSelf.image info:info];
} else if (strongSelf->_delegateFlags.delegateDidLoadImage) {
ASDN::MutexUnlocker u(strongSelf->__instanceLock__);
@ -766,20 +768,20 @@
}
if ([imageContainer asdk_image] == nil && _downloader != nil) {
[self _downloadImageWithCompletion:^(id<ASImageContainerProtocol> imageContainer, NSError *error, id downloadIdentifier) {
finished(imageContainer, error, downloadIdentifier, ASNetworkImageSourceDownload);
[self _downloadImageWithCompletion:^(id<ASImageContainerProtocol> imageContainer, NSError *error, id downloadIdentifier, id userInfo) {
finished(imageContainer, error, downloadIdentifier, ASNetworkImageSourceDownload, userInfo);
}];
} else {
as_log_verbose(ASImageLoadingLog(), "Decached image for %@ img: %@ url: %@", self, [imageContainer asdk_image], URL);
finished(imageContainer, nil, nil, ASNetworkImageSourceAsynchronousCache);
finished(imageContainer, nil, nil, ASNetworkImageSourceAsynchronousCache, nil);
}
};
[_cache cachedImageWithURL:URL
callbackQueue:dispatch_get_main_queue()
completion:completion];
} else {
[self _downloadImageWithCompletion:^(id<ASImageContainerProtocol> imageContainer, NSError *error, id downloadIdentifier) {
finished(imageContainer, error, downloadIdentifier, ASNetworkImageSourceDownload);
[self _downloadImageWithCompletion:^(id<ASImageContainerProtocol> imageContainer, NSError *error, id downloadIdentifier, id userInfo) {
finished(imageContainer, error, downloadIdentifier, ASNetworkImageSourceDownload, userInfo);
}];
}
}

View File

@ -35,6 +35,7 @@
#import <AsyncDisplayKit/ASBasicImageDownloader.h>
#import <AsyncDisplayKit/ASPINRemoteImageDownloader.h>
#import <AsyncDisplayKit/ASMultiplexImageNode.h>
#import <AsyncDisplayKit/ASNetworkImageLoadInfo.h>
#import <AsyncDisplayKit/ASNetworkImageNode.h>
#import <AsyncDisplayKit/ASPhotosFrameworkImageRequest.h>

View File

@ -25,14 +25,15 @@ NS_ASSUME_NONNULL_BEGIN
@interface ASBasicImageDownloader : NSObject <ASImageDownloaderProtocol>
/**
* A shared image downloader which can be used by @c ASNetworkImageNodes and @c ASMultiplexImageNodes
* A shared image downloader which can be used by @c ASNetworkImageNodes and @c ASMultiplexImageNodes.
* The userInfo provided by this downloader is `nil`.
*
* This is a very basic image downloader. It does not support caching, progressive downloading and likely
* isn't something you should use in production. If you'd like something production ready, see @c ASPINRemoteImageDownloader
*
* @note It is strongly recommended you include PINRemoteImage and use @c ASPINRemoteImageDownloader instead.
*/
+ (instancetype)sharedImageDownloader;
@property (class, readonly) ASBasicImageDownloader *sharedImageDownloader;
+ (instancetype)new __attribute__((unavailable("+[ASBasicImageDownloader sharedImageDownloader] must be used.")));
- (instancetype)init __attribute__((unavailable("+[ASBasicImageDownloader sharedImageDownloader] must be used.")));

View File

@ -130,7 +130,7 @@ static ASDN::StaticMutex& currentRequestsLock = *new ASDN::StaticMutex;
if (completionBlock) {
dispatch_async(callbackQueue, ^{
completionBlock(image, error, nil);
completionBlock(image, error, nil, nil);
});
}
}
@ -206,7 +206,7 @@ static const char *kContextKey = NSStringFromClass(ASBasicImageDownloaderContext
@implementation ASBasicImageDownloader
+ (instancetype)sharedImageDownloader
+ (ASBasicImageDownloader *)sharedImageDownloader
{
static ASBasicImageDownloader *sharedImageDownloader = nil;
static dispatch_once_t once = 0;
@ -235,9 +235,9 @@ static const char *kContextKey = NSStringFromClass(ASBasicImageDownloaderContext
#pragma mark ASImageDownloaderProtocol.
- (id)downloadImageWithURL:(NSURL *)URL
callbackQueue:(dispatch_queue_t)callbackQueue
downloadProgress:(nullable ASImageDownloaderProgress)downloadProgress
completion:(ASImageDownloaderCompletion)completion
callbackQueue:(dispatch_queue_t)callbackQueue
downloadProgress:(nullable ASImageDownloaderProgress)downloadProgress
completion:(ASImageDownloaderCompletion)completion
{
ASBasicImageDownloaderContext *context = [ASBasicImageDownloaderContext contextForURL:URL];

View File

@ -72,8 +72,9 @@ typedef void(^ASImageCacherCompletion)(id <ASImageContainerProtocol> _Nullable i
@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.
@param downloadIdentifier The identifier for the download task that completed.
@param userInfo Any additional info that your downloader would like to communicate through Texture.
*/
typedef void(^ASImageDownloaderCompletion)(id <ASImageContainerProtocol> _Nullable image, NSError * _Nullable error, id _Nullable downloadIdentifier);
typedef void(^ASImageDownloaderCompletion)(id <ASImageContainerProtocol> _Nullable image, NSError * _Nullable error, id _Nullable downloadIdentifier, id _Nullable userInfo);
/**
@param progress The progress of the download, in the range of (0.0, 1.0), inclusive.

View File

@ -28,12 +28,13 @@ NS_ASSUME_NONNULL_BEGIN
@interface ASPINRemoteImageDownloader : NSObject <ASImageCacheProtocol, ASImageDownloaderProtocol>
/**
* A shared image downloader which can be used by @c ASNetworkImageNodes and @c ASMultiplexImageNodes
* A shared image downloader which can be used by @c ASNetworkImageNodes and @c ASMultiplexImageNodes.
* The userInfo provided by this downloader is an instance of `PINRemoteImageManagerResult`.
*
* This is the default downloader used by network backed image nodes if PINRemoteImage and PINCache are
* available. It uses PINRemoteImage's features to provide caching and progressive image downloads.
*/
+ (ASPINRemoteImageDownloader *)sharedDownloader;
@property (class, readonly) ASPINRemoteImageDownloader *sharedDownloader;
/**

View File

@ -114,7 +114,7 @@ static ASPINRemoteImageDownloader *sharedDownloader = nil;
@implementation ASPINRemoteImageDownloader
+ (instancetype)sharedDownloader
+ (ASPINRemoteImageDownloader *)sharedDownloader
{
static dispatch_once_t onceToken = 0;
@ -235,12 +235,12 @@ static ASPINRemoteImageDownloader *sharedDownloader = nil;
[ASPINRemoteImageDownloader _performWithCallbackQueue:callbackQueue work:^{
#if PIN_ANIMATED_AVAILABLE
if (result.alternativeRepresentation) {
completion(result.alternativeRepresentation, result.error, result.UUID);
completion(result.alternativeRepresentation, result.error, result.UUID, result);
} else {
completion(result.image, result.error, result.UUID);
completion(result.image, result.error, result.UUID, result);
}
#else
completion(result.image, result.error, result.UUID);
completion(result.image, result.error, result.UUID, result);
#endif
}];
};

View File

@ -0,0 +1,22 @@
//
// ASNetworkImageLoadInfo+Private.h
// AsyncDisplayKit
//
// Created by Adlai on 1/30/18.
// Copyright © 2018 Facebook. All rights reserved.
//
#import <AsyncDisplayKit/ASNetworkImageLoadInfo.h>
NS_ASSUME_NONNULL_BEGIN
@interface ASNetworkImageLoadInfo ()
- (instancetype)initWithURL:(NSURL *)url
sourceType:(ASNetworkImageSourceType)sourceType
downloadIdentifier:(nullable id)downloadIdentifier
userInfo:(nullable id)userInfo;
@end
NS_ASSUME_NONNULL_END

View File

@ -38,14 +38,14 @@
[downloader downloadImageWithURL:URL
callbackQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
downloadProgress:nil
completion:^(id<ASImageContainerProtocol> _Nullable image, NSError * _Nullable error, id _Nullable downloadIdentifier) {
completion:^(id<ASImageContainerProtocol> _Nullable image, NSError * _Nullable error, id _Nullable downloadIdentifier, id _Nullable userInfo) {
[firstExpectation fulfill];
}];
[downloader downloadImageWithURL:URL
callbackQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
downloadProgress:nil
completion:^(id<ASImageContainerProtocol> _Nullable image, NSError * _Nullable error, id _Nullable downloadIdentifier) {
completion:^(id<ASImageContainerProtocol> _Nullable image, NSError * _Nullable error, id _Nullable downloadIdentifier, id _Nullable userInfo) {
[secondExpectation fulfill];
}];

View File

@ -238,7 +238,7 @@
// Simulate completion.
ASImageDownloaderCompletion completionBlock = [inv as_argumentAtIndexAsObject:5];
completionBlock([self _testImage], nil, nil);
completionBlock([self _testImage], nil, nil, nil);
});
NSNumber *imageIdentifier = @1;

View File

@ -44,6 +44,9 @@
#define InsetForHeader UIEdgeInsetsMake(0, HORIZONTAL_BUFFER, 0, HORIZONTAL_BUFFER)
#define InsetForFooter UIEdgeInsetsMake(VERTICAL_BUFFER, HORIZONTAL_BUFFER, VERTICAL_BUFFER, HORIZONTAL_BUFFER)
@interface PhotoCellNode () <ASNetworkImageNodeDelegate>
@end
@implementation PhotoCellNode
{
PhotoModel *_photoModel;
@ -77,6 +80,7 @@
}];
_photoImageNode = [[ASNetworkImageNode alloc] init];
_photoImageNode.delegate = self;
_photoImageNode.URL = photo.URL;
_photoImageNode.layerBacked = YES;
@ -284,6 +288,19 @@
}];
}
#pragma mark - Network Image Delegate
- (void)imageNode:(ASNetworkImageNode *)imageNode didLoadImage:(UIImage *)image info:(ASNetworkImageLoadInfo *)info
{
// Docs say method is called from bg but right now it's called from main.
// Save main thread time by shunting this.
if (info.sourceType == ASNetworkImageSourceDownload) {
ASPerformBlockOnBackgroundThread(^{
NSLog(@"Received image %@ from %@ with userInfo %@", image, info.url.path, ASObjectDescriptionMakeTiny(info.userInfo));
});
}
}
#pragma mark - Helper Methods
- (ASTextNode *)createLayerBackedTextNodeWithString:(NSAttributedString *)attributedString