|
Recently I was working on an iPhone App that was struggling with a really slow UITableView. The reason it was slow, was because it was loading remote images for every UITableViewCell on each load. The best approach would be to load the image once, cache it, and show the cached file if it exists.
Over my years of doing iOS development I have a pretty decent collection of utilities and classes to do many common tasks. Loading remote images in a UITableViewCell is one of them. I put a demo project up on GitHub. You can download it at: https://github.com/natelyman/NLCachedImageTableViewCell
I'll do a brief walk through if you want to learn what I'm doing here...
NLCachedImageTableViewCell.h:
In the header file I define a couple properties that the caller will use in this UITableViewCell. The first is an NSString called imageUrlString, which the caller will pass in to load the remote image. The second is a UIImage called placeholderImage. The placeholder image is an optional image that the UITableView will display while the remote images are loading. This is pretty important if the images are large. If they're thumbnails it is less important.
NLCachedImageTableViewCell.m:
The setImageUrlString: method is where all the magic happens. The first step is to create a unique filename. I use SHA1 to generate the filename because I want to avoid collisions. I have used this class in some very large apps that do extensive image caching, so collisions can happen if you go with a simple naming pattern. We store the file in the Applications' Documents directory. You could store it in the Temporary or Cache directory, but iOS 5 is a lot more pro-active about clearing these. If you are loading in data that changes often, say a stream from Twitter, I'd recommend using the Cache directory. If you need the cached images to stick around for longer than a day or two, leave it in the Documents directory.
Next we see if the file exists, if it does we simply load the stored file and set the UIImageView's UIImage property and we're good to go. If the file doesn't exist we need to load it. To do this we use Grand Central Dispatch to asynchronously load the images. There are other ways to do this, but in the UITableView use case, I have found Grand Central Dispatch to be the most performant. I make the network call to load the image, save the image to the file system using the filename we came up with earlier. I then pass the UIImage into the cell's UIImageView.
As a bonus, if you checkout the demo project, I used Twitter as a data source using iOS 5's new Twitter framework. I then load the profile images using the above Table View Cells.
|