Monday, September 24, 2012

Unnecessary Code Indentation


Unnecessary Code Indentation

If you know me or read my blog or follow me on twitter, you'll know that I have ... particularities. I like things a certain way and, while I don't believe in forcing my way of doing things onto others, when I do things, I do them conscientiously. Since first year when a sage upper year student showed me how to avoid unnecessary indentation in my code, it's something I've tried to do. I won't correct existing code since it doesn't improve performance, but I structure my code to avoid superfluous tabstops. Following Apple's example, we write a custom initializer of an Objective-C object like the following:
- (id)init {
  self = [super init];
  if (self) {
    creationDate = [[NSDate alloc] init];
  }
  return self;
}
You'll notice that the if statement is only checking that self is non-nil. Why not do the following?
- (id)init {
  self = [super init];
  if (!self) return nil;
  creationDate = [[NSDate alloc] init];
  return self;
}
If we're nil, let's bail early so we don't accidentally add code after our if block that could operate on a nil self.
Better yet:
- (id)init {
  if (!(self = [super init])) return nil;
  creationDate = [[NSDate alloc] init];
  return self;
}
Brackets are around the assignment to avoid a compiler warning on Xcode 4's LLVM compiler; GCC doesn't complain.
Again, this is a particularity of mine and I don't care enough to change existing code, but I care enough to blog about it. Does anyone have any thoughts on this method of writing initializers or indenting in general?

Projections on NSArray using valueForKey:


Projections on NSArray using valueForKey:

A coworker of mine recently told me about how valueForKey: works on an NSArray instance. It will enumerate the contents of the array and invoke valueForKey: on each element, returning an autoreleased array instance of the response of the elements. Formally, valueForKey: on an NSArray is a projection of your data to specific values. This is the same as a Select() on a .Net collections object. The following code:
NSArray *array = [[NSArray alloc] initWithObjects:
  [NSDictionary dictionaryWithObjectsAndKeys:
    @"First Object", kNameKey, 
    [NSNumber numberWithInt:0], kNumberKey, 
    nil],
  [NSDictionary dictionaryWithObjectsAndKeys:
    @"Second Object", kNameKey, 
    [NSNumber numberWithInt:1], kNumberKey, 
    nil],
  [NSDictionary dictionaryWithObjectsAndKeys:
    @"Third Object", kNameKey, 
    [NSNumber numberWithInt:2], kNumberKey, 
    nil],
  nil];

NSArray *selectedArray = [array valueForKey:kNameKey];
for (id obj in selectedArray)
    NSLog(@"%@", obj);
Produces the expected output: First Object Second Object Third Object
This is pretty cool! We used it for retrieve JSON parsed to an array of dictionaries used for contents of a UIPickerView. Each element had a user-displayed value and an internal value. This saved us from having to write a method to convert from the user-visible to the corresponding internal value.
This got me thinking what other things the Objective-C collections API would let you do to avoid writing unnecessary code; I don't have time to summarize my results now, but take a look at the Collections Operators. How many for loops could those save in your code?

The Future of Android/iOS Doesn't Matter. The Present Does.


The Future of Android/iOS Doesn't Matter. The Present Does.

I met an Android fan over the weekend - nice guy with a math degree. We got along fine :) I brought up the topic of Android vs. iOS and we had a good talk. Two of his main points were the following:
  • Apple, one company, does not have the manpower or budget to innovate as fast as a group of large companies, like Samsung, as well as a group of eager open source developers.
  • Given the above, he predicted very soon Android is going to outpace iOS in terms of an innovative consumer experience. He compared the current smartphone market to the consumer computer market of the mid-to-late-nineties, a market Apple almost lost entirely.
Let's deal with the first point. I don't think that anyone could call Apple non-innovative. The company has introduced so many new markets - not just products, but markets - over the last decade that we can discount the claim that they can't innovate. They currently worth more than the Great Wall of China, but we know that money can't buy innovation and we've all seen how large, innovate companies can fall into a slouch. So maybe Apple will fall behind in the race to innovate against Android makers. Let's consider the second point.
Even if a single developer, or company, or even Google has some sort of revolutionary idea and actually develops, the code has to be merged into the mainline trunk, tested, sent out to hardware manufacturers who will diddle with it, then sent to carriers who infamously diddle with the handset software, adding their own apps to the consumer's detriment. Any innovation in the Android space is likely to be squashed under the weight of its own size and segmentation. Apple can innovate more easily because it can keep secrets and it can direct their vision more, well, directly.
The future of the smartphone industry doesn't matter because the handsets available today determine consumer purchases.
Android has come a long way. The very best, very latest Android phones offer a hardware experience that is comparable to that of a current generation iPhone. To me, Android handset's software still lacks polish and the kind of high-quality user experience that I've come to expect from using my iPhone 4. My contract with Telus runs out in 20 months, so Android has that long to catch up.
Impress me.

