Norbert
Norbert

Reputation: 4291

Download an image from the web and caching it by using Core Data

Imagine you use a web service that delivers images via an API. Every image has an UID and you have a Core Data entity Image with attributes uid (int) and image (transformable).

Now a gallery of your app needs to show many images (the UIDs are known). You don't know which of the images have been downloaded and stored before. How can you lazily download images with core data in the background, so that the view may show an UIActivityIndicator during loading and automatically shows the image as soon as it is stored locally (e.g. by using the NSFetchedResultsControllerDelegate protocol)?

Is it useful to subclass UIImageView for that purpose?

Upvotes: 0

Views: 763

Answers (3)

Zhang
Zhang

Reputation: 11607

If you don't absolutely need Core Data, then may I recommend using MWPhotoBrowser?

https://github.com/mwaterfall/MWPhotoBrowser

It essential generates a gallery view controller for you which you can push onto your navigation controller. The gallery view controller has scrollable images with pinch zoom, pan, everything, even emailing the photo to someone.

It also does the lazy loading of the image with the activity indicator.

Short answer: everything you wanted to do without reinventing the wheel.

Upvotes: 0

runmad
runmad

Reputation: 14886

I wouldn't use Core Data to store images, but I'd store them on disk. I was trying to find in the documentation where Apple themselves warn against storing images larger than 100k or so in Core Data since you'd run into a performance issue.

However, I found this article that talks about Core Data Image Caching that may be of use.

Also, here's another Stack Overflow post with a good answer that tells you when to store images in a database and when to just use references to disk storage.

Upvotes: 1

Rob
Rob

Reputation: 437582

  1. Yes, you can use Core Data for this, but be forewarned that there is a performance hit when you use Core Data to store images. It's negligible if you're dealing with small (e.g. thumbnail) images, but for very large images, the performance hit is observable. For large images, I'd store the images in Documents folder (or, better, a subfolder), and use Core Data to keep track of what images have been downloaded, their filenames, etc. But if the images are smaller, keeping everything right there in Core Data is cleaner.

  2. I probably would not want to use a subclassed UIImageView for this purpose, because you might want to decouple the presentation layer (the image view) from the caching of images. Also, for sophisticated user interfaces, UIImageView objects may be discarded or reused as the user scrolls through a big collection of images, so you might not want a hard link between the UIImageView and your caching logic. Also, depending upon your user interface, sometimes the images can dictate something broader than the UIImageView (e.g., if you're using a tableview, you might want to adjust the cell height based upon the image as it's downloaded). The particulars of the implementation of what the UI might do depend upon where the image is being used (a UITableView, a UIScrollView that is showing a grid of images, etc.).

So, bottom line, for simple user interfaces, perhaps you could subclass a UIImageView but I'd generally advise to have some custom image caching object that does the lazy loading with some delegate protocol to tell the UI when the image load is complete.

Upvotes: 3

Related Questions