{"id":3286,"date":"2012-01-27T18:05:40","date_gmt":"2012-01-27T08:05:40","guid":{"rendered":"https:\/\/therefinedgeek.com.au\/?p=3286"},"modified":"2012-01-27T18:05:40","modified_gmt":"2012-01-27T08:05:40","slug":"ios-sdk-lazy-image-downloading","status":"publish","type":"post","link":"https:\/\/therefinedgeek.com.au\/index.php\/2012\/01\/27\/ios-sdk-lazy-image-downloading\/","title":{"rendered":"iOS SDK: Lazy Image Downloading."},"content":{"rendered":"<p>I&#8217;ve had a couple people ask me for the code behind the image loading that&#8217;s referenced in my <a href=\"https:\/\/therefinedgeek.com.au\/index.php\/2010\/12\/21\/fast-scrolling-uitableview-updates-for-ios-4-2\/\" target=\"_blank\">updates for fast scrolling post<\/a> and I&#8217;m making good on a promise to post the code for everyone else to use. It&#8217;s shown below:<\/p>\n<p>ImageDownloader.h<\/p>\n<pre class=\"brush: objc; title: ; notranslate\" title=\"\">\r\n\/\/\r\n\/\/  ImageDownloader.h\r\n\/\/  Lobaco\r\n\/\/\r\n\/\/  Created by David Klemke on 14\/10\/10.\r\n\/\/  Copyright 2010 __MyCompanyName__. All rights reserved.\r\n\/\/\r\n\r\n#import\r\n@class Post;\r\n\r\n@protocol ImageDownloadDelegate;\r\n\r\n@interface ImageDownloader : NSObject {\r\n\tPost *post;\r\n\tNSIndexPath *indexPathInTableView;\r\n\tid  delegate;\r\n\r\n\tNSMutableData *activeDownload;\r\n\tNSURLConnection *imageConnection;\r\n\tbool downloadPostImage;\r\n}\r\n\r\n@property (nonatomic, retain) Post *post;\r\n@property (nonatomic, retain) NSIndexPath *indexPathInTableView;\r\n@property (nonatomic, assign) id  delegate;\r\n@property bool downloadPostImage;\r\n@property (nonatomic, retain) NSMutableData *activeDownload;\r\n@property (nonatomic, retain) NSURLConnection *imageConnection;\r\n\r\n- (void)startDownload;\r\n- (void)cancelDownload;\r\n\r\n@end\r\n\r\n@protocol ImageDownloadDelegate\r\n\r\n-(void)imageDidLoad: (NSIndexPath *)indexPath;\r\n\r\n@end\r\n\r\n<\/pre>\n<p>ImageDownloader.m<\/p>\n<pre class=\"brush: objc; title: ; notranslate\" title=\"\">\r\n\/\/\r\n\/\/  ImageDownloader.m\r\n\/\/  Lobaco\r\n\/\/\r\n\/\/  Created by David Klemke on 14\/10\/10.\r\n\/\/  Copyright 2010 __MyCompanyName__. All rights reserved.\r\n\/\/\r\n\r\n#import &quot;ImageDownloader.h&quot;\r\n#import &quot;Post.h&quot;\r\n\r\n#define kImageHeight 75\r\n\r\n@implementation ImageDownloader\r\n\r\n@synthesize post;\r\n@synthesize indexPathInTableView;\r\n@synthesize delegate;\r\n@synthesize activeDownload;\r\n@synthesize imageConnection;\r\n@synthesize downloadPostImage;\r\n\r\n#pragma mark\r\n\r\n- (void)dealloc\r\n{\r\n\t&#x5B;post release];\r\n\t&#x5B;indexPathInTableView release];\r\n\t&#x5B;activeDownload release];\r\n\t&#x5B;imageConnection cancel];\r\n\t&#x5B;imageConnection release];\r\n\t&#x5B;super dealloc];\r\n}\r\n\r\n- (void)startDownload\r\n{\r\n\tself.activeDownload = &#x5B;NSMutableData data];\r\n\t\/\/NSLog(@&quot;%@&quot;,&#x5B;post.data objectForKey:@&quot;ProfileImage&quot;]);\r\n\tNSURL *url;\r\n\tif (downloadPostImage)\r\n\t{\r\n\t\turl = &#x5B;&#x5B;NSURL alloc] initWithString:&#x5B;post.data objectForKey:@&quot;PostImage&quot;]];\r\n\t}\r\n\telse\r\n\t{\r\n\t\turl = &#x5B;&#x5B;NSURL alloc] initWithString:&#x5B;post.data objectForKey:@&quot;ProfileImage&quot;]];\r\n\t}\r\n\r\n\tNSURLConnection *connection = &#x5B;&#x5B;NSURLConnection alloc] initWithRequest:&#x5B;NSURLRequest requestWithURL:url] delegate:self];\r\n\tself.imageConnection = connection;\r\n\t&#x5B;url release];\r\n\t&#x5B;connection release];\r\n}\r\n\r\n- (void)cancelDownload\r\n{\r\n\t&#x5B;self.imageConnection cancel];\r\n\tself.imageConnection = nil;\r\n\tself.activeDownload = nil;\r\n}\r\n\r\n#pragma mark -\r\n#pragma mark Download support (NSURLConnectionDelegate)\r\n\r\n- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data\r\n{\r\n    &#x5B;self.activeDownload appendData:data];\r\n}\r\n\r\n- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error\r\n{\r\n    \/\/ Clear the activeDownload property to allow later attempts\r\n    self.activeDownload = nil;\r\n\r\n    \/\/ Release the connection now that it's finished\r\n    self.imageConnection = nil;\r\n}\r\n\r\n- (void)connectionDidFinishLoading:(NSURLConnection *)connection\r\n{\r\n    \/\/ Set Image and clear temporary data\/image\r\n    UIImage *image = &#x5B;&#x5B;UIImage alloc] initWithData:self.activeDownload];\r\n\r\n    if (image.size.width != kImageHeight &amp;&amp; image.size.height != kImageHeight)\r\n    {\r\n        CGSize itemSize = CGSizeMake(kImageHeight, kImageHeight);\r\n        UIGraphicsBeginImageContext(itemSize);\r\n        CGRect imageRect = CGRectMake(0.0, 0.0, itemSize.width, itemSize.height);\r\n        &#x5B;image drawInRect:imageRect];\r\n\t\tif (&#x5B;self downloadPostImage])\r\n\t\t{\r\n\t\t\tself.post.postImage = UIGraphicsGetImageFromCurrentImageContext();\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tself.post.profileImage = UIGraphicsGetImageFromCurrentImageContext();\r\n\t\t}\r\n        UIGraphicsEndImageContext();\r\n    }\r\n    else\r\n    {\r\n\t\tif (&#x5B;self downloadPostImage])\r\n\t\t{\r\n\t\t\tself.post.postImage = image;\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tself.post.profileImage = image;\r\n\t\t}\r\n    }\r\n\r\n    self.activeDownload = nil;\r\n    &#x5B;image release];\r\n\r\n    \/\/ Release the connection now that it's finished\r\n    self.imageConnection = nil;\r\n\r\n    \/\/ call our delegate and tell it that our icon is ready for display\r\n    &#x5B;delegate imageDidLoad:self.indexPathInTableView];\r\n}\r\n\r\n@end\r\n<\/pre>\n<p>There&#8217;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!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve had a couple people ask me for the code behind the image loading that&#8217;s referenced in my updates for fast scrolling post and I&#8217;m&#8230;<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[4],"tags":[3137,3136,1747,1545,2044],"class_list":["post-3286","post","type-post","status-publish","format-standard","hentry","category-tech","tag-fast-scrolling-tableview","tag-image-loading","tag-ios","tag-lazy","tag-objective-c"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/ppBqt-R0","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/therefinedgeek.com.au\/index.php\/wp-json\/wp\/v2\/posts\/3286","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/therefinedgeek.com.au\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/therefinedgeek.com.au\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/therefinedgeek.com.au\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/therefinedgeek.com.au\/index.php\/wp-json\/wp\/v2\/comments?post=3286"}],"version-history":[{"count":0,"href":"https:\/\/therefinedgeek.com.au\/index.php\/wp-json\/wp\/v2\/posts\/3286\/revisions"}],"wp:attachment":[{"href":"https:\/\/therefinedgeek.com.au\/index.php\/wp-json\/wp\/v2\/media?parent=3286"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/therefinedgeek.com.au\/index.php\/wp-json\/wp\/v2\/categories?post=3286"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/therefinedgeek.com.au\/index.php\/wp-json\/wp\/v2\/tags?post=3286"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}