Beta Testing


Beta Testing

I'm working at 500px as my first real, big project out of University. I've been given a lot of responsibility for making this app a success, which is one of the reasons I'm finding this such a rewarding workplace. One of things I've been responsible for is managing beta testers and beta feedback. Thank god for TestFlight
What I've really noticed is a change in how I look at beta testing. I used to think of it as a way for me to be a lazy developer (work smart, no hard, after all) and offload a lot of testing to someone else. Now I see beta testing as a multifaceted tool capable of accomplishing all kinds of awesome things.
Beta testing engages your audience. I've never had an audience before, but having people who genuinelywant to use the software I'm writing is an amazing feeling and effective motivation. I'm a better developer for a pre-production product because I have more people I don't want to let down. In Paul Graham terms, I'm exposing my position to the forces of competitive pressure and I love it.
It's also making me a more mindful developer. I'm keenly aware of user expectations because I've been in email contact with them already. When I make a decision or add a new feature, I'm asking myself "what are the beta testers going to say about this?"
Lastly, it's really humanized users for me. It's hard to empathize with users when they're separated by an App Store review. Speaking of reviews, beta testing is a way better mechanism for getting feedback because now the developers are humanized, too. Users aren't writing all caps, 1-star, negative reviews; they're sending an email to me directly with helpful suggestions and contructive feedback.
Maybe I just have awesome beta testers. At any rate, I've never been more fulfilled with my work; the interactions I have with users on a daily basis are a huge part of that.

Objective-C Memory Deallocation Advice


Objective-C Memory Deallocation Advice

Hey iOS nerd friends, I need your help. I fetched, store, and display models to the use in batches of twelve. A batch is represented by an NSArray instance and is stored in a cache which responds to low memory warnings by clearing out the batches no currently in use. The models themselves form a doubly-linked list (ie: each one has an __unsafe_unretained property to each previous and next). I navigate through the models this way sometimes, and through the "batches" way others.
My problem is memory management. If I were building for iOS 5, I could use the zeroing-weak reference properties in the model class and not worry about it. But I'm not, so I have to. The two options I've thought of are:
  • When releasing a batch from the cache, remove the references into and out of it.
Something like:
NSArray *keys = [sharedCache allKeys]; for (NSString *key in keys) { [[[[sharedCache objectForKey:key] objectAtIndex:0] previousModel] setNextModel:nil]; [[[[sharedCache objectAtIndex:key] objectAtIndex:11] nextModel] setPreviousModel:nil]; [sharedCache removeObjectForKey:key]; }
And then not worry about zero-ing out the next/previous references individually within the batch.
  • When dealloc'ing a model instance, use a static NSLock to remove the references to each model.
Something like:
static NSLock *deallocLock = nil; if (!deallocLock) deallocLock = [[NSLock alloc] init]; [deallocLock lock]; self.nextPhotoModel.previousPhotoModel = nil; self.previousPhotoModel.nextPhotoModel = nil; [deallocLock unlock];
Which guarantees two neighbouring models in the list don't accidentally try to dereference one another while dealloc'ing.
I don't like the first option because it leaves the possibility that two models within the batch will do something funky. I don't like the second option because locking in the dealloc method scares the shit out of me.
I haven't implemented either of these solutions, yet. I'm currently getting infrequent crashes from my beta testers in the dealloc method of my model (trying to dereference a dangling pointer to previous/next).
Any suggestions?

Thoughts on Test-Driven Development


Thoughts on Test-Driven Development

I read an article this morning on Test-Driven Development, or TDD. TDD is the software development paradigm that dictates that you don't write any code without first writing tests for that code; that way, you'll know when you're done (all the tests pass). Without getting into the pros or cons of TDD, my main problem with this article is the holier-than-thou attitude its authors take. This is all to common in discussions regarding TDD: "if you're finding it hard to follow TDD, it's because you're not a capable enough programmer." Or, "if you're finding writing tests is taking too long compared to simply debugging problems, then you're doing it wrong."
Both of these statements may be true, but certainly aren't always. There are legitimate criticisms to TDD. I won't list them because I don't want Hacker News commenters to start nitpicking. I hate nitpicking. The problem is really that whenever someone brings up a problem with TDD, they're shot down with religious vigour and told the problem isn't TDD, the problem is them.
Well, fuck that.
Maybe TDD doesn't work for every developer on every project written with every language using everyframework.
The fact that I can only say this is maybe true without invoking the wrath of TDD Believers is a testament to how unthinkingly some developers push TDD.
To me, the main benefit to TDD was never actually the tests - the tests are meaningless! The main point to TDD is stopping. Thinking. Planning.
Before coding.
TDD may work well for you and your team on your project. It may, however, not. And there's nothing wrong with that.

