Speaking on iOS5 tonight at Frederick Web Tech

I’m speaking again tonight at the Frederick Web Tech meetup about some of the “new” features available in iOS5.

You can check out the meetup page here.

There’s also a GitHub and Slideshare link.

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.

Do Just About Anything With Blocks

I love using blocks in objective-C (and C for that matter).  I think they’re the most useful additions to language since . . . well I don’t know.  I allows your code to be more compact and more logically grouped (remember UIView animation delegates? yeesh).  In some cases, even faster by backgrounding certain operations with GCD.   Sadly, blocks have only made it into a small portion on the SDKs and frameworks, most notably collection enumeration and the vastly improved UIView animations.  Fortunately there’s some enterprising individuals and groups who’ve created some very good libraries for extending blocks to other parts of the framework.

BlocksKit

BlocksKit is an open source library that allows you to do just about anything with blocks.  You can easily apply blocks as selectors to UIControls, UIGestureRecognizers, and NSTimers.  There are facilities to apply blocks in different ways to collections, and through the use of dynamic delegates you can use blocks in place of delegates on alerts and action sheets.  As a bonus there’s some handy utilities for dealing with associated objects too.

Block based drawing

I’ve shared this before,but David Hamrick posted a great demo on using blocks to handle drawing on UIViews without the need to subclass.  Find it here.

UIAlertView+Blocks:

If you don’t need everything in BlocksKit, you can check out UIAlertView+Blocks which works very nicely for working with alerts and actions sheets without the need for a delegate at all.

Note: BlocksKit and the above categories don’t play nice together.  You’ll need to pick on or the other to avoid some very odd runtime bugs.

Some block tips of my own:

Static comparators

Apple added block based comparisons for sorting NSArrays.  The block takes 2 objects and returns an NSComparisonResult.  If you find yourself sorting the same thing in multiple places it’s often faster to statically declare your comparator that you can reuse.  Let’s say we have an array of a custom class person, with strings for first and last name:


@interface Person : NSObject
@property (nonatomic, copy) NSString *firstName, *lastName;
@end

Sorting using a block is simple enough, given an array of Person objects:


[people sortUsingComparator:^NSComparisonResult(id p1, id p2) {
if ([[p1 lastName] isEqualToString:[p2 lastName]])
{
return [[p1 firstName] caseInsensitiveCompare:[p2 firstName]];
}
return [[p1 lastName] caseInsensitiveCompare:[p2 lastName]];
}];

If we want to reuse the comparator multiple places, we store it into a static variable:


static NSComparator personCompare = ^NSComparisonResult(id p1, id p2) {
if ([[p1 lastName] isEqualToString:[p2 lastName]])
{
return [[p1 firstName] caseInsensitiveCompare:[p2 firstName]];
}
return [[p1 lastName] caseInsensitiveCompare:[p2 lastName]];
};

// ...

[people sortUsingComparator:personCompare];

You can do the same thing with literally any block you want to reuse, but you don’t get the benefit capturing scoped variables.

Blocks in forms:

It’s common to have forms made of table cells with text fields for entering user data.  Normally to properly apply the captured data you either have to do some creative work with UIView tags or extend the UITableViewDelegate to hand your new cell type.  You can also use blocks to handle the callback by either adding a block variable to a custom table cell.


typedef void(^TextViewEndCallback)(NSString *enteredText);

@interface MultiLineTextFieldCell : UITableViewCell <UITextViewDelegate>
{
UITextView *textView;
SBTextViewEndCallback textViewEndCallback;
}
@property (nonatomic, retain) IBOutlet UITextView *textView;
- (void)setTextViewEndCallback:(TextViewEndCallback)callback;
@end

The above example uses a text view in a table cell.  The table cell should be delegate for the text view.  In the text view delegate method you need only call the block passed into the cell:


- (void)textViewDidEndEditing:(UITextView *)textView_
{
textViewEndCallback(textView.text);
}

This is very easy to use in your cellForRowAtIndexPath method:


__block SomeClass *object = [objects objectAtIndex:indexPath.row];

[cell setTextViewEndCallback:^(NSString *enteredText) {
object.somestring = enteredText;
}];

We used very similar ideas to the above in SalesBag to speed development along.

That’s it!

I enjoy how blocks can speed development along and allows you to write more flexible and sometimes even more reusable code.  Have any cool block tricks?  I’d love to hear them.  Happy Coding!

Printing a C array in the debugger Console

