ASMultiplexImageNode.h 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /* Copyright (c) 2014-present, Facebook, Inc.
  2. * All rights reserved.
  3. *
  4. * This source code is licensed under the BSD-style license found in the
  5. * LICENSE file in the root directory of this source tree. An additional grant
  6. * of patent rights can be found in the PATENTS file in the same directory.
  7. */
  8. #import <AsyncDisplayKit/ASImageNode.h>
  9. #import <AsyncDisplayKit/ASImageProtocols.h>
  10. @protocol ASMultiplexImageNodeDelegate;
  11. @protocol ASMultiplexImageNodeDataSource;
  12. extern NSString *const ASMultiplexImageNodeErrorDomain;
  13. /**
  14. * ASMultiplexImageNode error codes.
  15. */
  16. typedef NS_ENUM(NSUInteger, ASMultiplexImageNodeErrorCode) {
  17. /**
  18. * Indicates that the data source didn't provide a source for an image identifier.
  19. */
  20. ASMultiplexImageNodeErrorCodeNoSourceForImage = 0,
  21. /**
  22. * Indicates that the best image identifier changed before a download for a worse identifier began.
  23. */
  24. ASMultiplexImageNodeErrorCodeBestImageIdentifierChanged,
  25. };
  26. /**
  27. * @abstract ASMultiplexImageNode is an image node that can load and display multiple versions of an image. For
  28. * example, it can display a low-resolution version of an image while the high-resolution version is loading.
  29. *
  30. * @discussion ASMultiplexImageNode begins loading images when its <imageIdentifiers> property is set. For each image
  31. * identifier, the data source can either return a UIImage directly, or a URL the image node should load.
  32. */
  33. @interface ASMultiplexImageNode : ASImageNode
  34. /**
  35. * @abstract The designated initializer.
  36. * @param cache The object that implements a cache of images for the image node.
  37. * @param downloader The object that implements image downloading for the image node.
  38. * @discussion If `cache` is nil, the receiver will not attempt to retrieve images from a cache before downloading them.
  39. * @returns An initialized ASMultiplexImageNode.
  40. */
  41. - (instancetype)initWithCache:(id<ASImageCacheProtocol>)cache downloader:(id<ASImageDownloaderProtocol>)downloader NS_DESIGNATED_INITIALIZER;
  42. /**
  43. * @abstract The delegate, which must conform to the <ASMultiplexImageNodeDelegate> protocol.
  44. */
  45. @property (nonatomic, readwrite, weak) id <ASMultiplexImageNodeDelegate> delegate;
  46. /**
  47. * @abstract The data source, which must conform to the <ASMultiplexImageNodeDataSource> protocol.
  48. * @discussion This value is required for ASMultiplexImageNode to load images.
  49. */
  50. @property (nonatomic, readwrite, weak) id <ASMultiplexImageNodeDataSource> dataSource;
  51. /**
  52. * @abstract Whether the receiver should download more than just its highest-quality image. Defaults to NO.
  53. *
  54. * @discussion ASMultiplexImageNode immediately loads and displays the first image specified in <imageIdentifiers> (its
  55. * highest-quality image). If that image is not immediately available or cached, the node can download and display
  56. * lesser-quality images. Set `downloadsIntermediateImages` to YES to enable this behaviour.
  57. */
  58. @property (nonatomic, readwrite, assign) BOOL downloadsIntermediateImages;
  59. /**
  60. * @abstract An array of identifiers representing various versions of an image for ASMultiplexImageNode to display.
  61. *
  62. * @discussion An identifier can be any object that conforms to NSObject and NSCopying. The array should be in
  63. * decreasing order of image quality -- that is, the first identifier in the array represents the best version.
  64. *
  65. * @see <downloadsIntermediateImages> for more information on the image loading process.
  66. */
  67. @property (nonatomic, readwrite, copy) NSArray *imageIdentifiers;
  68. /**
  69. * @abstract Notify the receiver that its data source has new UIImages or NSURLs available for <imageIdentifiers>.
  70. *
  71. * @discussion If a higher-quality image than is currently displayed is now available, it will be loaded.
  72. */
  73. - (void)reloadImageIdentifierSources;
  74. /**
  75. * @abstract The identifier for the last image that the receiver loaded, or nil.
  76. *
  77. * @discussion This value may differ from <displayedImageIdentifier> if the image hasn't yet been displayed.
  78. */
  79. @property (nonatomic, readonly) id loadedImageIdentifier;
  80. /**
  81. * @abstract The identifier for the image that the receiver is currently displaying, or nil.
  82. */
  83. @property (nonatomic, readonly) id displayedImageIdentifier;
  84. @end
  85. #pragma mark -
  86. /**
  87. * The methods declared by the ASMultiplexImageNodeDelegate protocol allow the adopting delegate to respond to
  88. * notifications such as began, progressed and finished downloading, updated and displayed an image.
  89. */
  90. @protocol ASMultiplexImageNodeDelegate <NSObject>
  91. @optional
  92. /**
  93. * @abstract Notification that the image node began downloading an image.
  94. * @param imageNode The sender.
  95. * @param imageIdentifier The identifier for the image that is downloading.
  96. */
  97. - (void)multiplexImageNode:(ASMultiplexImageNode *)imageNode didStartDownloadOfImageWithIdentifier:(id)imageIdentifier;
  98. /**
  99. * @abstract Notification that the image node's download progressed.
  100. * @param imageNode The sender.
  101. * @param downloadProgress The progress of the download. Value is between 0.0 and 1.0.
  102. * @param imageIdentifier The identifier for the image that is downloading.
  103. */
  104. - (void)multiplexImageNode:(ASMultiplexImageNode *)imageNode
  105. didUpdateDownloadProgress:(CGFloat)downloadProgress
  106. forImageWithIdentifier:(id)imageIdentifier;
  107. /**
  108. * @abstract Notification that the image node's download has finished.
  109. * @param imageNode The sender.
  110. * @param imageIdentifier The identifier for the image that finished downloading.
  111. * @param error The error that occurred while downloading, if one occurred; nil otherwise.
  112. */
  113. - (void)multiplexImageNode:(ASMultiplexImageNode *)imageNode
  114. didFinishDownloadingImageWithIdentifier:(id)imageIdentifier
  115. error:(NSError *)error;
  116. /**
  117. * @abstract Notification that the image node's image was updated.
  118. * @param imageNode The sender.
  119. * @param image The new image, ready for display.
  120. * @param imageIdentifier The identifier for `image`.
  121. * @param previousImage The old, previously-loaded image.
  122. * @param previousImageIdentifier The identifier for `previousImage`.
  123. * @note This method does not indicate that `image` has been displayed.
  124. * @see <[ASMultiplexImageNodeDelegate multiplexImageNode:didDisplayUpdatedImage:withIdentifier:]>.
  125. */
  126. - (void)multiplexImageNode:(ASMultiplexImageNode *)imageNode
  127. didUpdateImage:(UIImage *)image
  128. withIdentifier:(id)imageIdentifier
  129. fromImage:(UIImage *)previousImage
  130. withIdentifier:(id)previousImageIdentifier;
  131. /**
  132. * @abstract Notification that the image node displayed a new image.
  133. * @param imageNode The sender.
  134. * @param image The new image, now being displayed.
  135. * @param imageIdentifier The identifier for `image`.
  136. * @discussion This method is only called when `image` changes, and not on subsequent redisplays of the same image.
  137. */
  138. - (void)multiplexImageNode:(ASMultiplexImageNode *)imageNode
  139. didDisplayUpdatedImage:(UIImage *)image
  140. withIdentifier:(id)imageIdentifier;
  141. /**
  142. * @abstract Notification that the image node finished displaying an image.
  143. * @param imageNode The sender.
  144. * @discussion This method is called every time an image is displayed, whether or not it has changed.
  145. */
  146. - (void)multiplexImageNodeDidFinishDisplay:(ASMultiplexImageNode *)imageNode;
  147. @end
  148. #pragma mark -
  149. /**
  150. * The ASMultiplexImageNodeDataSource protocol is adopted by an object that provides the multiplex image node,
  151. * for each image identifier, an image or a URL the image node should load.
  152. */
  153. @protocol ASMultiplexImageNodeDataSource <NSObject>
  154. @optional
  155. /**
  156. * @abstract An image for the specified identifier.
  157. * @param imageNode The sender.
  158. * @param imageIdentifier The identifier for the image that should be returned.
  159. * @discussion If the image is already available to the data source, this method should be used in lieu of providing the
  160. * URL to the image via -multiplexImageNode:URLForImageIdentifier:.
  161. * @returns A UIImage corresponding to `imageIdentifier`, or nil if none is available.
  162. */
  163. - (UIImage *)multiplexImageNode:(ASMultiplexImageNode *)imageNode imageForImageIdentifier:(id)imageIdentifier;
  164. /**
  165. * @abstract An image URL for the specified identifier.
  166. * @param imageNode The sender.
  167. * @param imageIdentifier The identifier for the image that will be downloaded.
  168. * @discussion Supported URLs include assets-library, Photo framework URLs (ph://), HTTP, HTTPS, and FTP URLs. If the
  169. * image is already available to the data source, it should be provided via <[ASMultiplexImageNodeDataSource
  170. * multiplexImageNode:imageForImageIdentifier:]> instead.
  171. * @returns An NSURL for the image identified by `imageIdentifier`, or nil if none is available.
  172. */
  173. - (NSURL *)multiplexImageNode:(ASMultiplexImageNode *)imageNode URLForImageIdentifier:(id)imageIdentifier;
  174. @end