When Should I Transition to Core Data?


When Should I Transition to Core Data?

Let's take it as read that if you're a seasoned Cocoa Developer and you're considering using Core Data in your project, you probably should be using Core Data. Why wouldn't you already be using Core Data? I think there are two common reasons:
  1. You're new at it and Core Data is hard.
    It is! Learning Core Data is like taking everything you know about database design and use, throwing away a very specific chunk of it, and then replacing it with unfamiliar-sounding words with not-immediately-apparent meanings like NSManagedObjectContext. It's a hard framework to learn and your first attempt at using it is almost certainly going to suck.
  2. You've been writing your project with a rapid application development approach.
    Your project started simple, with simple data models. As the project grew, so did the models, and maybe you weren't so strict with the MVC. So what? Rules were made to be broken, amirite? But now you're spending a lot of time maintaining that logic in models. Getters and setters have side-effects, you need to be careful about what order you access properties in, etc.
Whatever your reasons for not already using Core Data (maybe you're data model is really simple - take a look here), using Core Data might make things a lot easier for you when writing or maintaining your app. But when do you know to switch?
I'm just finishing up a refactoring job that's taken 3 days; in the process of transition to using Core Data, I've noticed a lot of code getting deleted, indicating that it was definitely time to make the switch. This is code that shouldn't have been written in the first place, but I wasn't using Core Data. I'd like to enumerate some indicators that you should already be using Core Data.
(Naturally, I would never admit to ever having any of these in my code.)
  1. Model objects are observers of UIApplicationDidReceiveMemoryWarningNotification.
  2. NSMutableSet or NSMutableDictionary instances behaving as caches.
  3. For that matter, any nontrivial amount of application logic in your models.
  4. Getters and setters in models having side-effects.
  5. Contrived application logic between your view controllers and your models. You're VC's shouldn't be importing the data to populate your models, you should have a tailor-made class for that.
  6. Models that conform to NSCoding (I'm looking at you two, NSKeyArchiver/NSUserDefaults). If you're saving model data to disk or NSUserDefaults, you're probably already going to larger pains than a Core Data transition would be.
  7. Saving NSData blobs to disk.
The transition is also a fantastic opportunity to do things in your code that you probably already should have been doing, like the following.
  1. Centralize access to external data sources, such as a web API.
  2. More clearly define the divisions between models and view controllers.
  3. Separate transient-ish properties of the view controllers from the models. Maybe your model remembers what cell index it corresponds to when that information belongs in a view controller.
When you're done your transition, you'll look back at how you were doing things before and wonder why you waited so long. I know I did.

Optimizing Core Data Saves


Optimizing Core Data Saves

I recently transitioned from keeping data models in memory to persisting them to disc using Core Data.There are a lot of good reasons to do this. This article discusses the finer points of optimizing an application for important data from an external API, storing it in Core Data, and displaying it to the user without adversely affecting performance of the app.
The existing set was fairly elegant; synchronous API fetches were performed in a background thread and invoked using another layer whose responsibility it was to make these calls asynchronous. View controllers accessed this middle layer and provided GCD blocks as callbacks to be executed when the API fetches were complete. The view controllers didn't touch any GCD code and the callbacks were all performed on the main queue.
One of the biggest challenges to getting started with Core Data is trying to do everything perfectly at first. This is kind of, you know, impossible. So I threw out early optimization and went with the naive approach of replacing my data model instances with NSManagedObject subclasses.
Simple, Naïve Core Data Implementation
Simple, Naïve Core Data Implementation
Since NSManagedObject contexts are not thread safe, this was not acceptable. An easy to implement solution was to isolate the parsing of the returned JSON to the middle layer; that way, the API access layer can be called from any thread.
Removing access to the NSManagedObject instances from the API layer
Removing access to the NSManagedObject instances from the API layer
This is a good first step, since with a small amount of effort, we've simplified the problem of safely accessing these object instances. Standard practice when using Core Data is to have one Managed Object Context, or MOC, for each thread. When you save one MOC, the modified attributes of the data models are propagated to the other MOCs. So that's what I did next.
Parsing JSON into the background MOC
Parsing JSON into the background MOC
Whenever the background MOC is saved, the Persistent Store Coordinator, or PSC, propagates the changes to the remaining MOCs. This is kind of a simplification and definitely not a automatic process; it involves some manual lifting on the programmer's part.
As it stood, the application was fine. It obeyed the conventions for good iOS apps, like MVC and not using view controllers to fetch from APIs, and followed the rules of Core Data with regards to memory management and concurrency.
However, it still wasn't a good app. As you can see in the above diagram, once we were finished loading data from the API and parsing into the background MOC, it needs to be persisted to the PSC and those changes propagated through to the main MOC. A chunk of this has to happen on the main queue, since that's where the main MOC lives. In my case, this adds quite a bit of disc access on the main thread (potentially megabytes of data). When an object has been updated from the background thread, it faults and is updated on the main thread, so changing any attribute or relationship of an object would cause the entire model to be re-fetched.. This lead to a lot of jerkiness in the UI, even a lack of perceived responsiveness. There had to be a better solution.
Fetching in the background, but parsing in the main queue to the main MOC
Fetching in the background, but parsing in the main queue to the main MOC
This is what I came up with. Since propagating the changes was now done in the background thread, it alleviated a lot of the work from the main thread and helped. But the interface was still lagging. I loaded my app in Instruments, and I was saving to Core Data in the main queue a lot. No seriously, like, a lot! I took a look at how the parsing was architected (easy, since it was all contained in one class). I was saving practically every time data was mutated. Since the background queue was only being used to fetch, never mutate, saving often was unnecessary (this is true in my case - your app may be different). So I did the clever thing and only saved every so often.
But how often?
If you try and do something like save every random interval, you're almost literally asking for trouble. You'll probably end up introducing intermittent and hard-to-detect bugs. I tried saving one tenth as often, which fixed the lagging. The only problem was, when it lagged one tenth as often, it lagged ten times as bad. So what to do?
The interface appears to be lagging only because the animation is jerky and the controls are unresponsive. The solution I came up with is to use UIScrollViewDelegate's method that corresponds to the end of a scrolling animation. At this point, the main context saves.
The milliseconds-long save isn't noticeable when the interface isn't animating
The milliseconds-long save isn't noticeable when the interface isn't animating
This lets us delay saves until they won't be noticed by the user. While it breaks my architecture of MVC and strictly separating view controllers from data fetches, it makes the best user experience.
The background MOC is now almost strictly used for accessing background instances of the data models. In fact, no parsing or mutating of data takes place in the background queue at all. I could get rid of it altogether, but I'm going to keep the background MOC around since it might come in handy to perform long-running fetches or importing lots of data.

Learn How to Write iOS Apps


Learn How to Write iOS Apps

My friend contacted me on twitter and asked for advice on different sources on how to learn iOS apps. Since this paragraph will already exceed 140 characters, I'm posting here, instead. (Obviously, reading this blog regularly is a great way to pick up some iOS development tricks)
To get started, some people buy a book or find some good online tutorials. I tried both approaches, and the online tutorials were definitely better. I found Stanford's class on iPhone Development, available for free on iTunesU, to be a great place to start. However, watching lectures is time-consuming and, frankly, boring. If I was going to learn now, here is the approach I'd take.
I'd use a top-down/bottom-up strategy to learn both the implementation details of writing Objective-C/CocoaTouch while also getting a handle on the high-level aspects of the platform. Learning them both would make it more obvious how they fit together.
You need to know some high-level stuff, particularly application lifecycle. Apple's documentation, listed below, is a good place to start. If you want to write iOS apps, you're probably already an iOS user, so you're familiar with user conventions. Reading the HIG is still a good idea. It's not long - 90 pages with lots of pictures.
Resources for getting started:
Apple's iOS Starting Point 
A great list of other Apple resources that step you through what tools you need, building your first "Hello World" app, and a primer in Objective-C. 
Apple's iOS App Programming Guide
Very detailed list of high-level concepts in iOS. This is a good resources for finding out the capabilities and limitations of the platform; check this for how to use push notifications, for example.
Programming iOS 4 by Matt Neuburg
This book is recommended by just about everyone that recommends books on iOS apps, but I admittedly haven't read it. It's apparently amazing and a great book to buy if reading books is how you learn things.
iOS Recipes
Once you get a handle on the basics, you'll want to make our apps look unique. This Pragmatic Bookshelf book offers discussions on how to do things like stylizing splash screen transitions, animating views for better user experience, creating custom alert/notification views, and more.
Mike Rundel's "Building iOS Apps from Scratch"
Mike Rundel linked to this in the comments on Hackers News. It's a fantastic, single-document guide that covers basic Objective-C, CocoaTouch, and app architecture. I wish I had read this when I was starting.
I find that following certain blogs or just looking through archives to be really helpful. Objective-C isn't just another language; it has a set of conventions that work very different than standard C, Java, or .Net code. Immersing yourself in these blogs is a great way to become familiar with the language and the runtime.
NSBlog by Mike Ash
This is an Intense (capital 'I') look at the Objective-C language and accompanying runtime. It plays with a lot of fire that you probably want to avoid in production code, but it also has some insightful, low-level reviews of concepts like Automatic Reference Counting and Grand Central Dispatch. He even looks at how you might implement some of these language/runtime features yourself (though you shouldn't).
Cocoa is My Girlfriend
This is like a "how to do things" look at iOS development. Apple's official documentation is sometimes opaque and hard to understand; CIMGF takes that documentation, explains the reasoning behind it, and does a good job of showing you how to use that knowledge in practice. 
Cocoa with Love
This is a kind of "best practices" website that takes a topic, say Core Data, and looks at how to develop consistent, efficient code to work with persistent stores. It goes beyond "following the rules" to show you great conventions you should be adhering to in your own code. It's a great resources and, whenever I'm googling for something, finding a Cocoa with Love article is usually the end of my search.
That's about all I can say - I learn best by trying, identifying a problem or shortcoming in my understanding, and then fixing it. Hopefully you'll be on your way in no time. If anyone ever has a question or comment, please feel free to contact me via twitter.

Software Developer Hiring Techniques


Software Developer Hiring Techniques

This week, an article by 37signals made its way around the Hacker Newswire that explained why they don't hire programmers based on riddles, puzzles, or other "parlor [sic] tricks" (sic because parlour has a 'u' in it - the Queen says so). It's worth a read and, as someone who went through the job hunting experience last year (twice), it's quite enjoyable. Each company I interviewed with eventually offered me a job (who can blame them?) and they each had their own unique way of determining my skill as a programmer. I'm going to classify some of the employers I interviewed with into one of the following.
The Riddler
The Riddler is a programmer who, now that they're in charge of a company, feels the need test programmers with riddles they find interesting. It's almost like a payback from when they were being interviewed for jobs and were passed over for other candidates who excelled not a riddles, but unimportant things like people skills.I was asked by a Riddler a series of programming questions. Some of these questions were practical in the context of the job and, to the Riddler's credit, they offered a poke in the right direction if I ever needed it. However, they also asked me to write FizzBuzz (and didn't particularly appreciate it when I laughed at them).
The best way to deal with the Riddler is to play their game until the interview is over. When they ask you if you have any questions, ask them if you'd be directly reporting to them in the organization. Reflect on their answer and decide if you want to spend your days tackling brain-teasers or actually getting things done.
The Academic
The Academic is typically a former programmer who is now in a hiring position and legitimately means well. They ask questions that any first-year university student should know the answer to. Unfortunately, university students typically forget these answers after first year because its trivial knowledge - a matter of definitions.You might be asked for the dictionary definition of Polymorphism when a description of how to use polymorphism be a better indicator of an understanding of the concept. I use polymorphism all the time but during the interview, I honestly couldn't answer the question (except for the words "'many forms' in Greek").
The Quizzer
My interview with the Quizzer was an enjoyable experience. I had a 15 minute phone interview before being invited for a two-part in-person interview at their office. I was told I would have to complete a one-hour quiz before taking part in a one-hour, in-person interview with lead members of the development team. No problem.The Quizzer told me that I had an hour to complete the quiz, but that candidates rarely finished on time, so don't worry and just answer the questions which I'm most familiar with to the best of my ability. Maybe it's because I just came out of University, or maybe I'm just that amazing, but I answered the entire quiz in 45 minutes.
The quiz was, in fact, a good indicator of my experience and expertise in Objective-C and CocoaTouch. It had different types of questions (including long-answer) that not only tested my trivial knowledge, but also tested my familiarity with more subjective topics like code architecture.
The Online Quizer
All of the interviewers I've listed so far have one thing in common: their techniques are motivated by a sincere desire to do what's best for the company, to determine if the interviewee is a good fit. The Online Quizzer's motivation was laziness.The Online Quizzer is like the Quizzer insofar as they want to test my understanding of programming. Unlike the Quizzer, however, they're only interested in classifying me to make a decision about my salary. They needed a bubble to fill in on their little interview sheet, Beginner, Intermediate, or Expert, and the best way they knew how to get that information was an online quiz.
The quiz itself, provided by an online third party, was incredibly stupid. The questions ranged from inconsequential ("What happens if you delete a file in Finder but don't update the Xcode project file? a) the filename in the project browser appears red b) the filename in the project browser appears red and its icon is faded c) etc…") to arcane ("What is the return value ofArcaneCryptoCFunction on success? a) 1 b) 0 c) true d) void "). My answers were ranked and normalized according to the answers of all the other Objective-C developers around the world who took the quiz. I got "Expert", but admittedly I looked at some header files while completing the quiz. You know, like a real programmer might.
I do not beleve that an online, multiple choice quiz with outdated and arcane questions can ever be a capable tool in determining a potential employee's value to a company or their proficiency in their trade. Any hiring manager who thinks otherwise is a fool.

How to Design iOS Apps


How to Design iOS Apps

When designing iOS applications, there are two routes you can take: you can either strictly adhere to Apple's look-and-feel, or go out and do your own thing. In this post, I'm going to discuss each option, their pros and cons, and why you should adhere to either one or the other. App developers, I feel, tend to one of two extremes: a cookie-cutter Apple-y app or a Frankenstein mess of disjoint ideas shoved together (just because you can doesn't mean you should). Let's look at the first option and see how you can create a great app using all the built-in goodness of UIKit but diverge to make some unique interfaces.

Adhere to Apple's Look-and-Feel

This option is the best option for most people. Apple provides amazing libraries of user interface elements that can be combined to make great apps. This doesn't mean that you can't be innovative and are forced to make cookie-cutter apps; only that you should focus on what the user is familiar with and expects.
This option has many, many advantages. The user will feel  at home and know instantly how to use your app. If you're a developer, you're probably bad at understanding the user's expectations, so using UIKit for everything means Apple has done all the user interface design for you (hooray!). Using UIKit is always way easier, so you can spend you're time doing things that make your app functional and unique, like figuring out Facebook's API.
However, developers often feel like using all the pre-made stuff is boring. Tough cookies. You know what? Programming isn't always exciting, and if you're interested in making a great iOS app, then you have to be aware of the user's expectations. Otherwise, you're a loose canon and should probably just go write Android apps until you finish puberty.
Let's take a look at one beloved example: Tweetie.
Tweetie 2.0 for iPhone, before Twitter took a shit on it
Tweetie 2.0 for iPhone, before Twitter took a shit on it
What I admired about Tweetie was the way it combined the existing system interfaces and made a functional app that always behaved as I expected while also not looking like a cookie-cutter apps. They used all your standard view transition conventions - navigation stacks, tab bars, and modal views, and all appropriately.
Yes, they customized the tab bar a bit, but it behaves the exact same. Yes, the tableview cells had custom actions for a swipe gesture, but the underlying controls look suspiciously like a UIToolbar instance. Yes, they were the first to implement pull-to-refresh, but it only takes about a half hour to make pull-to-refresh using nothing but built-in UIKit elements.
Tweetie would make any user familiar with their iPhone feel completely at home and in control of the interface, but they still made some really innovative interface components that makes it a memorable app.
Using the pre-made UIKit elements is faster and easier. It doesn't require up-front graphic design work, so programmers can work solo while they complete their functional app, hiring designers near the end of the project. It lets programmers mess around and try things with limited risk of loosing a lot of time and, most importantly, gets novice iOS developers familiar enough with UIKit and Core Animation to roll their own interfaces (see below).
You can easily add innovative interface elements, as Tweetie did, later in the project. In fact, it's best you do so, so your working app has some neat features  instead of a crappy Twitter timeline demo with Stage-4, fully-metastasized feature-creep.

... or Roll Your Own

This alternative option is best suited for development teams with graphic designer talent. (No, developers who have a pirated version of photoshop and get confused about how the Pen tool works do not count as graphic designers.) This kind of app typically involves making something completely new and innovative or copying existing, but non-standard, interfaces. Examples include Twitter's iPad app, which pioneered the accordion-style "infinite" navigation stack; Facebook's use of an "under the hood" menu, and (not to toot my own horn too much) the 500px iPad app's "floating sidebar" with pinch-to-zoom thumbnails. Even reproducing an existing system style of interface can be challenging if Apple hasn't provided their own public classes to do so.
You have to first understand that rolling your own anything in iOS is challenging and probably involves a lot of work. Creating a cohesive and consistent interface takes hours upon hours of design work before you even start to code. It should involve designers and developers working together to create an innovative and consistent user experience. Using open-source projects should be a means to an end; if you start with some neat menu demo project from github as the basis for your app, it's probably going to suck. Instead, start with an idea of what you want and leverage existing solutions to achieve this goal.
Creating your own interface requires an in-depth knowledge of both UIKit and Core Animation. You need to know how you can (ab)use existing tools to achieve the interface yo want. Even something as simple as adding a drop shadow to a navigation bar can be challenging. No? Don't think so? Try doing it with a UITableViewController's nav bar. You'll need to add the shadow gradient to to the nav bar to stop it from scrolling with the tableview. Then you'll quickly find a bug in some versions of iOS that makes UIBarButtonItem's in the navigation bar invisible when the bar's clipsToBounds is set to NO.
Writing your own super-innovative mega-awesome interface is going to require a lot of design work. You're going to need icons. Lots and lots of icons. However, use the system standard icons wherever you can. There are some really neat ways to use system UIBarButtonItem's pretty much anywhere, so use them.
With all that said, it can be really fun to do and create a consistent, rewarding user experience. I can't really stress enough, though, the dangers of this route. It can actually be too fun. When you get in the mindset of rolling your own things, you tend to forget about the ways that you can use existing things. This happened to me the other day when I found myself entirely reimplementing UIActionSheet. Seriously! I stepped back and ask myself what the hell I was doing! Constantly question yourself and ask if there is a better way to do things using existing tools.
Leveraging existing classes and only deviating from UIKit when necessary will minimize the risk that something will break in future versions of iOS and also save you development time now. Just look at Twitter's iPad app:
Twitter's iPad App
​Twitter's iPad App
Nice iPad App, Twitter! Innovative accordion-style navigation stack! And look! The entire key window appears to slide down to revel the tweet composer! That's awesome! But look at what else there: a popover. A simple instance of UIPopoverController with a content view displaying the user's photo collection. They didn't have to write their own, so they didn't. Perfect. Do you think they implemented their own UITableView for the leftmost navigation view? Or for the tweet list? Of course not. They used what they could and only built from scratch what they had to.
Facebook's iPhone App
​Facebook's iPhone App
Facebook's new iPhone app is pretty shitty, but they did introduce a really neat top-level navigation system: the key window appears to slide to the right to reveal a navigation menu underneath it. Cool!
Wherever possible, avoid using transparent .png's to achieve some effect. The system can hardware accelerate your app's graphics a lot easier if they're using a CAGradientLayer and not some UIImageView instance.
Most importantly ...
Under no circumstances should you subclass UINavigationController. Ever.
I don't often bold entire sentences on my blog, but when I do, I'm really fucking serious. You never - ever - need to roll your own navigation controller. The built in one will work absolutely fine. With a little ignorance of MVC, you can achieve all the custom transitions between view controllers you want without ever creating your own navigation stack or abstract base UIViewController class.

Don't Half-Ass it

Finally, don't half-ass your app's design. Don't just throw a drop shadow under all your navigation bars because you figured out CAGradientLayers. Don't use your app's name as the title text for all of your views in the nav stack. Don't throw 7 buttons onto a view and try to fake a UITableView just because you want a logo behind the "cells."
These are all things I've seen developers do in order to make unique apps. Well, they're unique alright, and for good reason.
So that's it. If you're new to iOS development or have no graphic designer available to help, and probably even if you're experienced with designer assistance, go with the first option and use what Apple gave you. If you have a designer holding your hand ever step of the way, you can cross the highway to building your own interface conventions (or re-implementing someone else's). But only when you have a concrete vision of what your app is going to look like when it's finished.

Designing Interfaces for iPhone


Designing Interfaces for iPhone

I gave a presentation this morning at Podcamp Toronto about designing interfaces for iPhone. The talk was a high-level description of how to organize and structure content in iPhone apps. The slides are available inKeynote and PDF. Slides were created in Keynote, but I've exported to PDF, too. I can't guarantee the fidelity of the export.
​Also, I release the slides under Creative Commons.

Why Objective-C is Hard to Learn


Why Objective-C is Hard to Learn

As an active member of "The Internet" and vocal Objective-C coder, I get a lot of questions surrounding the language. They're often framed around thinking about learning the language or trying to write an app, but they also usually involve a phrase like "Objective-C looks really hard" or "what are all those minus signs about?" Both of these are pretty good questions, and I'd like to address why someone might be more hesitant to jump into iOS or OS X development compared to, say, Ruby or Java.

Syntax

Let's talk about what a programming language is. A programming language is the human-readable code that expresses how a program behaves. A language consists of a syntax (rules for valid expressions and statements) and semantics (rules for how to organize those expressions and statements in meaningful ways to accomplish some task).
Most (common) programming languages out there are based on the C-style syntax of method invocation and the dot-syntax of accessing members of classes (well, structs in C). They'll usually implement their own brand of class definition (Java differs a bit from C# or C++), but the nuts and bolts of the language itself is the same. When approaching a new language, seeing similarities in the syntax makes people feel more comfortable, and most people know the C syntax.
Objective-C is a very different language with regards to its syntax. It's so different, even, that most people don't look at it long enough to realize that the semantics of the language are almost identical to C++, Java, or others.
Even other "weird" languages like Python or Ruby are accessible because they at least use the dot-syntax for method invocation and member access in classes. Lack of curly braces doesn't bother people for long because they were probably indenting their code anyway.
This is usually how introducing someone to Objective-C goes: I compare it with another OOP language.
No problem so far. Maybe they've seen lisp at some point, but they're usually OK with this.
OK they're freaking out a little and asking a lot of questions. But then things take a turn for the worse.
At this point, people usually start breathing into a paper bag and trying not to pass out.
What is all that typing? Those colons! The horror! Questions start poring in: What is that method called, anyway? performAction? Or something else? How does overloading work, then? Argh!
Forget the fact that we're not even talking about methods, really, we're talking about messages (a distinction I'm not going to make) and you refer to selectors like the one above asperformAction:withTwoParameters:. Most people don't care anymore.
The language is a strict superset of C, which is kind of cool, except in some ways it's holding the language back when compared to other modern languages. Being a superset of C adds a lot of cruft which, we'll see shortly, compounds a problem with complexity of Objective-C.
Objective-C is a large language. I mean that in a very special way: its syntax is complex and extensive. Apple has been making strides in reducing the size of the Objective-C language, like their slow-but-steady transition away from classical C-style header files. However, they're also adding to the language in ways that makes the code expressed in Objective-C simpler:
  • Synthesizing properties
  • Dot-syntax for accessing getters/setters
  • Garbage Collection
  • Blocks (closures)
  • Automatic Reference Counting
  • Weak references
So while the language is getting larger, the code used to express ideas in the language is getting less complex.

Runtime

The Objective-C runtime is dynamic, which seems counter-intuitive when you think about Objective-C's relation to C. C is about as close to the metal as you can get without writing assembly code, so you'd expect Objective-C to be very rigid, but in fact it's a very fluid, dynamic runtime. Among other things, Objective-C lets you do function currying, adding and removing methods from classes at runtime, and reflection.
Unless you've played with other languages that support these features, like Ruby or Lisp, then this feels really weird. Don't worry! Lots of great things feel really weird the first time you try them, like broccoli or sexual intercourse.

Frameworks

Objective-C is almost useless without the Cocoa/Cocoa Touch frameworks used by developers to build apps. It would be like trying to write a web app in Ruby from scratch without Rails.
Cocoa is very old and very large. Again, Apple is making progress in reducing its complexity year after year and it's iOS-based cousin Cocoa Touch is very lean. However, there is still a lot to learn when making even the most simplest of apps. While the header files and developer documentation provided by Apple are wonderful resources, there is still a lot of assumed knowledge. Take the contentStretch property on UIView, for instance. This is all the header file has to say:
@property(nonatomic) CGRect contentStretch __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0); // animatable. default is unit rectangle {{0,0} {1,1}}
That's it? What does it do? Well, it defines the stretchable content area, I suppose. But how? And what is this unit rectangle? It's a property you could probably live without ever knowing about, but when you need to use it, how would you know?
Cocoa/Cocoa-Touch is large and the only way to get better at it is experimentation, which is daunting to a newcomer.

History

Historically, Apple has driven forward development on the Objective-C language, the Objective-C runtime, the Cocoa/Cocoa Touch frameworks, and the Compiler to build Objective-C programs. There is a high level of co-design in these different areas, which makes "Objective-C' such a nebulous term.
Comparing Objective-C runtime, framework, and language relationship
When learning Objective-C, it's not just a language or a framework or a runtime or a compiler, it's all of these things. Something as integral to the language like Automatic Reference Counting involves the language semantics (no calling dealloc directly anymore), the compiler (obviously), and strongly enforced naming conventions in the Cocoa/Cocoa Touch frameworks.
This tightly-coupled co-design is unique to Objective-C. There are other languages that run on .Net, such as Iron Python. Lots of language use the JVM besides Java, like Clojure. Even Ruby and Rails are two distinct entities and projects. The only significant effort to use a different language with Cocoa/Cocoa Touch and the Objective-C runtime, Mac Ruby, was a project largely backed by Apple before they abandoned it.
Objective-C, and the corresponding frameworks, runtime, and compiler, exist in a silo from the rest of the software development community.

Future

The evidence we've seen over the past 4 years or so indicates that Apple is attempting to reduce the size and complexity of the Objective-C language. They're attempting to make it easier to approach by doing away with manual memory management and classical C header files; they're also introducing modern programming language concepts like Automatic Reference Counting and dot-syntax for getter/setter access. But for now, Objective-C remains difficult to approach; only the appeal of writing hit iOS apps seems to be driving its popularity.