I’ve had a couple people ask me for the code behind the image loading that’s referenced in my updates for fast scrolling post and I’m making good on a promise to post the code for everyone else to use. It’s shown below:
ImageDownloader.h
// // ImageDownloader.h // Lobaco // // Created by David Klemke on 14/10/10. // Copyright 2010 __MyCompanyName__. All rights reserved. // #import @class Post; @protocol ImageDownloadDelegate; @interface ImageDownloader : NSObject { Post *post; NSIndexPath *indexPathInTableView; id delegate; NSMutableData *activeDownload; NSURLConnection *imageConnection; bool downloadPostImage; } @property (nonatomic, retain) Post *post; @property (nonatomic, retain) NSIndexPath *indexPathInTableView; @property (nonatomic, assign) id delegate; @property bool downloadPostImage; @property (nonatomic, retain) NSMutableData *activeDownload; @property (nonatomic, retain) NSURLConnection *imageConnection; - (void)startDownload; - (void)cancelDownload; @end @protocol ImageDownloadDelegate -(void)imageDidLoad: (NSIndexPath *)indexPath; @end
ImageDownloader.m
// // ImageDownloader.m // Lobaco // // Created by David Klemke on 14/10/10. // Copyright 2010 __MyCompanyName__. All rights reserved. // #import "ImageDownloader.h" #import "Post.h" #define kImageHeight 75 @implementation ImageDownloader @synthesize post; @synthesize indexPathInTableView; @synthesize delegate; @synthesize activeDownload; @synthesize imageConnection; @synthesize downloadPostImage; #pragma mark - (void)dealloc { [post release]; [indexPathInTableView release]; [activeDownload release]; [imageConnection cancel]; [imageConnection release]; [super dealloc]; } - (void)startDownload { self.activeDownload = [NSMutableData data]; //NSLog(@"%@",[post.data objectForKey:@"ProfileImage"]); NSURL *url; if (downloadPostImage) { url = [[NSURL alloc] initWithString:[post.data objectForKey:@"PostImage"]]; } else { url = [[NSURL alloc] initWithString:[post.data objectForKey:@"ProfileImage"]]; } NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:[NSURLRequest requestWithURL:url] delegate:self]; self.imageConnection = connection; [url release]; [connection release]; } - (void)cancelDownload { [self.imageConnection cancel]; self.imageConnection = nil; self.activeDownload = nil; } #pragma mark - #pragma mark Download support (NSURLConnectionDelegate) - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { [self.activeDownload appendData:data]; } - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { // Clear the activeDownload property to allow later attempts self.activeDownload = nil; // Release the connection now that it's finished self.imageConnection = nil; } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { // Set Image and clear temporary data/image UIImage *image = [[UIImage alloc] initWithData:self.activeDownload]; if (image.size.width != kImageHeight && image.size.height != kImageHeight) { CGSize itemSize = CGSizeMake(kImageHeight, kImageHeight); UIGraphicsBeginImageContext(itemSize); CGRect imageRect = CGRectMake(0.0, 0.0, itemSize.width, itemSize.height); [image drawInRect:imageRect]; if ([self downloadPostImage]) { self.post.postImage = UIGraphicsGetImageFromCurrentImageContext(); } else { self.post.profileImage = UIGraphicsGetImageFromCurrentImageContext(); } UIGraphicsEndImageContext(); } else { if ([self downloadPostImage]) { self.post.postImage = image; } else { self.post.profileImage = image; } } self.activeDownload = nil; [image release]; // Release the connection now that it's finished self.imageConnection = nil; // call our delegate and tell it that our icon is ready for display [delegate imageDidLoad:self.indexPathInTableView]; } @end
There’s definitely room for improvement in there (you can remove some of the application specific logic) but it works well and I never had an issue with it. Let me know if you run into any problems though!
Show Comments