Advanced pure Swift framework for loading, processing, caching, displaying and preheating images.
var request = ImageRequest(URLRequest: <#NSURLRequest#>)
request.targetSize = CGSize(width: 200, height: 200) // Resize image
request.processor = <#ImageProcessing#> // Apply image filters
Nuke.taskWithRequest(request) { response in
let image = response.image
}.resume()
Features
- Zero config & user-friendly
- Performant, asynchronous, thread safe
- Optional Alamofire plugin
- Optional AnimatedImage plugin
- Beautiful playground and complete documentation included
Loading
- Uses NSURLSession with HTTP/2 support
- Uses a single data task for multiple equivalent requests
- Automated preheating of images close to the viewport
- Full featured extensions for UI components
Caching
- Doesn't reinvent caching, relies on HTTP cache and its implementation in Foundation
- Caching is completely transparent to the client
- Two cache layers including auto purging memory cache
Processing
- Create and apply image filters
- Background image decompression and scaling in a single step
- Resize loaded images to fit displayed size
Advanced
- Compose image filters
- Compose image decoders
- Nuke is a pipeline that loads images using injectable dependencies
Requirements
- iOS 8.0+ / watchOS 2.0+ / OS X 10.9+ / tvOS 9.0+
- Xcode 7.1+, Swift 2.0+
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(URLRequest: <#NSURLRequest#>)
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 {
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()
task.progress = { completed, total in
// Update progress
}
let state = task.state // Track task state
task.completion { // Add multiple completions, even for completed task
let image = $0.image
}
task.cancel()
Using UI Extensions
let imageView = UIImageView()
// let task = imageView.nk_setImageWithURL(<#NSURL#>)
let task = imageView.nk_setImageWithRequest(<#ImageRequest#>, options: <#ImageViewLoadingOptions?#>)
Adding UI Extensions
Nuke makes it extremely easy to add full-featured image loading extensions to UI components
extension MKAnnotationView: ImageDisplayingView, ImageLoadingView {
// That's it, you get default implementation of all methods in ImageLoadingView protocol
public var nk_image: UIImage? {
get { return self.image }
set { self.image = newValue }
}
}
UICollectionView
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(cellReuseID, forIndexPath: indexPath)
let imageView: ImageView = <#view#>
imageView.nk_prepareForReuse()
imageView.nk_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.nk_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 Filters
let processor1: ImageProcessing = <#processor#>
let processor2: ImageProcessing = <#processor#>
let composition = ImageProcessorComposition(processors: [processor1, processor2])
Preheating Images
let requests = [ImageRequest(URL: imageURL1), ImageRequest(URL: imageURL2)]
Nuke.startPreheatingImages(requests: requests)
Nuke.stopPreheatingImages(requests: requests)
Automate Preheating
let preheater = ImagePreheatingControllerForCollectionView(collectionView: <#collectionView#>)
preheater.delegate = self // Signals when preheat window changes
Customizing Image Manager
let dataLoader: ImageDataLoading = <#dataLoader#>
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 |
---|---|
ImageManager |
A top-level API for managing 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
To install Nuke add a dependency to your Podfile:
# source 'https://github.com/CocoaPods/Specs.git'
# use_frameworks!
# platform :ios, "8.0" / :watchos, "2.0" / :osx, "10.9" / :tvos, "9.0"
pod "Nuke"
pod "Nuke-Alamofire-Plugin" # optional
pod "Nuke-AnimatedImage-Plugin" # optional
Carthage
To install Nuke add a dependency to your Cartfile:
github "kean/Nuke"
github "kean/Nuke-Alamofire-Plugin" # optional
Import
Import installed modules in your source files
import Nuke
import NukeAlamofirePlugin
import NukeAnimatedImagePlugin
Satellite Projects
- Nuke Alamofire Plugin - Alamofire plugin for Nuke that allows you to use Alamofire for networking
- Nuke AnimatedImage Plugin - FLAnimatedImage plugin for Nuke that allows you to load and display animated GIFs
- Nuke Integration Tests - Contains CocoaPods and Carthage integration tests for Nuke
Contacts
License
Nuke is available under the MIT license. See the LICENSE file for more info.