Nuke Tutorial for iOS: Getting Started

In this Nuke tutorial, you’ll learn how to integrate Nuke using Swift Package Manager and use it to load remote images, both with and without Combine. By Ehab Amer.

Leave a rating/review
Download materials
Save for later
Update note: Ehab Yosry Amer updated this tutorial for iOS 13, Xcode 11 and, Swift 5. Yono Mittlefehldt wrote the original.

Each year, the newest iPhone camera gets better and better. But do you know who has the best cameras? No, not the modeling agency that does your headshots. It’s NASA!

And what’s the best subject matter for them to photograph? Again, unless you work for NASA, the answer is, unfortunately, not you. It’s SPACE! But you’re a close second. :]

Wouldn’t it be nice to have an app that displays NASA’s beautiful photos so you could look at them on your phone whenever you want? The only problem is that some of these photos of space are enormous — like 60MB enormous. And to top it off, they don’t have thumbnails available.

You already dread having to write the tons of boilerplate code associated with OperationQueue. If only there were a better way.

Good news! There is a better way in the form of a third-party library called Nuke.

In this Nuke tutorial, you’ll learn how to:

  • Integrate Nuke into your project using the Swift Package Manager.
  • Load remote images while maintaining the app’s responsiveness.
  • Resize photos on the fly to keep memory usage under control.
  • Integrate Nuke’s Combine extension called ImagePublisher.
  • Use Combine in your project to load different image sizes consecutively.

Ready to explore space from the comfort of your iPhone? Time to get started!

Getting Started

Click the Download Materials button at the top or bottom of this tutorial to download the resources you’ll need. Open the starter project, then build and run. Take a look around the app at your leisure.

The Far Out Photos app grabs photos from NASA’s website and displays them in a UICollectionView-based gallery. Tapping one of the beautiful photos brings it up in full screen.

Unfortunately, there’s a major problem with this app. It’s slow and unresponsive. This is because all network requests for images are done on the main thread, so they interfere with your ability to scroll. Additionally, there’s no caching so images are re-fetched each time they’re loaded.

Annoyed yellow monster with closed eyes

You’re going to use Nuke to fix this app and get it running smoothly.

The former planet Pluto

Setting up Nuke

You have a few options for integrating Nuke into your project, but for this tutorial, you’ll use Swift Package Manager, or SwiftPM. It’s an easy way to install packages in your project that Apple introduced in Xcode 11.

To learn more about SwiftPM, check out the Swift Package Manager for iOS tutorial.

Installing with Swift Package Manager

To add a package, go to File ▸ Swift Packages ▸ Add Package Dependency.

Adding a package with SwiftPM

This opens a dialog box to choose the package you want to install. Enter the URL in the text field and click Next.

Nuke URL in SwiftPM Dialogue

Select Version for the rule, and with Up to Next Major from the drop-down menu, and enter 9.1.0 in the box. This specifies that the version will be a minimum of 9.1.0 and up to a maximum of, but not including, 10.0.0. Then select Next and wait for Xcode to verify the package.

Nuke version settings in SwiftPM

Make sure the target Far Out Photos is selected and click Finish.

Make sure the target is selected

Your Project navigator should look like this when the package is installed.

Project Navigation after package is installed

With that done, it’s time to dive into Nuke.

Note: You may see a different patch number — the third number in the version — since Nuke is still under active development.

Using Nuke: Basic Mode

The first thing you’re going to fix is the terrible responsiveness of the app when scrolling through the gallery.

To get started, open PhotoGalleryViewController.swift. Add the following to the top of the file:

import Nuke

Next, find collectionView(_:cellForItemAt:). In this method, you should see the following code:

if let imageData = try? Data(contentsOf: photoURLs[indexPath.row]),
  let image = UIImage(data: imageData) {
    cell.imageView.image = image
} else {
  cell.imageView.image = nil

This code inefficiently fetches the photo from the provided URL and assigns it to the image view within the collection view cell, blocking the main thread in the whole process.

Delete those seven lines and replace them with the following:

// 1
let url = photoURLs[indexPath.row]

// 2
Nuke.loadImage(with: url, into: cell.imageView)

In this code, you:

  1. Grab the URL for the correct photo based on the cell’s index path.
  2. Use Nuke to load the image from the URL directly into the cell’s image view. Nuke is doing all of the heavy lifting under-the-hood. It loads the image on a background thread and assigns it to the image view.

That’s it! Much easier than expected right? :]

Build and run. You should notice one major improvement. You can now smoothly scroll the gallery view!

Smooth scrolling in gallery after using Nuke

Setting Loading Options

That’s a great start, but there’s something very important still missing. The app doesn’t give the user visual feedback that images are coming. Instead, if users scroll fast enough, they’ll only be greeted with an almost solid black screen.

If only Nuke had some way to show an image in place of the loading image, a placeholder if you will.

Today is your lucky day. It does!

Nuke has a struct called ImageLoadingOptions, which allows you to change how Nuke presents images, including setting a placeholder image.

Back in collectionView(_:cellForItemAt:), replace the code you just wrote with the following:

let url = photoURLs[indexPath.row]

// 1
let options = ImageLoadingOptions(
  placeholder: UIImage(named: "dark-moon"),
  transition: .fadeIn(duration: 0.5)
// 2 
Nuke.loadImage(with: url, options: options, into: cell.imageView)

Here you:

  1. Create an ImageLoadingOptions struct. You set the placeholder image to the image named dark-moon and configure the transition from the placeholder image to the image fetched from the network. In this case, you set the transition as a fade-in over 0.5 seconds.
  2. Use Nuke to load the image from the URL directly into the cell’s image view, just like before, but this time using the options you just configured.

Now, build and run the app. You should see the placeholder images fade to reveal the real images as they are loaded.

A placeholder image is shown until the original is loaded and the cross fade

Fantastic job! You’ve already greatly improved the app with just a few lines of code.