Updated version here : http://www.geekygoodness.com/2011/06/17/uiimage-from-url-simplified/
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 :
@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 :
#import "GGImageLoader.h" @implementation GGImageLoader @synthesize image; - (void)dealloc { [url release]; [connection release]; [mutData release]; [image release]; [super dealloc]; } - (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 alloc] init] 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..
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.
- (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!
GJaldN I want to say – thank you for this!
Thanks for the post. I am just starting out and was wondering if you could show me how to do a form post?
I am trying to create a batch poster in cocoa. I will need to feed in an encoded cookie string and POST it to the server every 500 milliseconds.
Any thoughts?
Also, how does this work:
- (void)connection:(NSURLConnection *)connection
didReceiveData:(NSData *)data
{
I am coming from an AS background, what is this technique called?
Thanks!
Ill do a future post on posting to servers, whenever I get time.
An NSURLConnection has delegate methods ( methods that are called when events happen, just like AS3′s EventDispatcher ), basically the NSURLConnection will stream the required NSURL contents via NSData through that function. Because they are received in parts we have to construct the overall data object, so as you can see, I have set up a NSMutableData object which im appending the NSData that is received. Its pretty simple.
Also im a AS3 developer ;), its a bit like the ProgressEvent in AS3, apart from instead of a percent and bytes loaded / bytes total, it also gives you the data it recieves =].
Hope that helps.
Thanks for the fast reply. Just ordered some cocoa books. I think I need to run through the basics first.
Peace
Hi, thank you for this – I had been looking for how do do that. I am still learning memory management, read a few books, etc… but I guess most examples I have seen were simple. If you are looking for an idea for your next log, explaining the retain and release in GGImageLoader would be great. Thank you.
Hello yves,
Its really simple, basically, think of it like this : anything you allocate will be automatically released, so [[UIView alloc] init]; will be picked up my the run loops etc and released accordingly. When you stick retain on it, it puts the retain count up by one, starts with 0, then you +1 to it, so now when the auto release pools run, it will ignore your object and wont get released. Likewise, if you run release on it, it will get rid of it from memory. If you dont retain objects when you need to, then problems occur when your trying to call the object, but it has already been released from memory, thus causing epic fail.
If that helps what so ever…and remember to follow @caffeinatedapp for my latest news on my app ;)
mutData = [[NSMutableData new] retain];
VERY BAD! -new already does a retain, so you are double-retaining
Your right, I modified it ;)
Hi,
I tried to load the images into a uitableview, everything works fine, but no pictures appear on the tableview.
can somebody help me what im doing wrong?
NSString *linkche = [[stories objectAtIndex:storyIndex] objectForKey:@”nr”];
GGImageLoader * imageLoader = [[[GGImageLoader alloc] initWithURL:[NSURL URLWithString:[[NSString alloc] initWithFormat:@”theDomain%@.jpg”, linkche]]] retain];
[imageLoader setDelegate:self];
[imageLoader load];
cell.imageView.image = imageLoader.image;
Does anybody know what i am doing wrong?!?
Thank you in advance for your help!!!!
your setting cell.imageView.image to imageLoader.image; when you have not waited for the image to load. This is async, meaning you have to wait for the callback to be able to grab the image. =]