Chapters

Hide chapters

iOS Test-Driven Development by Tutorials

Second Edition · iOS 15 · Swift 5.5 · Xcode 13

10. ImageClient
Written by Joshua Greene

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

In the last chapter, you used DogPatchClient to download and display dogs. Each Dog has an imageURL, but you haven’t used it so far. While you could download images by making network requests directly within ListingsViewController, you wouldn’t be able to use that logic anywhere else.

Instead, you’ll do TDD to create an ImageClient for handling images. You can use ImageClient anywhere you need it in the app.

You’ll work through these steps in this chapter:

  • Set up the image client.
  • Create an image client protocol.
  • Download an image from a URL.
  • Cache tasks and images based on their URL.
  • Set an image from a URL on an image view.
  • Use the image client to display images.

Getting started

Feel free to use your project from the last chapter. If you want a fresh start, navigate to this chapter’s starter directory, open the DogPatch subdirectory and then open DogPatch.xcodeproj.

Your first step is going to be to get everything set up for your image client. Here’s how.

Setting up the image client

Another developer (ahem, you’re welcome) has already done TDD for ImageClient and its properties. To keep the focus on new concepts, this section will fast-track you through adding this code.

Creating an image client protocol

Similar to DogPatchClient, you’ll create a protocol for the ImageClient to enable you to mock and verify its use.

Downloading an image

You next need to implement downloadImage(fromURL:completion:).

Handling the happy path

You’re now ready to handle the happy path, downloading an image successfully. Add this test next:

Handling the error path

You also need to handle the error case. Add this test right after the last one:

Dispatching an image

Next, you need to ensure that completion dispatches to the responseQueue whenever your app successfully downloads an image. Add this test to verify this:

Dispatching an error

You also need to verify errors are dispatched to the responseQueue. Add this test right after the last one:

Caching

Your ImageClient is really coming along, but it’s still missing a critical piece of functionality: Caching. Specifically, you need to cache images that the user has already downloaded.

Setting an image view from a URL

Remember how you declared another method on ImageService, setImage(on imageView: fromURL url: withPlaceholder image:)?

Canceling a cached task

First, add this test to validate that you’ve canceled the existing task when setImageOnImageView is called, ignoring the compiler error for now:

Setting a placeholder image

Next, add this test to ensure the placeholder image is set on the imageView:

Caching the download image task

Next, you need to call downloadImage and cache the download task for the image view. Add this test right after the last one:

Removing the cached task

When downloadImage completes, you also need to remove task from the cache. Add this test for this:

Setting the image on image view

Lastly, you need to set the downloaded image on the image view. Add this test right after the last one:

Handling a download image error

In the case of an error, you’ll simply not set the image and instead will print a message to the console. To verify this happens, add the following test next:

Using the image client

Great job implementing the ImageClient! You’re now ready to use it in ListingsViewController.

Key points

In this chapter, you learned how to do TDD for an image client. Here are the key points:

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2026 Kodeco Inc.

You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now