Skip to content

Itelios/Nuke

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Micro-framework for loading, processing, caching and preheating images.

Features

  • Simple API, zero configuration required
  • Performant, asynchronous, thread-safe
  • Extensions for UI components
  • Two cache layers including auto purging memory cache
  • Background image decompression
  • Custom image filters
  • Deduplication of equivalent requests
  • Automate preheating (prefetching)
  • Pipeline with injectable dependencies
  • Alamofire and FLAnimatedImage plugins
  • iOS 8.0 / watchOS 2.0 / OS X 10.10 / tvOS 9.0
  • Xcode 8, Swift 3

Getting Started

Usage

Loading Images

Nuke.loadImage(with: URL(string: "http://...")!).then { image in
    print("\(image) loaded")
}

Customizing Requests

Each image request is represented by Request struct which can be initialized either with URL or URLRequest.

Nuke.loadImage(with: Request(urlRequest: URLRequest(url: (URL: "http://...")!)))

Using Response

Each of the methods from loadImage(with:...) family returns a Promise<Image> with expected methods like then, catch, etc.

// The closures get called on the main thread by default.
Nuke.loadImage(with: URL(string: "http://...")!)
    .then { image in print("\(image) loaded") }
    .catch { error in print("catched \(error)") }

It also has a more conventional in iOS completion method:

Nuke.loadImage(with: URL(string: "http://...")!).completion { resolution in
    switch resolution {
    case let .fulfilled(image): print("\(image) loaded")
    case let .rejected(error): print("catched \(error)") 
    }
}

Cancelling Request

If you need to cancel your requests you should create them with a CancellationToken.

let cts = CancellationTokenSource()
Nuke.loadImage(with: URL(string: "http://...")!, token: cts.token).then { image in
    print("got \(image)")
}
cts.cancel()

This pattern provides a simple and reliable model for cooperative cancellation of asynchronous operations.

Using UI Extensions

Nuke provides UI extensions to make image loading as simple as possible.

let imageView = UIImageView()

// Loads and displays an image for the given URL. Previously started request is cancelled.
imageView.nk_setImage(with: URL(string: "http://...")!)

Adding UI Extensions

It's also extremely easy to add image loading capabilities (trait) to custom UI components. All you need is to implement ResponseHandling protocol in your view which consists of a single method nk_handle(response:isFromMemoryCache:).

extension MKAnnotationView: ResponseHandling {
    public func nk_handle(response: PromiseResolution<Image>, isFromMemoryCache: Bool) {
        // display image, handle error, etc
    }
}

Each view that implements ResponseHandling gets a bunch of method for loading images.

let view = MKAnnotationView()
view.nk_setImage(with: Request(urlRequest: <#request#>))

Customizing UI Extensions

Each view with image loading trait also get and an associated ViewContext object which is your primary interface for customizing image loading.

let view = UIImageView()
view.nk_context.loader = <#loader#> // `Loader.shared` by default.
view.nk_context.cache = <#cache#> // `Cache.shared` by default.
view.nk_context.handler = { _ in // Overwrite deafult handler.
    // Handler response
}

UICollection(Table)View

When you display a collection of images it becomes quite tedious to manage tasks associated with image cells. Nuke takes care of all that complexity for you:

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier(cellReuseID, forIndexPath: indexPath)
    let imageView: ImageView = <#view#>
    imageView.image = nil
    imageView.nk_setImage(with: imageURL)
    return cell
}

Applying Filters

Nuke defines a simple Processing protocol that represents image filters. It takes just a couple line of code to create your own filters. You can apply filters by adding them to the Request.

let filter1: Processing = <#filter#>
let filter2: Processing = <#filter#>

var request = Request(url: <#image_url#>)
request.add(processor: filter1)
request.add(processor: filter2)

Nuke.loadImage(with: request).then { image in
    // Filters are applied, processed image
}.resume()

Creating Filters

Processing protocol consists of a single method process(image: Image) -> Image?. Here's an example of custom image filter that uses Core Image. For more info see Core Image Integration Guide.

struct ImageFilterGaussianBlur: Processing {
    private let radius: Int
    init(radius: Int = 8) {
        self.radius = radius
    }

    func process(image: UIImage) -> UIImage? {
        // The `applyFilter` function is not shipped with Nuke.
        return image.applyFilter(CIFilter(name: "CIGaussianBlur", withInputParameters: ["inputRadius" : self.radius]))
    }

    // `Processing` protocol also requires filters to be `Hashable`. 
    // Nuke compares filters to be able to identify cached images and deduplicate equivalent requests.
    func ==(lhs: ImageFilterGaussianBlur, rhs: ImageFilterGaussianBlur) -> Bool {
        return lhs.radius == rhs.radius
    }
}

Preheating Images

Preheating means loading and caching images ahead of time in anticipation of its use. Nuke provides a Preheater class with a set of self-explanatory methods for image preheating which were inspired by PHImageManager:

let preheater = Preheater(loader: Loader.shared)

// User enters the screen:
let requests = [Request(url: imageURL1), Request(url: imageURL2), ...]
preheater.startPreheating(for: requests)

// User leaves the screen:
preheater.stopPreheating(for: requests)

Automating Preheating

You can use Nuke with Preheat library which automates preheating of content in UICollectionView and UITableView. For more info see Image Preheating Guide, Nuke's demo project, and Preheat documentation.

let preheater = Nuke.Preheater(loader: Loader.shared)
let controller = Preheat.Controller(view: <#collectionView#>)
controller.handler = { addedIndexPaths, removedIndexPaths in
    preheater.startPreheating(for: requests(for: addedIndexPaths))
    preheater.stopPreheating(for: requests(for: removedIndexPaths))
}

Caching Images

Nuke provides both on-disk and in-memory caching.

For on-disk caching it relies on URLCache. The URLCache is used to cache original image data downloaded from the server. This class a part of the URL Loading System's cache management, which relies on HTTP cache.

As an alternative to URLCache Nuke provides a DataCaching protocol that allows you to easily integrate any third-party caching library.

For on-memory caching Nuke provides Caching protocol and its implementation in Cache class built on top of Foundation.Cache. The Cache is used for fast access to processed images that are ready for display.

The combination of two cache layers results in a high performance caching system. For more info see Image Caching Guide which provides a comprehensive look at HTTP cache, URL Loading System and NSCache.

Design

Protocol Description
Loading A top-level API for loading images
DataLoading Performs loading of image data (Data)
DataCaching Stores data into disk cache (optional)
DataDecoding Converts Data with URLResponse to Image objects
Processing Processes images (optional)
Caching Stores processed images into memory cache

Installation

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.10" / :tvos, "9.0"

pod "Nuke"
pod "Nuke-Alamofire-Plugin" # optional
pod "Nuke-AnimatedImage-Plugin" # optional

To install Nuke add a dependency to your Cartfile:

github "kean/Nuke"
github "kean/Nuke-Alamofire-Plugin" # optional
github "kean/Nuke-AnimatedImage-Plugin" # optional

Import

Import installed modules in your source files

import Nuke
import NukeAlamofirePlugin
import NukeAnimatedImagePlugin

Satellite Projects

  • Preheat - Automates preheating (precaching) of content in UITableView and UICollectionView
  • 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

Contacts

License

Nuke is available under the MIT license. See the LICENSE file for more info.

About

Micro-framework for loading, processing, caching and preheating images

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Swift 95.6%
  • Shell 2.8%
  • Ruby 1.4%
  • Objective-C 0.2%