Advanced pure Swift framework for loading, caching, processing, displaying and preheating images. It uses latest advancements in iOS SDK and doesn't reinvent existing technologies.
Nuke is a pipeline that loads images using multiple dependencies which can be injected in runtime.
Nuke.taskWithURL(URL) {
let image = $0.image
}.resume()
Features
- Zero config, yet immense customization and flexibility
- Great performance even on outdated devices, asynchronous and thread safe
- Optional Alamofire integration
- Optional FLAnimatedImage integration
Loading
- Uses NSURLSession with HTTP/2 support
- Uses a single data task for multiple equivalent requests
- Intelligent preheating of images close to the viewport
- Progress tracking using
NSProgress
Caching
- Instead of reinventing a caching methodology it relies on HTTP cache as defined in HTTP specification and caching implementation provided by Foundation
- Caching is completely transparent to the client
- Two cache layers, including top level memory cache for decompressed images
Decoding and Processing
- Apply image filters
- Background image decompression and scaling in a single step
- Scale large images (~6000x4000 px) and prepare them for display with ease
- Resize loaded images to fit displayed size
Advanced
- Image decoder composition
- Image filter composition
- Customize different parts of the framework using dependency injection
Getting Started
- Download the latest release version
- Experiment with Nuke APIs in a Swift playground
- Take a look at the demo project, it's easy to install with
pod try Nuke
command - Install,
import Nuke
and enjoy!
Usage
Zero Config
Nuke.taskWithURL(imageURL) {
let image = $0.image
}.resume()
Adding Request Options
var request = ImageRequest(URL: imageURL)
request.targetSize = CGSize(width: 300.0, height: 400.0) // Set target size in pixels
request.contentMode = .AspectFill
Nuke.taskWithRequest(request) {
let image = $0.image // Image is resized
}.resume()
Using Image Response
Nuke.taskWithRequest(request) { response in
switch response { // Response is an enum with associated values
case let .Success(image, info):
// Use image and inspect info
case let .Failure(error):
// Handle error
}
}.resume()
Using Image Task
let task = Nuke.taskWithURL(imageURL).resume()
let progress = task.progress // Track progress using NSProgress
let state = task.state // Track task state
task.completion { // Add multiple completions, even for completed task
let image = $0.image
}
task.cancel() // Cancel image task
UICollectionView
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(cellReuseID, forIndexPath: indexPath)
let imageView: ImageView = <#view#>
imageView.prepareForReuse()
imageView.setImageWithURL(imageURL)
return cell
}
Cancel image task as soon as the cell goes offscreen (optional):
func collectionView(collectionView: UICollectionView, didEndDisplayingCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) {
let imageView: ImageView = <#view#>
imageView.prepareForReuse()
}
Applying Filters
let filter1: ImageProcessing = <#filter#>
let filter2: ImageProcessing = <#filter#>
let filterComposition = ImageProcessorComposition(processors: [filter1, filter2])
var request = ImageRequest(URL: <#image_url#>)
request.processor = filterComposition
Nuke.taskWithRequest(request) {
// Filters are applied, filtered image is stored in memory cache
let image = $0.image
}.resume()
Composing Image Filters
let processor1: ImageProcessing = <#processor#>
let processor2: ImageProcessing = <#processor#>
let composition = ImageProcessorComposition(processors: [processor1, processor2])
Composing Image Decoders
let decoder1: ImageDecoding = <#decoder#>
let decoder2: ImageDecoding = <#decoder#>
let composition = ImageDecoderComposition(decoders: [decoder1, decoder2])
Preheating Images
let requests = [ImageRequest(URL: imageURL1), ImageRequest(URL: imageURL2)]
Nuke.startPreheatingImages(requests: requests)
Nuke.stopPreheatingImages(requests: requests)
Customizing Image Manager
let dataLoader: ImageDataLoading = <#data_loader#>
let decoder: ImageDecoding = <#decoder#>
let cache: ImageMemoryCaching = <#cache#>
let configuration = ImageManagerConfiguration(dataLoader: dataLoader, decoder: decoder, cache: cache)
ImageManager.shared = ImageManager(configuration: configuration)
Design
Protocol | Description |
---|---|
ImageManaging |
A high-level API for loading images |
ImageDataLoading |
Performs loading of image data (NSData ) |
ImageDecoding |
Converts NSData to UIImage objects |
ImageProcessing |
Processes decoded images |
ImageMemoryCaching |
Stores processed images into memory cache |
Installation
CocoaPods
CocoaPods is a dependency manager for Cocoa projects. If you are not familiar with CocoaPods the best place to start would be CocoaPods guides. To install Nuke add a dependency in your Podfile:
# Podfile
# platform :ios, '8.0'
# platform :watchos, '2.0'
# use_frameworks!
pod 'Nuke'
By default it will install these subspecs (if they are available for your platform):
Nuke/Core
- core classesNuke/UI
- UI components
There are two more optional subspec:
Nuke/Alamofire
- Alamofire integrationNuke/GIF
- FLAnimatedImage integration
Carthage
Carthage is a decentralized dependency manager for Cocoa projects. Nuke has a limitied Carthage support that doesn't feature FLAnimatedImage and Alamofire integration. To install Nuke add a dependency to your Cartfile:
github 'Nuke'
Requirements
- iOS 8.0+ / watchOS 2.0+
- Xcode 7.0+, Swift 2.0+
Contribution
- If you need help, use Stack Overflow. (Tag 'iosnuke')
- If you'd like to ask a general question, use Stack Overflow.
- If you found a bug, and can provide steps to reproduce it, open an issue.
- If you have a feature request, open an issue.
- If you want to contribute, branch of the
develop
branch and submit a pull request.
Contacts
License
Nuke is available under the MIT license. See the LICENSE file for more info.