Blog Archives

A Lesson In Knowing Your Product

Long ago, in my first year at Mindgrub we were contracted to work on a community site that circled around creating a sense of nostalgia.  You could go in and become fans (or something) of things from your 80s childhood.  The site details really aren’t important, and I’m not even sure if the site is even still around anymore.  Regardless, we were working with other far flung contractors to bring this whole nugget together, and it wasn’t happening.  At all.

I remember sitting in weekly conference calls discussing the merit of the PHP site architecture, templating systems, database backends.  Tons of nitty gritty details that really had absolutely nothing to do with creating a community site.  Phrases like “so when when we’re done the templating system will work just like smarty” were uttered often (clarification: not by us, we were only making some javascript widgets).  Usually someone would follow with “then why the fuck aren’t we using smarty?”.   I recall this verbatim.

The situation continued to spiral into more and more delays as we trudged along. There eventually was a call between our CEO and theirs where our CEO asked why they’re so focused on software development when what they were trying to build was a community site, not a software system.  I imagine the silence was deafening.

It was a bad case of “not invented here” syndrome.  Symptoms include burning tons of time and energy on something that quite simply has A) already been done, B) probably better and better tested than you could do it, and C) completely ancillary to your core business.

That conversation came ringing back all to true to me on a recent project.  We were looking to add a rich PDF viewer to an app with paging, zooming, and all the other bells and whistles.  For a few days I looked on the internet, found some sample code, and toyed with some of the Apple examples for displaying PDFs.  I got something that worked, sort of.  One stray rotation of the device could throw the whole thing out of whack.  I was trying to avoid having to pay for a library that does all these.  Then it hit me.  The goal of the app was not to display PDFs, it was merely one facet of it.  I has already been done, better than I could have done it in the time we had to do it.  Displaying PDFs was not the business goal of this application.  I was doing nobody any good by continuing to churn on it.

The lesson here is to know what your product is, whether it belongs to you or you’re ultimately helping someone else create theirs.  It’s always important to recognize that using a well tested pay-for component might just the thing you need to add the value you were looking for and get everyone back to focusing on what’s really important.

Advertisements

Taming NSDate-Utilities

NSDate-Utilities is a part of a great library for working with NSCalendar and NSDate. It provides uber-convenient methods on NSDate for finding out, for example, whether the NSDate receiver falls within the current day. These utilities are fantastic, but unfortunately, they’re also a bit on the slow side.

Why so slow?

Many of the methods rely on getting NSDateComponents from a date via the NSCalendar. Each sends an independent call to [NSCalendar currentCalendar]. Unfortunately, getting the current calendar seems really slow. The latest SalesBag release will feature a very robust set of calendar views to help salespeople schedule their meetings. This means a ton of calculations on NSDate inside tight loops. Using the NSDate-Utilities methods and the time profiler, I found the app spending nearly half a second in [NSCalendar currentCalendar]. This is not good.

Diagnosis

The NSDate-Utilities methods that spend time with NSCalendar all call out to [NSCalendar currentCalendar] independently. For general use, this is probably fine and leaves the app a little leaner on memory. It also (seems to) guarantee that the calendar will always be right if the user changes it mid stream in the app. For Salesbag, this won’t be a problem. We assume that salespeople in the US will be using the gregorian calendar.

Fixing

To speed things up I first created a static NSCalendar variable at the top of the m file that we’ll use in place of grabbing NSCalendar fresh every time.

static NSCalendar *curCalendar = nil;

Then I replaced the #define for current calendar with my static variable

#define CURRENT_CALENDAR curCalendar

Lastly, I need to create the calendar when needed. For this I created a new macro that I placed at the head of any method using the CURRENT_CALENDAR macro:

#define INIT_CURRENT_CALENDAR if (curCalendar == nil) curCalendar = [[NSCalendar currentCalendar] retain];

// later ...
- (BOOL) isSameYearAsDate: (NSDate *) aDate
{
    INIT_CURRENT_CALENDAR
	NSDateComponents *components1 = [CURRENT_CALENDAR components:NSYearCalendarUnit fromDate:self];
	NSDateComponents *components2 = [CURRENT_CALENDAR components:NSYearCalendarUnit fromDate:aDate];
	return ([components1 year] == [components2 year]);
}

Improvement

The time profiler showed the time spent in [NSCalendar currentCalendar] dropped to a measly 35ms. Something I can certainly live with. Of course there’s no such thing as a free lunch and any developer would point out that my static won’t be deallocated until the app terminates. In this case though, the memory trade off was worth it for the speed increase.

10 iOS Libraries + 2

AppDevMag posted a list of 10 libraries to make iOS development easier. We’ve used Three20 and a few of the others here at Mindgrub, and wound up writing our own library similar to ASIHTTPRequest back in the iOS 2 days, though it was built around NSHTTPURLRequest rather than CFNetwork.

Two great libraries they left out however:

  • ShareKit – Post to many social network sites out of the box. This library is light and fast, and easily extendable to add other services.
  • XMLRPC in WordPress for iOS – Writing XML-RPC from scratch is a pain, but this library will get a lot of the boiler plate code out of the way. The app is open source.