I’m by no means a GDB expert.  I know the basics, but I just learned this gem today.  Say you have a C array with five items created with something like this:


int *array = malloc(5 * sizeof(int));

And you want to print it out in the debugger quickly.  You can’t just print the pointer because GDB doesn’t know to print it as an array, but this will:


p *array@5

Output:


$1 = {0, 0, 0, 0, 0, 1}

To use this the left hand side, before the ‘@’ should be an array, and the right hand side needs to be the length of the array.  Very handy.

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.

2011 in review

This is admittedly pretty cool:

 

The WordPress.com stats helper monkeys prepared a 2011 annual report for this blog.

Here’s an excerpt:

The concert hall at the Sydney Opera House holds 2,700 people. This blog was viewed about 12,000 times in 2011. If it were a concert at Sydney Opera House, it would take about 4 sold-out performances for that many people to see it.

Click here to see the complete report.

2012 – A look back and a look forward

Another day, another dollar.  Another year, another . . . something.

Dunno.  I’ve never had much use for resolutions related to an arbitrary day of the year.  I tend to see goal setting as an ongoing thing and goals as more of a continual series of milestones rather than a single achievable event.  Why new years resolutions anyway?  Why not 6-month resolutions?  Or monthly resolutions?  Monthly resolutions in agile sprints?  Maybe I’m onto something . . .

Most of the stuff I put up here is highly technical in nature.  Tutorials on how to do this or that in iOS or XCode.  I was tempted to go technical on this one too.  A rambling list of technologies I’ve worked with.  Another xxxKit.framework I intend to plod around with.

Boring.  Who cares.

That in itself isn’t really interesting to anyone (not even me really).  So in a different direction I’m taking stock of what I’m good at, what I’m not good at, and what I want to be better at on a very general level.  I think these could apply to anyone working as developer whether working on an indie project (as many people reading iDevBlogADay probably are) or working on client work (as I do).

Things I’m Good At:

Watching the details – It came to me in an epiphany this year.  Strangely.  I am a detail oriented person.  I was never the kid with a clean room.  I never meticulously organized my closet by color.  I never had the border-line OCD, must-organize-everything kind of personality.  I still don’t.  On some level I separate ordinary details from Details That Matter.

At any rate, I have a penchant for the details when it comes to my work.  I like this.  I love this.  I used to be envious of the detail oriented folk.  I’m pleased to count myself among them in some regard.  I think this is necessary for people who work as developers.  Your job is detail oriented.  “The computer will only do exactly what you tell it”, my dad used to say.  To a fault.  I take pride in the craftsmanship of my work.  I always have.  2012 will be no different.

Making a plan – 2012 was one of my first forays in developing a real, honest-to-god software engineering plan.  I thought I’d nailed it.  Turns out I was about 75% of the way there (the gaps really showed up during development).  Regardless the parts that were planned well went off without much of a hitch and came in under-time against the project plan.  This is something I want to expand upon in 2012.  You’d be amazed what you can figure out ahead of time before you write one line of code.  Every 15 minute interval spent mulling over a problem before you start will save probably hours in development when the same problem inevitably comes up.  As mine and Mindgrub’s projects grow ever larger this will become increasingly more important.

Things I Suck At (and want to improve upon):

Automating the mundane – Shame on me as a developer, but there’s a lot of things for which I don’t have automation in place.  Simple stuff.  Dumb stuff.  Stupid stuff I still do manually like pushing a build to test flight or setting up a UITableView.  I think there’s a couple reasons I haven’t delved into this more.

  1. Time is not always on my side, in that the pressure to just get the client work out the door is high to where I don’t think I’ll have time to find/write a script or an automator action or make an XCode template.  Usually by the time I notice that I should have automated it I’m already 75% done with the task.
  2. Fear of the tools – What if automator jacks the upload to testflight?  What if the deployment script fails?  Dumb fear.  Paranoia.  I need to get over this one.
  3. Lack of knowledge – In no way can I count myself as a bash guru.  I couldn’t write a Perl script to save my life.  Granted automator is a huge help here.  In some ways you can put this under “fear of the tools”

Not sure if there’s an easy solution here.  First would be to learn the tools: automator, a little bash.  I think I’ll leave Perl until 2013.  I also have a mind to make a slew of Xcode templates to use with my development team as it always seems there’s a bunch of things we have to add to any UIViewController.  Third for me is to try out tools and scripts that get posted to various places like HackerNews and Twitter, see what other folks are doing and try to adopt them into my and my team’s workflow.

