<commit_before><p align="center"><img src="https://cloud.githubusercontent.com/assets/1567433/6684993/5971ef08-cc3a-11e4-984c-6769e4931497.png" height="100"/>

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. It has an elegant and powerful API that will extend the capabilities of your app.

```swift
let URL = NSURL(string: "http://farm8.staticflickr.com/7315/16455839655_7d6deb1ebf_z_d.jpg")!
let task = ImageManager.shared().taskWithURL(URL) {
    let image = $0.image
}
task.resume()
```

Nuke is a [pipeline](#h_design) that loads images using pluggable components which can be injected in runtime.

> Programming in Objective-C? Try [DFImageManager](https://github.com/kean/DFImageManager).

1. [Getting Started](#h_getting_started)
2. [Usage](#h_usage)
3. [Design](#h_design)
4. [Installation](#install_using_cocopods)
5. [Requirements](#h_requirements)
6. [Contribution](#h_contribution)

## <a name="h_features"></a>Features

- Zero config, yet immense customization and flexibility
- Great performance even on outdated devices, asynchronous and thread safe
- Optional [FLAnimatedImage](https://github.com/Flipboard/FLAnimatedImage) integration

##### Loading
- Uses [NSURLSession](https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSURLSession_class/) with [HTTP/2](https://en.wikipedia.org/wiki/HTTP/2) support
- Uses a single data task for multiple equivalent requests
- [Intelligent preheating](https://github.com/kean/DFImageManager/wiki/Image-Preheating-Guide) 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](https://tools.ietf.org/html/rfc7234) and caching implementation provided by [Foundation](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/URLLoadingSystem/URLLoadingSystem.html)
- Caching is completely transparent to the client
- Two cache layers, including [top level memory cache](https://github.com/kean/DFImageManager/wiki/Image-Caching-Guide) for decompressed images

##### Decoding and Processing
- Background image decompression and scaling in a single step
- Scale large images (~6000x4000 px) and prepare them for display with ease
- Resize and crop loaded images to [fit displayed size](https://developer.apple.com/library/ios/qa/qa1708/_index.html)

##### Advanced
- Image decoder composition
- Image filter composition
- Customize different parts of the framework using dependency injection

## <a name="h_getting_started"></a>Getting Started
- Download the latest [release](https://github.com/kean/Nuke/releases) 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 using CocoaPods](#install_using_cocopods) and enjoy!

## <a name="h_usage"></a>Usage

#### Zero Config Image Loading

```swift
ImageManager.shared().taskWithURL(imageURL) {
    let image = $0.image
}.resume()
```

#### Adding Request Options

```swift
var request = ImageRequest(URL: imageURL)
request.targetSize = CGSize(width: 300.0, height: 400.0) // Set target size in pixels
request.contentMode = .AspectFill

ImageManager.shared().taskWithRequest(request) {
    let image = $0.image
}.resume()
```

#### Using Image Response

```swift
ImageManager.shared().taskWithRequest(request) {
    (response) -> Void 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

```swift
let task = ImageManager.shared().taskWithURL(imageURL) {
    let image = $0.image
}
task.resume()

// Use progress object to track load progress
let progress = task.progress

// Track task state
let state = task.state

// Cancel image task
task.cancel()
```

#### Using UI Components

```swift
let imageView: ImageView = <#view#>
imageView.setImageWithURL(imageURL)
```

#### UICollectionView

```swift
override 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):

```swift
override func collectionView(collectionView: UICollectionView, didEndDisplayingCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) {
    let imageView: ImageView = <#view#>
    imageView.prepareForReuse()
}
```

#### Preheating Images

```swift
let requests = [ImageRequest(URL: imageURL1), ImageRequest(URL: imageURL2)]
ImageManager.shared().startPreheatingImages(requests: requests)

ImageManager.shared().stopPreheatingImages(requests: requests)
```

#### Composing Image Decoders

```swift
let decoder1: ImageDecoding = <#decoder#>
let decoder2: ImageDecoding = <#decoder#>
let composition = ImageDecoderComposition(decoders: [decoder1, decoder2])
```

#### Composing Image Filters

```swift
let processor1: ImageProcessing = <#processor#>
let processor2: ImageProcessing = <#processor#>
let composition = ImageProcessorComposition(processors: [processor1, processor2])
```

#### Customizing Image Manager

```swift<commit_msg>Add applying filters section to readme<commit_after><p align="center"><img src="https://cloud.githubusercontent.com/assets/1567433/6684993/5971ef08-cc3a-11e4-984c-6769e4931497.png" height="100"/>

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. It has an elegant and powerful API that will extend the capabilities of your app.

```swift
let URL = NSURL(string: "http://farm8.staticflickr.com/7315/16455839655_7d6deb1ebf_z_d.jpg")!
let task = ImageManager.shared().taskWithURL(URL) {
    let image = $0.image
}
task.resume()
```

Nuke is a [pipeline](#h_design) that loads images using pluggable components which can be injected in runtime.

> Programming in Objective-C? Try [DFImageManager](https://github.com/kean/DFImageManager).

1. [Getting Started](#h_getting_started)
2. [Usage](#h_usage)
3. [Design](#h_design)
4. [Installation](#install_using_cocopods)
5. [Requirements](#h_requirements)
6. [Contribution](#h_contribution)

## <a name="h_features"></a>Features

- Zero config, yet immense customization and flexibility
- Great performance even on outdated devices, asynchronous and thread safe
- Optional [FLAnimatedImage](https://github.com/Flipboard/FLAnimatedImage) integration

##### Loading
- Uses [NSURLSession](https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSURLSession_class/) with [HTTP/2](https://en.wikipedia.org/wiki/HTTP/2) support
- Uses a single data task for multiple equivalent requests
- [Intelligent preheating](https://github.com/kean/DFImageManager/wiki/Image-Preheating-Guide) 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](https://tools.ietf.org/html/rfc7234) and caching implementation provided by [Foundation](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/URLLoadingSystem/URLLoadingSystem.html)
- Caching is completely transparent to the client
- Two cache layers, including [top level memory cache](https://github.com/kean/DFImageManager/wiki/Image-Caching-Guide) 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](https://developer.apple.com/library/ios/qa/qa1708/_index.html)

##### Advanced
- Image decoder composition
- Image filter composition
- Customize different parts of the framework using dependency injection

## <a name="h_getting_started"></a>Getting Started
- Download the latest [release](https://github.com/kean/Nuke/releases) 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 using CocoaPods](#install_using_cocopods) and enjoy!

## <a name="h_usage"></a>Usage

#### Zero Config Image Loading

```swift
ImageManager.shared().taskWithURL(imageURL) {
    let image = $0.image
}.resume()
```

#### Adding Request Options

```swift
var request = ImageRequest(URL: imageURL)
request.targetSize = CGSize(width: 300.0, height: 400.0) // Set target size in pixels
request.contentMode = .AspectFill

ImageManager.shared().taskWithRequest(request) {
    let image = $0.image
}.resume()
```

#### Using Image Response

```swift
ImageManager.shared().taskWithRequest(request) {
    (response) -> Void 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

```swift
let task = ImageManager.shared().taskWithURL(imageURL) {
    let image = $0.image
}
task.resume()

// Use progress object to track load progress
let progress = task.progress

// Track task state
let state = task.state

// Cancel image task
task.cancel()
```

#### UICollectionView

```swift
override 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):

```swift
override func collectionView(collectionView: UICollectionView, didEndDisplayingCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) {
    let imageView: ImageView = <#view#>
    imageView.prepareForReuse()
}
```

#### Applying Filters

```swift
let filter1: ImageProcessing = <#filter#>
let filter2: ImageProcessing = <#filter#>
let filterComposition = ImageProcessorComposition(processors: [filter1, filter2])

var request = ImageRequest(URL: <#image_url#>)
request.processor = filterComposition

ImageManager.shared().taskWithRequest(request) {
    // Filters are applied
    // Processed images are intelligently cached
    let image = $0.image
}.resume()
```

#### Composing Image Decoders

```swift
let decoder1: ImageDecoding = <#decoder#>
let decoder2: ImageDecoding = <#decoder#>
let composition = ImageDecoderComposition(decoders: [decoder1, decoder2])
```

#### Composing Image Filters

```swift
let processor1: ImageProcessing = <#processor#>
let processor2: ImageProcessing = <#processor#>
let composition = ImageProcessorComposition(processors: [processor1, processor2])
```

#### Preheating Images

```swift
let requests = [ImageRequest(URL: imageURL1), ImageRequest(URL: imageURL2)]
ImageManager.shared().startPreheatingImages(requests: requests)

ImageManager.shared().stopPreheatingImages(requests: requests)
```

#### Customizing Image Manager

```swift
{'fraction_non_alphanumeric': 0.11849486493484077, 'fraction_numerical': 0.018727884698368863, 'mean_word_length': 5.34263820470717, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 41, 'https://': 22, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4342193', 'n_tokens_mistral': 3617, 'n_tokens_neox': 3328, 'n_words': 981}