Archive for October, 2009

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;