September, 2009


13
Sep 09

A simple COCOA Asynchronous image loader class to use in your iPhone app.

This isnt a tutorial, this is just some source code that you might find useful. This class will load images in the background so it wont lock your UI up!

Heres the header file :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
@interface GGImageLoader : NSObject {
 
	NSURLConnection * connection;
 
	NSURL * url;
 
	NSMutableData * mutData;
 
	UIImage * image;
 
	id delegate;
 
}
 
@property ( nonatomic, retain ) UIImage * image;
 
- (id)initWithURL:(NSURL *)aURL;
- (void)setDelegate:(id)anObject;
- (void)load;
 
@end
 
@protocol GGImageLoaderProtocol
 
@required
- (void)imageLoader:(GGImageLoader *)loader
	   didLoadImage:(UIImage *)anImage;
 
@optional
- (void)imageLoader:(GGImageLoader *)loader
	didReceiveError:(NSError *)anError;
 
@end

and heres the main file :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#import "GGImageLoader.h"
 
 
@implementation GGImageLoader
 
@synthesize image;
 
- (void)dealloc
{
	[super dealloc];
	[url release];
	[connection release];
	[mutData release];
	[image release];
}
 
- (id)initWithURL:(NSURL *)aURL
{
	url = [aURL retain];
	return self;
}
 
- (void)setDelegate:(id)anObject
{
	delegate = anObject;
}
 
- (void)load
{
	// SHOW NETWORK INDICATOR
 
	[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
 
	// SET UP THE REQUEST
 
	NSURLRequest * request = [[[NSURLRequest alloc] initWithURL:url] autorelease];
 
	// SET UP THE CONNECTION
 
	connection = [[NSURLConnection alloc] initWithRequest:request
												 delegate:self];
 
	// NEW MUT DATA
 
	mutData = [[NSMutableData new] retain];
 
}
 
- (void)connection:(NSURLConnection *)connection
  didFailWithError:(NSError *)error
{
	if( [delegate respondsToSelector:@selector(imageLoader:didReceieveError:)] )
	{
		[delegate imageLoader:self
			  didReceiveError:error];
	}
}
 
- (void)connection:(NSURLConnection *)connection
	didReceiveData:(NSData *)data
{
 
	// APPEND THE DATA
 
	[mutData appendData:data];
}
 
- (void)connectionDidFinishLoading:(NSURLConnection *)aConnection
{
 
	// ONCE LOADED HIDE NETWORK INDICATOR
 
	[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
 
	// RELEASE THE CONNECTION
 
	[connection release];
 
	// CREATE NEW UIIMAGE FROM THE DATA
 
	image = [[[UIImage alloc] initWithData:mutData] retain];
 
	if( [delegate respondsToSelector:@selector(imageLoader:didLoadImage:)] )
	{
		[delegate imageLoader:self
				 didLoadImage:image];
	}
 
}
 
@end

Its pretty self explanatory, meerly do the following to get it to work..

1
2
3
GGImageLoader * imageLoader = [[[GGImageLoader alloc] initWithURL:[NSURL URLWithString:@"myimageurlhere"]] retain];
[imageLoader setDelegate:self];
[imageLoader load];

The class also has delegate methods and a protocol to follow, so we know when the image has loaded, you can use the GGImageLoaderProtocol in your header file if you like.

1
2
3
4
5
6
7
8
9
- (void)imageLoader:(GGImageLoader *)imageLoader didReceieveError:(NSError *)anError
{
}
 
- (void)imageLoader:(GGImageLoader *)imageLoader didLoadImage:(UIImage *)anImage
{
	// BE SURE TO RELEASE THE IMAGE LOADER
	[imageLoader release];
}

and thats about it, hope its helps some people out!

If ive made a mistake anywhere in this please say, it was a rush post!