Posts Tagged‘objective-c’

iOS SDK: Lazy Image Downloading.

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!

Still In The Grok Stage.

After reaching 1.0 of Lobaco I’ve taken a breather from developing it, mostly so I could catch up on my backlog of games and give my brain a well deserved break from working on that problem space. It’s not that I’m tired of the idea, I still think it has merit, but the last 6 months of little free time on the nights and weekends were starting to catch up with me and a break is always a good way to kick start my motivation. It didn’t take long for numerous new ideas to start popping into my head afterwards and instead of jumping back into Lobaco development I thought I’d cut my teeth on another, simple project that would give me the experience I needed to migrate Lobaco into the cloud.

The weekend before last I started experimenting with ASP.NET MVC, Microsoft’s web framework that based on the model-view-controller pattern that I had become familiar with after deep diving into Objective-C. I could have easily done this project in Silverlight but I thought that I’d have to man up sooner or later and learn a proper web language otherwise I’d be stuck in my desktop developer paradigm for good. The results weren’t spectacular and I could only bring myself to spend about half the time I usually do coding on the new site, but there was progress made there none the less.

Last weekend was more productive with me managing to make the site look something like the vision I had in my head. Satisfied that I could design a decent looking website I decided to start hacking away at the core fundamentals of the application. This is where I rubbed up against the limitations of the framework that I had chosen for this particular project, not knowing that whilst ASP.NET MVC might share most of its name with its ASP.NET cousins it is in fact a world away from it. Sure it’s still extremely capable but it’s nothing like the drag and drop framework that I had been used to with other Microsoft products, leaving me to research pure HTML and Javascript solutions, something which I had avoided like the plague in the past. This meant that progress was pretty slow and the temptation to play Starcraft 2 with a bunch of my good mates was too strong and I left it there for the weekend.

The slow progress really frustrated me. After finally gaining competence with Objective-C I felt like learning yet another new framework would be easy, even if it meant learning another language. Somehow I managed to forget that frustrating first month where progress was almost nil and I convinced myself I wasn’t procrastinating when looking for other solutions to my problems. Eventually I came to the realization that I was still grokking the new framework I had chosen for my application and that I shouldn’t be expecting myself to be blazing trails when I was still establishing my base of fundamental knowledge.

I see lots of people go through the same struggle when trying out new things and can see how easy it is to give up when you’re not making the kinds of progress other people are. Believe me its even worse in the tech/start-up area where every other day I’m reading about someone who hacked together a fully usable service in a weekend whilst I struggle to get my page to look like it wasn’t written in notepad. The realization that you’re still in the grok stage of learning something new I find to be quite a powerful motivator as past experience has shown that it’s only a matter of time and persistence between floundering around and becoming quite capable.

I’m usually the first one to tell people to stick with what they know as re-skilling is extremely expensive time wise (and can be $$$ wise too, Objective-C set me back a few large) but the pay-offs of diversifying you skills can be quite large. Whilst I’ve yet to make any semblance of a dollar from all my adventures in iPhone development I still count it as a valuable experience, if for the mere fact it’s given me a lot of perspective and oodles of delicious blog fodder. Time will tell if this current foray into yet another web framework will be worth my time but I wouldn’t be doing it if I thought there was no chance of it ever paying off.

Lobaco 1.0: iPhone Testers Required!

It’s been a long 7 months since I first laid eyes on Xcode and the iOS SDK all that time ago and I’ve had quite the love/hate relationship with it. There were times when I could spend only a couple hours coding and blast through features barely breaking a sweat, and others when I’d spend multiple torturous hours figuring out why something just wasn’t working the way I thought it should. The last couple months have been quite successful as my code base has grown large enough to cover most of the rudimentary functions I use constantly and my muscle memory with certain functions is approaching a usable level. Last weekend it all came to head after I polished off the last of my TODO list and sank back into my chair.

Then it hit me, this was a feature complete 1.0 release.

Apart from the achievements (which are barely implemented in the web client) you can do everything on the iPhone client that you could do with the full web client. I’ve taken design cues from many iPhone applications that I’ve been using and I feel its quite usable, especially if you’re familiar with the myriad of Twitter clients out there. I’ve been fiddling with it over the past few days and it seems to be stable enough for me to unleash on others to see how it goes and that’s where you, my faithful readers, come into play.

I’m looking for people to beta test this application pending a full release of it to the app store. If you’re interested in testing out the application and have any 3G and up iPhone (2G might work, but it would be dreadfully slow) hit me up on my gmail [email protected] and we’ll take it from there. I haven’t really experimented with Apple’s beta testing yet so the first lot of you are more than likely to be in for a fun ride as I stumble my way through deploying the application to you, but this is all part of the fun of being a very, very early adopter 🙂

Despite all the trials and tribulations that developing this client has brought me the experience is proving to be invaluable as it’s helped me refine the idea down to the core ideal I started with almost 2 years ago: getting people communicating around a location. It’s also been the first new language I’ve learned in almost 5 years and it has reminded me just how much fun it was learning and creating in a completely new environment, so much so that I’m almost completely sold on the idea of recoding the web client in Ruby on Rails. Still that’s all pie in the sky stuff for now as the next big improvement to Lobaco is moving the entire service off my poor VPS and into the wonderful world of the cloud, most likely Windows Azure. I hope you’ll jump on board with me for testing Lobaco and hopefully in the future this will grow into something much more than my pet project.