Nuke v9.0.0-beta.1 Release Notes
Release Date: 2020-04-01 // almost 4 years ago-
🚀 Nuke 9 is the best release so far with refinements across the entire framework.
SwiftUI · Combine · Task builder API · New advanced set of core protocols for power-users · HEIF · Transcoding images in disk cache · Progressive decoding performance improvements · Improved resizing APIs · Automatic registering of decoders · SVG · And More
📚 Most of the Nuke APIs are source compatible with Nuke 8. There is also a Nuke 9 Migration Guide (WIP) to help with migration.
Overview
The primary focus of this release was to build on top the infrastructure introduced in Nuke 8 to deliver more and better advanced features while keeping the easy things easy. To achieve this, in Nuke 9 all core protocols, like
ImageProcessing
,ImageEncoding
,ImageDecoding
, now have a basic subset of methods that you must implement, and then there are new advanced methods which give you full control.Taking cues from Combine, all processors are now available in
ImageProcessors
namespace, all encoders are now available inImageEncoders
namespace... you get the idea.📦 Along with Nuke 9, three new amazing Swift packages were introduced:
- FetchImage which makes it easy to use Nuke with SwiftUI
- ImagePublisher with Combine publishers for Nuke
And finally ImageTaskBuilder which introduces a new fun and convenient way to use Nuke. I really love this package. Just look at these APIs:
ImagePipeline.shared.image(with: URL(string: "https://")!) .resize(width: 320) .blur(radius: 10) .priority(.high) .load { result inprint(result) }
I would also like to highlight two other changes.
First, there is a completely new README and two new guides:
- Image Pipeline Guide with a detailed description of how the pipeline delivers images
- Image Formats Guide with an overview of the improved decoding/encoding infrastructure and information how to support variety of image formats: GIF, HEIF, SVG, WeP, and more.
There is also a new Troubleshooting Guide. I would really recommend going through the updated documentation.
📦 Another small but delightful change the demo project which can now be run by simply clicking on the project and running it, all thank to Swift Package Manager magic.
🔄 Changelog
General Improvements
- ⬆️ Bump minimum platform version requirements. The minimum iOS version is now iOS 11 which is a 64-bit only system. This is great news if you are installing your dependencies using Carthage as Nuke is now going to compile twice as fast: no need to compile for
i386
andarmv7
anymore.
📚 Documentation Improvements
- Rewrite most of the README
- Add a completely new Image Pipeline Guide ](https://github.com/kean/Nuke/blob/9.0.0-beta.1/Documentation/Guides/image-pipeline.md) which describes in detail how the pipeline works.
- Add a new Image Formats Guide
ImageContainer
🚀 This release introduces
ImageContainer
type. It is integrated throught the framework instead ofPlatformImage
.Reasoning
- Separate responsibility.
ImageResponse
- result of the current request with information about the current request, e.g.URLResponse
that was received.ImageContainer
- the actual downloaded and processed image regardless of the request - Stop relying on Objective-C runtime which
animatedImageData
was using - Stop relying on extending Objective-C classes like
UIImage
- ➕ Add type-safe way to attach additional information to downloaded images
🔄 Changes
⚡️ Update
ImageCaching
protocol to storeImageContainer
instead ofImageResponse
.ImageResponse
is a result of the individual request, it should not be saved in caches.public protocol ImageCaching: AnyObject { subscript(request: ImageRequest) -> ImageContainer?}
⚡️ Update
ImagePipeline.cachedImage(for:)
method to returnImageContainer
🗄 Deprecate
PlatformImage.animatedImageData
, please useImageContainer.data
instead🗄 Deprecated
ImagePipelineConfiguration.isAnimatedImageDataEnabled
, the defaultImageDecoder
now setImageContainer.data
automatically when it recognizes GIF format
ImageProcessing
improvementsThere are now two levels of image processing APIs. For the basic processing needs, implement the following method:
func process(\_ image: UIImage) -\> UIImage? // NSImage on macOS
📇 If your processor needs to manipulate image metadata (
ImageContainer
), or get access to more information via the context (ImageProcessingContext
), there is now an additional method that allows you to do that:func process(\_ container: ImageContainer, context: ImageProcessingContext) -\> ImageContainer?
- 🚚 All image processors are now available
ImageProcessors
namespace so it is now easier to find the ones you are looking for. Unrelated types were moved toImageProcessingOption
. - ➕ Add
ImageResponse
toImageProcessingContext
- 🆕 New convenience
ImageProcessors.Resize.init(width:)
andImageProcessors.Resize.init(height:)
initializers
🚧
ImageDecoding
Improvements (WIP)➕ Add a new way to register the decoders in
ImageDecoderRegistry
withImageDecoderRegistering
protocol.public func register<Decoder: ImageDecoderRegistering>(_ decoder: Decoder.Type)
- #354/// An image decoder which supports automatically registering in the decoder register.public protocol ImageDecoderRegistering: ImageDecoding { init?(data: Data, context: ImageDecodingContext) // Optionalinit?(partiallyDownloadedData data: Data, context: ImageDecodingContext) }
0️⃣ The default decoder now implementes
ImageDecoderRegistering
protocol⚡️ Update the way decoders are created. Now if the decoder registry can't create a decoder for the partially downloaded data, the pipeline will no longer create (failing) decoding operation reducing the pressure on the decoding queue
Rework
ImageDecoding
protocol👍 Nuke now supports decompression and processing of images that require image data to work
🗄 Deprecate
ImageResponse.scanNumber
, the scan number is now passed inImageContainer.userInfo[ImageDecodert.scanNumberKey]
(this is a format-specific feature and that's why I made it non-type safe and somewhat hidden). Previusly it was also only working for the defaultImageDecoders.Default
. Now any decoder can pass scan number, or any other information usingImageContainer.userInfo
All decoders are now defined in
ImageDecoders
namespace➕ Add
ImageDecoders.Empty
➕ Add
ImageType
struct
ImageEncoding
Improvements#353 - There are now two levels of image encoding APIs. For the basic encoding needs, implement the following method:
func encode(\_ image: UIImage) -\> UIImage? // NSImage on macOS
📇 If your encoders needs to manipulate image metadata (
ImageContainer
), or get access to more information via the context (ImageEncodingContext
), there is now an additional method that allows you to do that:func encode(\_ container: ImageContainer, context: ImageEncodingContext) -\> Data?
- All image encoders are now available
ImageEncoders
namespace so it is now easier to find the ones you are looking for. - ➕ Add
ImageEncoders.ImageIO
with HEIF support - #344 - 🔧 The default adaptive encoder now uses
ImageEncoders.ImageIO
under the hood and can be configured to support HEIF
Progressive Decoding Improvements
- You can now opt-in to store progressively generated previews in the memory cache by setting the pipeline option
isStoringPreviewsInMemoryCache
totrue
. All of the previews haveisPreview
flag set totrue
. - $352
👌 Improved Cache For Processed Images - #345
🚀 Nuke 9 revisits data cache for processed images feature introduced in Nuke 8.0 and fixes all the rough edges around it.
There are two primary changes.
🗄 1. Deprecate
isDataCachingForOriginalImageDataEnabled
andisDataCachingForProcessedImagesEnabled
properties.These properties were replaced with a new
DataCacheOptions
.public struct DataCacheOptions { /// Specifies which content to store in the `dataCache`. By default, the/// pipeline only stores the original image data downloaded using `dataLoader`./// It can be configured to encode and store processed images instead.////// - note: If you are creating multiple versions of the same image using/// different processors, it might be worse enabling both `.originalData`/// and `.encodedImages` cache to reuse the same downloaded data.////// - note: It might be worth enabling `.encodedImages` if you want to/// transcode downloaded images into a more efficient format, like HEIF.public var storedItems: Set\<DataCacheItem\> = [.originalImageData] }public enum DataCacheItem { /// Originl image data.case originalImageData/// Final image with all processors applied.case finalImage}
📚 Now we no longer rely on documentation to make sure that you disable data cache for original image data when you decide to cache processed images instead.
2. Rework
DataCacheItem.finalImage
behavior.🗄 The primary reason for deprecation is a significantly changed behavior of data cache for processed images.
👀 The initial version introduced back in Nuke 8.0 never really made sense. For example, only images for requests with processors were stored, but not the ones without. You can see how this could be a problem, especially if you disable data cache for original image data which was a recommended option.
🔧 The new behavior is much simpler. You set
configuration.dataCacheOptions.storedItems
to[. finalImage]
, and Nuke encodes and stores all of the downloaded images, regardless of whether they were processed or not.DataCache
Improvements - #350⚡️ Nuke 9 realized the original vision for
DataCache
. The updated staging/flushing mechanism now performs flushes on certain intervals instead of on every write. This makes some of the newDataCache
features possible.- 🔀
flush
not performs synchronously - ➕ Add
flush(for:)
methods which allows to flush changes on disk only for the given key - ➕ Add public property
let queue: DispatchQueue
- ➕ Add public method
func url(for key: Key) -> URL?
Other
ImagePreheater
now automatically cancels all of the outstanding tasks on deinit - #349ImagePipeline
now hasfunc cacheKey(for request: ImageRequest, item: DataCacheItem) -> String
method which return a key for disk cache- 🔄 Change the type of
ImageRequest.userInfo
fromAny?
to[AnyHashable: Any]
- ✂ Remove
DFCache
from demo - #347 - ✂ Remove
FLAnimatedImage
and Carthage usage from demo - #348 - Migrate to Swift 5.1 - #351