Branch Out – I’ve been working with iOS almost exclusively in 2011.  It’s great and I love it but I’ve been feeling the need to branch out lately.  I believe it’s important especially in the current job market to be versatile as a developer.  Learning new programming languages will make you better at whichever language you use everyday.  Learning new frameworks will make you think differently about the frameworks you already use.  And if you don’t learn anything new, technology will pass you by.  For 2012 I want to get a release of a cocoa app.  While it’s still objective-c, there’s a lot of nuanced differences between the two.  I’ve got a couple of ideas rattling around, just gotta get up and get going on one.

Making every moment count – I feel like I need a little more get up and go in my life.  Not that I’m lazy.  Far from it.  But I want to make more of my free time that I have.  That doesn’t necessarily mean more work or side projects but more about getting the feeling that I’m getting most out of every minute.  This year I want to work on paring down distractions and focus more on important things.

So, maybe this process was a little more cathartic than I thought looking at the tone of the post from the top to the bottom.  At any rate I want to wish those few regular readers and folks from iDevBlogADay a great new year.  Happy Coding!

Finally Own an iPhone

My dirty little secret as a developer is that I’ve been an Android user for the past 2 years.  I finally upgraded this week to an iPhone.  I can’t begin to describe how much better the experience it is!

UIView Subclass for Custom Drawing Using Blocks

UnderTheBridge picked up a post on a clever method for using blocks for drawing.  Especially useful for small views that don’t do anything else other than just custom drawing.

Check out the original post from David Hamrick here.

Multiple Build Targets For Fun and Profit

This month Mindgrub and Wheelhouse Analytics released Salesbag 1.0, a sales presentation tool geared at the financial services industry. The project represents somewhat of departure for Mindgrub as a consultancy. Most previous projects have been a once-and-done kind of project. For Salesbag we’ll be working long-term with Wheelhouse to release frequent updates to the app.

This presented numerous challenges as 1.0 got out the door and we started work on the first set of updates. Aside from our internal testing team, Wheelhouse has a team of their own. They want to be able to show the app store version off while still testing our updated builds to them. To keep the development and live builds totally separate we decided the best course was to create separate target for the dev version that they would use for their testing. To iPad, these would look like entirely different apps, so we’d never run the chance of damaging the live data during testing. In the rest of this post I’ll detail how to create a separate development target for testing purposes some of the added benefits you’ll get out of doing this.

Step 1 – Create a new app id and provisioning profile.

In the provisioning portal, create a new app id and ad hoc provisioning portal. I assume that everyone reading knows how to do this. For Salesbag we created a com.wheelhouse.salesbagDev app id.

Step 2 – Create a duplicate target

Duplicating the target is simple. Simply right click the build target in the project details and select “duplicate”.

Step 3 – Create a duplicate info plist

In order to use the new app id, we’ll need to duplicate and modify the info.plist to include the new app id.

You can also change other build settings like the bundle display name to make your dev version distinguishable from the production app.

Step 4 – Modify the target build settings to include the new plist

The new target must know to use the new the info.plist. Open the build settings for the target, search for info, and change the name of the info.plist.

Step 5 – Create a new scheme to build the new target

The last thing to do is to create a new scheme to build the new target. Under the schemes drop down at the top of the Xcode window and select manage schemes to bring up the scheme manager. You select duplicate from the actions (gear) menu at the bottom of the window.

Once your new scheme is created, click edit to open the new scheme. All you need to do next is replace the old target with your dev target and hit ok (this is in the “build” section).

You should now see the new scheme in the schemes drop down.

BONUS – Setup target specific code

In the dev version of salesbag we added some features for testers to be able to wipe out old data from previous iterations of Salesbag (in our case local eventkit calendars from development on the earlier versions). With your new target you can easily create custom preprocessor directives to dynamically include code in dev versions that you give to your testers.

Step 1 – Create a new preprocessor macro

In the build settings for the dev target search for preprocessor and double click the section called Preprocessor Macros under the target. Add a new parameter in here. We chose “DEV_VERSION=1”.

Step 2 – Use your new macro in code

To include code specifically for your dev version, simply use the macro you created in step 1:

#if DEV_VERSION
NSLog(@"cool testing feature");
#endif

That’s it!

Hopefully the process above will help some other developers in their longer term projects.  Also be sure to drop a comment if you have any feedback.  Happy coding!