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!
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 ;)