22 OctAsynchronous UIImage from web

Everybody needed or will need to load images from web. The easiest way to do it is to get NSData from NSURL and create UIImage:

UIImage *myImage = [[UIImage alloc] initWithData:
[NSData dataWithContentsOfURL:[NSURL URLWithString:strImageUrl]]];

But it’d look strange for customers to hover while image loading from server.

Asynchronous loading is a de-facto standard. Let’s make an elegant solution for future need.

Usually we show UIImage with UIImageView on views, so there is a reason to inherit UIImageView. The task is easy: download NSData in background and show it. We need only one public method which actually starts background working:

@interface AsynchronousImageView : UIImageView {
NSURLConnection *connection;    NSMutableData *data;}                           

- (void)loadImageFromURLString:(NSString *)theUrlString;

@end

Asynchronous download from web requires the use of a NSURLRequest and NSURLConnection. Don’t forget about caching and select necessary NSURLRequest’s cachePolicy:

- (void)loadImageFromURLString
 :( NSString *)theUrlString{ [self.image release],
self.image = nil; NSURLRequest *request = [NSURLRequest requestWithURL:
[NSURL URLWithString:theUrlString]
cachePolicy:NSURLRequestReturnCacheDataElseLoad
 timeoutInterval:30.0];                          

 connection = [[NSURLConnection alloc]
 initWithRequest:request delegate:self];}

Then we need to process data receiving:

- (void)connection:(NSURLConnection *)theConnection
 didReceiveData:(NSData *)incrementalData {    if (data == nil)
 data = [[NSMutableData alloc] initWithCapacity:2048];                 

    [data appendData:incrementalData];}

- (void)connectionDidFinishLoading:(NSURLConnection *)theConnection
{    self.image = [UIImage imageWithData:data];
  [data release], data = nil; [connection release],
connection = nil;}

To apply brand new AsynchronousImageView we need just add it

to a UIVIew. Open InterfaceBuilder,

add UIImageView to the view and change its class to AsynchronousImageView:

Now create and connect an IBOutlet with AsynchronousImageView and call loading a test image.

IBOutlet AsynchronousImageView *asynchronousImageView;
[asynchronousImageView
loadImageFromURLString:@"http://www.iphone-codes.com/wp-content/uploads/2008/03
/apple-iphone-sdk-beta-2.jpg"];

If you’ve made all right it’d download and show your image.

Look sample sources or directly git “git clone git://github.com/slatvick/Alterplay-iPhone-dev-tips.git“.

PS.
It’s not depend of where you want to show web image. It can be a Multiline UITableViewCellor UITableView header as I needed in one of my project:

AsynchronousImageView *imageView = [[AsynchronousImageView alloc] init];
 [imageView loadImageFromURLString: @"..." ];
 self.tableView.tableHeaderView = imageView;

  • http://www.blogger.com/profile/09292023538568023514 WASD

    Actually it is not UIImage, it is UIImageView. That's mean that you can't use this code for UITableViewCell image for example.

  • http://www.blogger.com/profile/10136059479406321000 Slava

    WASD, yes there is a better way to do so, but anyway you can download an image and then set to your UIImageView.

  • http://www.blogger.com/profile/09768627127581377494 CNG

    Thank you SO much…your code worked perfectly for my purposes and was very straighforward. Keep up the good work! I'm coming to you from now on for tips :)

  • http://www.blogger.com/profile/10136059479406321000 Slava

    Yes, that is standard old way. I'd recommend to find common solution on GitHub, e.g.

  • http://www.blogger.com/profile/05763882563280551906 Sam

    This post has been removed by a blog administrator.