You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

610 lines
27 KiB

2 years ago
  1. <br/>
  2. <!-- <p align="left"><img src="https://cloud.githubusercontent.com/assets/1567433/13918338/f8670eea-ef7f-11e5-814d-f15bdfd6b2c0.png" height="180"/></p> -->
  3. <img src="https://user-images.githubusercontent.com/1567433/106092470-5c360000-60fc-11eb-8a41-28229fbf0512.png">
  4. # Powerful Image Loading System
  5. <p align="left">
  6. <img src="https://img.shields.io/cocoapods/v/Nuke.svg?label=version">
  7. <img src="https://img.shields.io/badge/platforms-iOS%2C%20macOS%2C%20watchOS%2C%20tvOS-lightgrey.svg">
  8. <img src="https://github.com/kean/Nuke/workflows/Nuke%20CI/badge.svg">
  9. </p>
  10. > Upgrading from the previous version? Use a [**Migration Guide**](https://github.com/kean/Nuke/blob/9.5.0/Documentation/Migrations).
  11. Nuke provides a simple and efficient way to download and display images in your app. Behind its clear and concise API is an advanced architecture which enables its unique features and offers virtually unlimited possibilities for customization. The primary Nuke feature is [performance](https://kean.blog/post/nuke-9). Nuke is trusted by $1B+ apps.
  12. > **Fast LRU memory and disk cache** · **SwiftUI** · **Smart background decompression** · **Image processing** · **Elegant builder API** · **Resumable downloads** · **Intelligent deduplication** · **Request prioritization** · **Low data mode** · **Prefetching** · **Rate limiting** · **Progressive JPEG, HEIF, WebP, SVG, GIF** · **Alamofire** · **Combine** · **Reactive extensions**
  13. <br/>
  14. ## Sponsors
  15. [![Stream](https://i.imgur.com/oU7XYkk.png)](https://getstream.io/?utm_source=github&utm_medium=nuke&utm_campaign=sponsorship)
  16. Nuke is proudly sponsored by [Stream](https://getstream.io/?utm_source=github&utm_medium=nuke&utm_campaign=sponsorship), the leading provider in enterprise grade [Feed](https://getstream.io/activity-feeds/?utm_source=github&utm_medium=nuke&utm_campaign=sponsorship) & [Chat](https://getstream.io/chat/?utm_source=github&utm_medium=nuke&utm_campaign=sponsorship) APIs. [Try the iOS Chat Tutorial](https://getstream.io/tutorials/ios-chat/?utm_source=github&utm_medium=nuke&utm_campaign=sponsorship).
  17. <br/>
  18. ## Getting Started
  19. Nuke is easy to learn and use. Here is an overview of its APIs and features:
  20. - **Image View Extensions** ‣ [UI Extensions](#image-view-extensions) · [Table View](#in-a-table-view) · [Placeholders, Transitions](#placeholders-transitions-content-modes-tint-colors) · [`ImageRequest`](#imagerequest)
  21. - **Image Processing** ‣ [`Resize`](#resize) · [`Circle`](#circle) · [`RoundedCorners`](#roundedcorners) · [`GaussianBlur`](#gaussianblur) · [`CoreImage`](#coreimagefilter) · [Custom Processors](#custom-processors)
  22. - **Image Pipeline** ‣ [Load Image](#image-pipeline) · [`ImageTask`](#imagetask) · [Customize Image Pipeline](#customize-image-pipeline) · [Default Pipeline](#default-image-pipeline)
  23. - **Caching** ‣ [LRU Memory Cache](#lru-memory-cache) · [HTTP Disk Cache](#http-disk-cache) · [Aggressive LRU Disk Cache](#aggressive-lru-disk-cache) · [Reloading Images](#reloading-images)
  24. - **Advanced Features** ‣ [Prefetching Images](#image-prefetching) · [Progressive Decoding](#progressive-decoding)
  25. - [**Extensions**](#h_plugins) ‣ [FetchImage](#fetch-image) · [Builder](#builder) · [Combine](#combine) · [RxNuke](#rxnuke) · [And More](#h_plugins)
  26. To learn more see a full [**API Reference**](https://kean-org.github.io/docs/nuke/reference/9.5.0/), and check out the [demo project](https://github.com/kean/NukeDemo). When you are ready to install, follow the [**Installation Guide**](https://github.com/kean/Nuke/blob/9.5.0/Documentation/Guides/installation-guide.md). See [**Requirements**](#h_requirements) for a list of supported platforms. If you encounter any issues, please refer to [**FAQ**](https://github.com/kean/Nuke/blob/master/Documentation/Guides/faq.md) or [**Troubleshooting Guide**](https://github.com/kean/Nuke/blob/9.5.0/Documentation/Guides/troubleshooting.md).
  27. <img src="https://img.shields.io/badge/supports-Swift%20Package%20Manager%2C%20CocoaPods%2C%20Carthage-green.svg">
  28. To learn more about the pipeline and the supported formats, see the dedicated guides.
  29. - [**Image Formats**](https://github.com/kean/Nuke/blob/9.5.0/Documentation/Guides/image-formats.md) ‣ [Progressive JPEG](https://github.com/kean/Nuke/blob/9.5.0/Documentation/Guides/image-formats.md#progressive-jpeg) · [HEIF](https://github.com/kean/Nuke/blob/9.5.0/Documentation/Guides/image-formats.md#heif) · [GIF](https://github.com/kean/Nuke/blob/9.5.0/Documentation/Guides/image-formats.md#gif) · [SVG](https://github.com/kean/Nuke/blob/9.5.0/Documentation/Guides/image-formats.md#svg) · [WebP](https://github.com/kean/Nuke/blob/9.5.0/Documentation/Guides/image-formats.md#webp)
  30. - [**Guides**](https://github.com/kean/Nuke/blob/9.5.0/Documentation/Guides) ‣ [Image Pipeline](https://github.com/kean/Nuke/blob/9.5.0/Documentation/Guides/image-pipeline.md) · [Performance](https://github.com/kean/Nuke/blob/9.5.0/Documentation/Guides/performance-guide.md) · [Third-Party Libraries](https://github.com/kean/Nuke/blob/9.5.0/Documentation/Guides/third-party-libraries.md)
  31. - [**Articles**](https://kean.blog) ‣ [Performance](https://kean.blog/post/nuke-9) · [Concurrency](https://kean.blog/post/concurrency) · [Caching](https://kean.blog/post/image-caching) · [Prefetching](https://kean.blog/post/image-preheating)
  32. If you'd like to contribute to Nuke see [**Contributing**](#h_contribute).
  33. <br/>
  34. # Image View Extensions
  35. <img align="right" src="https://user-images.githubusercontent.com/1567433/59150381-d34beb80-8a22-11e9-8d9a-6b1527ffc9e1.png" width="360"/>
  36. Download and display an image in an image view with a single line of code:
  37. ```swift
  38. Nuke.loadImage(with: url, into: imageView)
  39. ```
  40. Nuke will check if the image exists in the memory cache, and if it does, will instantly display it. If not, the image data will be loaded, decoded, processed, and decompressed in the background.
  41. > See [Image Pipeline Guide](https://github.com/kean/Nuke/blob/9.5.0/Documentation/Guides/image-pipeline.md) to learn how images are downloaded and processed.
  42. ### In a Table View
  43. When you request a new image for the existing view, Nuke will prepare it for reuse and cancel any outstanding requests for the view.
  44. ```swift
  45. func tableView(_ tableView: UITableView, cellForItemAt indexPath: IndexPaths) -> UITableViewCell {
  46. /* Create a cell ... */
  47. Nuke.loadImage(with: url, into: cell.imageView)
  48. }
  49. ```
  50. > When the view is deallocated, an associated request gets canceled automatically. To manually cancel the request, call `Nuke.cancelRequest(for: imageView)`.
  51. ### Placeholders, Transitions, Content Modes, Tint Colors
  52. Use `ImageLoadingOptions` to set a `placeholder`, select one of the built-in `transitions`, or provide a custom one.
  53. ```swift
  54. let options = ImageLoadingOptions(
  55. placeholder: UIImage(named: "placeholder"),
  56. transition: .fadeIn(duration: 0.33)
  57. )
  58. Nuke.loadImage(with: url, options: options, into: imageView)
  59. ```
  60. You can even customize content modes or tint colors per image type:
  61. ```swift
  62. let options = ImageLoadingOptions(
  63. placeholder: UIImage(named: "placeholder"),
  64. failureImage: UIImage(named: "failureImage"),
  65. contentModes: .init(success: .scaleAspectFill, failure: .center, placeholder: .center),
  66. tintColors: .init(success: .green, failure: .red, placeholder: .yellow)
  67. )
  68. ```
  69. > In case you want all image views to have the same behavior, you can modify `ImageLoadingOptions.shared`.
  70. Please keep in mind that the built-in extensions for image views are designed to get you up and running as quickly as possible. If you want to have more control, or use some of the advanced features, like animated images, it is recommended to use `ImagePipeline` directly in your custom views.
  71. ### `ImageRequest`
  72. `ImageRequest` allows you to set image processors, change the request priority and more:
  73. ```swift
  74. let request = ImageRequest(
  75. url: URL(string: "http://..."),
  76. processors: [ImageProcessors.Resize(size: imageView.bounds.size)],
  77. cachePolicy: .reloadIgnoringCacheData,
  78. priority: .high
  79. )
  80. ```
  81. > Another way to apply processors is by setting the default `processors` on `ImagePipeline.Configuration`. These processors will be applied to all images loaded by the pipeline. If the request has a non-empty array of `processors`, they are going to be applied instead.
  82. The advanced options available via `ImageRequestOptions`. For example, you can provide a `filteredURL` to be used as a key for caching in case the URL contains transient query parameters.
  83. ```swift
  84. let request = ImageRequest(
  85. url: URL(string: "http://example.com/image.jpeg?token=123")!,
  86. options: ImageRequestOptions(
  87. filteredURL: "http://example.com/image.jpeg"
  88. )
  89. )
  90. ```
  91. > There are more options available, to see all of them check the inline documentation for `ImageRequestOptions`.
  92. <br/>
  93. # Image Processing
  94. <img align="right" src="https://user-images.githubusercontent.com/1567433/59151404-cb944300-8a32-11e9-9c58-dbed9789080f.png" width="360"/>
  95. Nuke features a powerful and efficient image processing infrastructure with multiple built-in processors which you can find in `ImageProcessors` namespace, e.g. `ImageProcessors.Resize`.
  96. > This and other screenshots are from the [demo project](https://github.com/kean/NukeDemo).
  97. ### `Resize`
  98. To resize an image, use `ImageProcessors.Resize`:
  99. ```swift
  100. ImageRequest(url: url, processors: [
  101. ImageProcessors.Resize(size: imageView.bounds.size)
  102. ])
  103. ```
  104. By default, the target size is in points. When the image is loaded, Nuke will downscale it to fill the target area maintaining the aspect ratio. To crop the image set `crop` to `true`. For more options, see `ImageProcessors.Resize` documentation.
  105. > Use an optional [Builder](#builder) package for a more concise API.
  106. >
  107. > pipeline.image(with: URL(string: "https://")!)
  108. > .resize(width: 320)
  109. > .blur(radius: 10)
  110. ### `Circle`
  111. Rounds the corners of an image into a circle with an optional border.
  112. ```swift
  113. ImageRequest(url: url, processors: [
  114. ImageProcessors.Circle()
  115. ])
  116. ```
  117. ### `RoundedCorners`
  118. Rounds the corners of an image to the specified radius. Make sure you resize the image to exactly match the size of the view in which it gets displayed so that the border appears correctly.
  119. ```swift
  120. ImageRequest(url: url, processors: [
  121. ImageProcessors.Circle(radius: 16)
  122. ])
  123. ```
  124. ### `GaussianBlur`
  125. `ImageProcessors.GaussianBlur` blurs the input image using one of the [Core Image](https://developer.apple.com/library/archive/documentation/GraphicsImaging/Reference/CoreImageFilterReference/index.html) filters.
  126. ### `CoreImageFilter`
  127. Apply any of the vast number [Core Image filters](https://developer.apple.com/library/archive/documentation/GraphicsImaging/Reference/CoreImageFilterReference/index.html) using `ImageProcessors.CoreImageFilter`:
  128. ```swift
  129. ImageProcessors.CoreImageFilter(name: "CISepiaTone")
  130. ```
  131. ### Custom Processors
  132. For simple one-off operations, use `ImageProcessors.Anonymous` to create a processor with a closure.
  133. Custom processors need to implement `ImageProcessing` protocol. For the basic image processing needs, implement `process(_:)` method and create an identifier which uniquely identifies the processor. For processors with no input parameters, you can return a static string.
  134. ```swift
  135. public protocol ImageProcessing {
  136. func process(image: UIImage) -> UIImage? // NSImage on macOS
  137. var identifier: String // get
  138. }
  139. ```
  140. If your processor needs to manipulate image metadata (`ImageContainer`), or get access to more information via `ImageProcessingContext`, there is an additional method that you can implement in addition to `process(_:)`.
  141. ```swift
  142. public protocol ImageProcessing {
  143. func process(_ image container: ImageContainer, context: ImageProcessingContext) -> ImageContainer?
  144. }
  145. ```
  146. In addition to `var identifier: String`, you can implement `var hashableIdentifier: AnyHashable` to be used by the memory cache where string manipulations would be too slow. By default, this method returns the `identifier` string. A common approach is to make your processor `Hashable` and return `self` from `hashableIdentifier`.
  147. <br/>
  148. # Image Pipeline
  149. At the core of Nuke is the `ImagePipeline` class. Use the pipeline directly to load images without displaying them:
  150. ```swift
  151. let task = ImagePipeline.shared.loadImage(
  152. with: url,
  153. progress: { _, completed, total in
  154. print("progress updated")
  155. },
  156. completion: { result: Result<ImageResponse, ImagePipeline.Error> in
  157. print("task completed")
  158. }
  159. )
  160. ```
  161. > `loadImage` returns always calls a completion closure asynchronously. To check if the image is stored in a memory cache, use `pipeline.cachedImage(for: url)`.
  162. > To download the data without doing any expensive decoding or processing, use `loadData(with:progress:completion:)`.
  163. ### `ImageTask`
  164. When you start the request, the pipeline returns an `ImageTask` object, which can be used for cancellation and more.
  165. ```swift
  166. task.cancel()
  167. task.priority = .high
  168. ```
  169. ### Customize Image Pipeline
  170. If you want to build a system that fits your specific needs, you won't be disappointed. There are a _lot of things_ to tweak. You can set custom data loaders and caches, configure image encoders and decoders, change the number of concurrent operations for each individual stage, disable and enable features like deduplication and rate limiting, and more.
  171. > To learn more see the inline documentation for `ImagePipeline.Configuration` and [Image Pipeline Guide](https://github.com/kean/Nuke/blob/9.5.0/Documentation/Guides/image-pipeline.md).
  172. <img align="right" src="https://user-images.githubusercontent.com/1567433/59148462-94f60280-8a09-11e9-906a-6c7209b8f8c8.png" width="360"/>
  173. Here are the protocols which can be used for customization:
  174. - `DataLoading` – Download (or return cached) image data
  175. - `DataCaching` – Store image data on disk
  176. - `ImageDecoding` – Convert data into images (see `_ImageDecoding` for new experimental decoding features)
  177. - `ImageEncoding` - Convert images into data
  178. - `ImageProcessing` – Apply image transformations
  179. - `ImageCaching` – Store images into a memory cache
  180. The entire configuration is described by the `ImagePipeline.Configuration` struct. To create a pipeline with a custom configuration either call the `ImagePipeline(configuration:)` initializer or use the convenience one:
  181. ```swift
  182. let pipeline = ImagePipeline {
  183. $0.dataLoader = ...
  184. $0.dataLoadingQueue = ...
  185. $0.imageCache = ...
  186. ...
  187. }
  188. ```
  189. And then set the new pipeline as default:
  190. ```swift
  191. ImagePipeline.shared = pipeline
  192. ```
  193. ### Default Image Pipeline
  194. The default image pipeline is initialized with the following dependencies:
  195. ```swift
  196. // Shared image cache with a size limit of ~20% of available RAM.
  197. imageCache = ImageCache.shared
  198. // Data loader with a default `URLSessionConfiguration` and a custom `URLCache`
  199. // with memory capacity 0, and disk capacity 150 MB.
  200. dataLoader = DataLoader()
  201. // Custom aggressive disk cache is disabled by default.
  202. dataCache = nil
  203. // By default uses the decoder from the global registry and the default encoder.
  204. makeImageDecoder = ImageDecoderRegistry.shared.decoder(for:)
  205. makeImageEncoder = { _ in ImageEncoders.Default() }
  206. ```
  207. Each operation in the pipeline runs on a dedicated queue:
  208. ```swift
  209. dataLoadingQueue.maxConcurrentOperationCount = 6
  210. dataCachingQueue.maxConcurrentOperationCount = 2
  211. imageDecodingQueue.maxConcurrentOperationCount = 1
  212. imageEncodingQueue.maxConcurrentOperationCount = 1
  213. imageProcessingQueue.maxConcurrentOperationCount = 2
  214. imageDecompressingQueue.maxConcurrentOperationCount = 2
  215. ```
  216. There is a list of pipeline settings which you can tweak:
  217. ```swift
  218. // Automatically decompress images in the background by default.
  219. isDecompressionEnabled = true
  220. // Configure what content to store in the custom disk cache.
  221. dataCacheOptions.storedItems = [.finalImage] // [.originalImageData]
  222. // Avoid doing any duplicated work when loading or processing images.
  223. isDeduplicationEnabled = true
  224. // Rate limit the requests to prevent trashing of the subsystems.
  225. isRateLimiterEnabled = true
  226. // Progressive decoding is an opt-in feature because it is resource intensive.
  227. isProgressiveDecodingEnabled = false
  228. // Don't store progressive previews in memory cache.
  229. isStoringPreviewsInMemoryCache = false
  230. // If the data task is terminated (either because of a failure or a
  231. // cancellation) and the image was partially loaded, the next load will
  232. // resume where it was left off.
  233. isResumableDataEnabled = true
  234. ```
  235. And also a few global options shared between all pipelines:
  236. ```swift
  237. // Enable to start using `os_signpost` to monitor the pipeline
  238. // performance using Instruments.
  239. ImagePipeline.Configuration.isSignpostLoggingEnabled = false
  240. ```
  241. <br/>
  242. # Caching
  243. ### LRU Memory Cache
  244. Nuke's default `ImagePipeline` has two cache layers.
  245. First, there is a memory cache for storing processed images which are ready for display.
  246. ```swift
  247. // Configure cache
  248. ImageCache.shared.costLimit = 1024 * 1024 * 100 // 100 MB
  249. ImageCache.shared.countLimit = 100
  250. ImageCache.shared.ttl = 120 // Invalidate image after 120 sec
  251. // Read and write images
  252. let request = ImageRequest(url: url)
  253. ImageCache.shared[request] = ImageContainer(image: image)
  254. let image = ImageCache.shared[request]
  255. // Clear cache
  256. ImageCache.shared.removeAll()
  257. ```
  258. `ImageCache` uses the [LRU](https://en.wikipedia.org/wiki/Cache_replacement_policies#Least_recently_used_(LRU)) algorithm – least recently used entries are removed first during the sweep.
  259. ### HTTP Disk Cache
  260. By default, unprocessed image data is stored using `URLCache`.
  261. ```swift
  262. // Configure cache
  263. DataLoader.sharedUrlCache.diskCapacity = 100
  264. DataLoader.sharedUrlCache.memoryCapacity = 0
  265. // Read and write responses
  266. let request = ImageRequest(url: url)
  267. let _ = DataLoader.sharedUrlCache.cachedResponse(for: request.urlRequest)
  268. DataLoader.sharedUrlCache.removeCachedResponse(for: request.urlRequest)
  269. // Clear cache
  270. DataLoader.sharedUrlCache.removeAllCachedResponses()
  271. ```
  272. ### Aggressive LRU Disk Cache
  273. If HTTP caching is not your cup of tea, you can try using a custom LRU disk cache for fast and reliable *aggressive* data caching (ignores [HTTP cache control](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control)). You can enable it using the pipeline configuration.
  274. ```swift
  275. ImagePipeline {
  276. $0.dataCache = try? DataCache(name: "com.myapp.datacache")
  277. // Also consider disabling the native HTTP cache, see `DataLoader`.
  278. }
  279. ```
  280. By default, the pipeline stores only the original image data. To store downloaded and processed images instead, set `dataCacheOptions.storedItems` to `[.finalImage]`. This option is useful if you want to store processed, e.g. downsampled images, or if you want to transcode images to a more efficient format, like HEIF.
  281. > To save disk space see `ImageEncoders.ImageIO` and `ImageEncoder.isHEIFPreferred` option for HEIF support.
  282. ### Reloading Images
  283. There are two options available. You can remove an image from all cache layers:
  284. ```swift
  285. let request = ImageRequest(url: url)
  286. pipeline.removeCachedImage(for: request)
  287. ```
  288. Another option is to keep the image in cache, but instruct the pipeline to ignore the cached data:
  289. ```swift
  290. let request = ImageRequest(url: url, cachePolicy: .reloadIgnoringCacheData)
  291. Nuke.loadImage(with: request, into: imageView)
  292. ```
  293. > If you are manually constucting a `URLRequest`, make sure to update the respective cache policy.
  294. <br/>
  295. # Advanced Features
  296. ### Image Prefetching
  297. Prefetching images in advance can dramatically improve your app's user experience.
  298. ```swift
  299. // Make sure to keep a strong reference to the prefetcher.
  300. let prefetcher = ImagePrefetcher()
  301. prefetcher.startPrefetching(with: urls)
  302. // Cancels all of the prefetching tasks. You don't need to balance the number of
  303. // `start` and `stop` requests. If you have multiple screens with prefetching,
  304. // create multiple `ImagePrefetcher` instances.
  305. prefetcher.stopPrefetching(with: urls)
  306. ```
  307. > To learn more about other performance optimizations you can do, see [Performance Guide](https://github.com/kean/Nuke/blob/9.5.0/Documentation/Guides/performance-guide.md).
  308. Keep in mind that prefetching takes up users' data and puts extra pressure on CPU and memory. To reduce the CPU and memory usage, you have an option to choose only the disk cache as a prefetching destination:
  309. ```swift
  310. // The prefetcher with `.diskCache` destination will skip image data decoding
  311. // entirely to reduce CPU and memory usage. It will still load the image data
  312. // and store it in disk caches to be used later.
  313. let prefetcher = ImagePrefetcher(destination: .diskCache)
  314. ```
  315. When the user leaves the screen, you can either continue/stop prefetching, or you can pause it using `prefetcher.isPaused` property. The prefetching will finish outstanding tasks (by default, there are only 2 at a time), and pause the rest.
  316. > On iOS, you can use [prefetching APIs](https://developer.apple.com/reference/uikit/uitableviewdatasourceprefetching) in combination with `ImagePrefetcher` to automate the process. To learn more about prefetching, see the [dedicated guide](https://kean.blog/post/image-preheating).
  317. ### Progressive Decoding
  318. To enable progressive image decoding set `isProgressiveDecodingEnabled` configuration option to `true`.
  319. <img align="right" width="360" alt="Progressive JPEG" src="https://user-images.githubusercontent.com/1567433/59148764-3af73c00-8a0d-11e9-9d49-ded2d509380a.png">
  320. ```swift
  321. let pipeline = ImagePipeline {
  322. $0.isProgressiveDecodingEnabled = true
  323. // If `true`, the pipeline will store all of the progressively generated previews
  324. // in the memory cache. All of the previews have `isPreview` flag set to `true`.
  325. $0.isStoringPreviewsInMemoryCache = true
  326. }
  327. ```
  328. And that's it, the pipeline will automatically do the right thing and deliver the progressive scans via `progress` closure as they arrive:
  329. ```swift
  330. let imageView = UIImageView()
  331. let task = ImagePipeline.shared.loadImage(
  332. with: url,
  333. progress: { response, _, _ in
  334. if let response = response {
  335. imageView.image = response.image
  336. }
  337. },
  338. completion: { result in
  339. // Display the final image
  340. }
  341. )
  342. ```
  343. <br/>
  344. <a name="h_plugins"></a>
  345. ## Extensions
  346. There is a variety of extensions available for Nuke:
  347. |Name|Description|
  348. |--|--|
  349. |[**FetchImage**](https://github.com/kean/FetchImage)|SwiftUI integration|
  350. |[**ImagePublisher**](https://github.com/kean/ImagePublisher)|Combine publishers for Nuke|
  351. |[**ImageTaskBuilder**](https://github.com/kean/ImageTaskBuilder)|A fun and convenient way to use Nuke|
  352. |[**Alamofire Plugin**](https://github.com/kean/Nuke-Alamofire-Plugin)|Replace networking layer with [Alamofire](https://github.com/Alamofire/Alamofire) and combine the power of both frameworks|
  353. |[**RxNuke**](https://github.com/kean/RxNuke)|[RxSwift](https://github.com/ReactiveX/RxSwift) extensions for Nuke with examples of common use cases solved by Rx|
  354. |[**WebP Plugin**](https://github.com/ryokosuge/Nuke-WebP-Plugin)| **[Community]** [WebP](https://developers.google.com/speed/webp/) support, built by [Ryo Kosuge](https://github.com/ryokosuge)|
  355. |[**Gifu Plugin**](https://github.com/kean/Nuke-Gifu-Plugin)|Use [Gifu](https://github.com/kaishin/Gifu) to load and display animated GIFs|
  356. |[**FLAnimatedImage Plugin**](https://github.com/kean/Nuke-AnimatedImage-Plugin)|Use [FLAnimatedImage](https://github.com/Flipboard/FLAnimatedImage) to load and display [animated GIFs]((https://www.youtube.com/watch?v=fEJqQMJrET4))|
  357. |[**Xamarin NuGet**](https://github.com/roubachof/Xamarin.Forms.Nuke)| **[Community]** Makes it possible to use Nuke from Xamarin|
  358. <br/>
  359. <a name="fetch-image"></a>
  360. ### [`FetchImage`](https://github.com/kean/FetchImage)
  361. [`FetchImage`](https://github.com/kean/FetchImage) is a Swift package that makes it easy to download images using Nuke and display them in SwiftUI apps. For more info, see the [introductory post](https://kean.blog/post/introducing-fetch-image).
  362. > **Note**: This is an API preview, it might change in the future.
  363. ```swift
  364. public struct ImageView: View {
  365. @ObservedObject var image: FetchImage
  366. public var body: some View {
  367. ZStack {
  368. Rectangle().fill(Color.gray)
  369. image.view?
  370. .resizable()
  371. .aspectRatio(contentMode: .fill)
  372. }
  373. }
  374. }
  375. ```
  376. **Low Data Mode**
  377. [`FetchImage`](https://github.com/kean/FetchImage) also offers built-in support for low-data mode via a special initializer:
  378. ```swift
  379. FetchImage(regularUrl: highQualityUrl, lowDataUrl: lowQualityUrl)
  380. ```
  381. ### Builder
  382. Find the default API a bit boring? Try [ImageTaskBuilder](https://github.com/kean/ImageTaskBuilder), a fun and convenient way to use Nuke.
  383. ```swift
  384. ImagePipeline.shared.image(with: URL(string: "https://")!)
  385. .fill(width: 320)
  386. .blur(radius: 10)
  387. .priority(.high)
  388. .start { result in
  389. print(result)
  390. }
  391. // Returns `ImageTask` when started.
  392. ```
  393. ```swift
  394. let imageView: UIImageView
  395. ImagePipeline.shared.image(with: URL(string: "https://")!)
  396. .fill(width: imageView.size.width)
  397. .display(in: imageView)
  398. ```
  399. ### RxNuke
  400. [RxNuke](https://github.com/kean/RxNuke) adds [RxSwift](https://github.com/ReactiveX/RxSwift) extensions for Nuke and enables common use cases: [Going from low to high resolution](https://github.com/kean/RxNuke#going-from-low-to-high-resolution) | [Loading the first available image](https://github.com/kean/RxNuke#loading-the-first-available-image) | [Showing stale image while validating it](https://github.com/kean/RxNuke#showing-stale-image-while-validating-it) | [Load multiple images, display all at once](https://github.com/kean/RxNuke#load-multiple-images-display-all-at-once) | [Auto retry on failures](https://github.com/kean/RxNuke#auto-retry) | [And more](https://github.com/kean/RxNuke#use-cases)
  401. To get a taste of what you can do with this extension, take a look at how easy it is to load the low resolution image first and then switch to high resolution:
  402. ```swift
  403. let pipeline = ImagePipeline.shared
  404. Observable.concat(pipeline.loadImage(with: lowResUrl).orEmpty,
  405. pipeline.loadImage(with: highResUrl).orEmpty)
  406. .subscribe(onNext: { imageView.image = $0 })
  407. .disposed(by: disposeBag)
  408. ```
  409. ### Combine
  410. [ImagePublisher](https://github.com/kean/ImagePublisher) adds Combine publishers for Nuke and, just like [RxNuke](https://github.com/kean/RxNuke), enables a variety of powerful use cases.
  411. <br/>
  412. <a name="h_contribute"></a>
  413. # Contribution
  414. [Nuke's roadmap](https://trello.com/b/Us4rHryT/nuke) is managed in Trello and is publicly available. If you'd like to contribute, please feel free to create a PR.
  415. <a name="h_requirements"></a>
  416. # Minimum Requirements
  417. | Nuke | Swift | Xcode | Platforms |
  418. |---------------|-----------------|-----------------|---------------------------------------------------|
  419. | Nuke 9.0 | Swift 5.1 | Xcode 11.0 | iOS 11.0 / watchOS 4.0 / macOS 10.13 / tvOS 11.0 |
  420. | Nuke 8.0 | Swift 5.0 | Xcode 10.2 | iOS 10.0 / watchOS 3.0 / macOS 10.12 / tvOS 10.0 |
  421. See [Installation Guide](https://github.com/kean/Nuke/blob/9.5.0/Documentation/Guides/installation-guide.md#h_requirements) for information about the older versions.
  422. # License
  423. Nuke is available under the MIT license. See the LICENSE file for more info.