iOS: Downloading Images Asynchronously (And Making Your UITableView Scroll Fast) is HARD

When I was first starting out as an iOS developer, I ran into an issue that every iOS developer faces sooner rather than later: How to Download Images Asynchronously. After I figured it out (or so I thought), I of course blogged about it.

But although my solution worked at first glance, it has a lot of issues:

  • Since the images are loaded asynchronously and the table view cells are re-usable, there is a big chance that your image will be loaded in the wrong cell. There needs to be a way to check that when the image downloads, the cell is still referring to the correct indexPath.
  • My caching system is super primitive – it stores the image in memory in a dictionary of objects. Obviously, that is not scalable at all.
  • The code is overall horrible in terms of Massive View Controller, etc 😁

To do it right, you’ll need to make something that:

  • Downloads an image asynchronously from an image URL – you can easily use NSURLSession for that.
  • From @alexito4:  It tracks ongoing request in order to not try to fetch same image twice while being downloaded.
  • Stores downloaded images to disk as a file
  • Has a way to easily access and load the images on disk asynchronously – via a cache key
  • Has a way to figure out whether the image is saved to disk and retrieve the saved image vs downloading it again via the image URL.
  • Has a way to clear the cache
  • You need a way to abstract this logic so it doesn’t clutter the ViewController, etc
  • You still have to make sure that the right image ends up in the right cell

The point is that although asynchronous image downloading is something that we need all the time in iOS development, it is not easy to do. I’ve even tried to write my own code recently, and the images wouldn’t scroll fast. My caching system was not good enough at loading lots of files really fast while managing to download new files. After looking at some of the caching implementation from Kingfisher, I don’t feel as bad. This stuff is tricky if you’re new to it.

So honestly, my suggestion is to leave it to the generous open source contributors and use an image downloading library. Kingfisher is my new favorite. But SDWebImage has been around for a while. And of course then there’s AlamofireImage if you’re already using Alamofire. Oh, and Facebook has a whole website with incredible documentation dedicated to AsyncDisplayKit 😬😬😬. There are other libraries as well that I haven’t mentioned but that should do the job as well.

Take the extra time to focus instead on all the other user-essential features in your app!

Update: @valeriyvan recommends watching this WWDC12 video on pre-rendering.

Also, if you’re still focused on writing this on your own [this blog post](http://sweettutos.com/2015/12/31/swift-how-to-asynchronously-download-and-cache-images-without-relying-on-third-party-libraries/) looks promising…

Enjoy the article? Join over 20,000+ Swift developers and enthusiasts who get my weekly updates.