A phone by any other name would smell as sweet…

The general consensus is that there will be a new iPhone announced next week. I, like others, think it’s going to have new features and capabilities. But how is Apple going to label this new device?

iPhone 3G?

It’s entirely possible that Apple will keep the same name as the previous version. There’s precedence in the Mac product line: we’ve had MacBook Pros for several years now with various ways of distinguishing different product iterations (“Late 2008”, “Unibody”, etc.)

Given Apple’s reluctance to publish any of the device’s hardware capabilities, this would seem to make sense.

Except for one small problem. It’s likely that the new iPhone will have a faster processor and more memory. Some applications will be written to take specific advantage of these improvements. And that, of course, means that you need a way to let iTunes customers know if those applications are compatible with their device.

I don’t see Apple putting “iPhone 3G (2008)” and “iPhone 3G (2009)” anywhere in the iTunes UI. It’s just too confusing.

iPhone 4G?

What about having artificial product designations like they did with PowerPC desktop Macs: “G3”, “G4” and “G5.”

The problem here is that 3G refers to a network service, not a product generation. If this naming convention is used, customers are bound to wonder if a “4G” product works on their 3G network.

iPhone 3G Plus?

So maybe they do something like we’ve seen with the iPod product line. Using terms like “Classic”, “mini”, “nano” and “shuffle” to differentiate the products.

The problem here, of course, is that there’s only one product on sale. Unless Apple plans to keep the current product on sale (at a reduced price,) this just doesn’t make sense.

I’m not going to make any predictions on the device’s name, but I will be paying close attention. The ultimate choice is likely to offer some subtle clues regarding Apple’s plans to evolve this product in future revisions.

Of toolbars and actions

Another area where I find iPhone development to be a bit convoluted was with toolbars and action sheets. The sheets are conceptually tied to the toolbar, yet there is no glue to combine UIActionSheet with UIToolbar. It’s also fairly difficult to represent your application state in the toolbar—an example is the refresh button in Twitterrific that turns into a cancel button while the refresh is taking place.

And then one day it dawned on me: an iPhone toolbar with an action sheet is like a menubar with menus on the Mac desktop (turn your phone upside down and there is even some visual similarity.)

After investigating some of the design patterns for NSMenu and NSMenuItem, it was clear that this would work well on a mobile interface as well. My implementation is a subclass of UIToolbar named IFActionToolbar.

In it’s simplest form, you attach a list of items to one of the toolbar’s bar button items:

@interface MyViewController : UIViewController
{
  IBOutlet IFActionToolbar *toolbar;
  IBOutlet UIBarButtonItem *barButtonItem;
}

...
@implementation MyViewController  

...

- (void)viewDidLoad
{
  [super viewDidLoad];

  IFActionToolbarActionItem *actionItem = nil;

  NSMutableArray *actionItems = [NSMutableArray arrayWithCapacity:3];
  actionItem = [[[IFActionToolbarActionItem alloc] initWithTitle:@"One" target:self action:@selector(firstAction:)] autorelease];
  [actionItems addObject:actionItem];
  actionItem = [[[IFActionToolbarActionItem alloc] initWithTitle:@"Two" target:self action:@selector(secondAction:)] autorelease];
  [actionItems addObject:actionItem];
  actionItem = [[[IFActionToolbarActionItem alloc] initWithTitle:@"Cancel" target:nil action:NULL] autorelease];
  [actionItems addObject:actionItem];
  [toolbar attachActionItems:actionItems toItem:barButtonItem];

  [toolbar update];
}

The IFActionToolbarActionItem is just a simple wrapper object that associates a title with a target and action. These action items are used to automatically construct the action sheet when the user taps on barButtonItem. If you’ve ever constructed an NSMenu using NSMenuItems, this will feel quite familiar.

Additionally, the toolbar supports an -update method. This method calls the assigned delegate to enable or disable toolbar buttons, set the image for the toolbar item, change the title of the action sheet, hide or show items in the action sheet, and define the cancel or destructive buttons in the sheet. Again, similar in pattern to how NSMenuItems are maintained.

Any time you call this update method, the UIToolbar is configured automatically. It makes it much easier to reflect the state of your controller in the view.

I’m not going to spend too much time discussing the inner workings of this class: the picture of a sample project is worth a thousand words.

One thing I would like to caution you about: don’t get too carried away with enabling and disabling items in the action menu. In our UI testing, we found that changing the list too much was confusing for users. It’s like the “adaptive menus” used in Microsoft Office: it’s very difficult for a user to adapt to your interface if it’s constantly changing. Just because you can doesn’t mean you should.

Again, I hope this code is useful in your own iPhone projects. Enjoy!

Matt Gallagher deserves a medal…

Every once in awhile you read a blog post that completely changes the way you think about a problem. Matt Gallagher’s Cocoa With Love is one of those blogs where it happens often. If you’re not subscribing to his RSS feed, do it now.

In particular, this post addressed a problem that every iPhone developer has encountered: any kind of settings or form UI is a pain in the butt if you follow Apple’s sample code. And, of course, this is exacerbated because these essential interfaces aren’t very fun to code. For both Twitterrific and Frenzic, it’s been a frustrating experience: I wanted to fix how this standard UI was created and maintained.

The motivation

Before I start talking about what I did using Matt’s concepts and code, I’d like to discuss the need for settings in an application.

There are some people who think that settings should only be in the Settings app. There are others that think they should only be within the application. I can honestly see how both groups are right, but what both sides fail to realize is that it’s often a matter of context.

If you’re working on a simple application with simple needs, relying on the infrastructure provided by the SDK is fine. You may have some additional support load for users who have problems finding your settings, but that’s a reasonable tradeoff for saving development time. Sophia Teutschler’s Groceries app is a fine example of where the built-in settings shine: I turned off the Marker Felt font several months ago, and I haven’t touched it since.

In the case of Twitterrific, there were three main reasons why we built the settings into the application:

  1. We could not split the settings between two locations. From a user’s point-of-view, it’s incredibly confusing to have an application’s configuration in two places. This would have happened if we had put the account settings in the application and everything else in the Settings app.
  2. Some of the settings are things that people will change on a fairly frequent basis. For example, the dark theme works best at night, while a light theme is better during the day. Leaving the app to make these types of adjustments is inconvenient.
  3. The Settings app can’t handle preferences that are “dynamic.” An example is a vibration setting for the notification: there’s no way to make this appear on an iPhone but not on an iPod touch.
As we start to see more complex applications appearing on the App Store, I think there will be a lot of other developers coming to grips with settings in their applications. That’s where my code comes in…

The solution

I’ve taken the basic concepts that Matt presented in his article and extended them to create a pixel perfect replica of what you see in the Settings application. Instead of configuring applications using a property list, you do it with some very simple code in a view controller. (Domain-specific languages, such as those found in Ruby, were an inspiration for the methods used in this code.)

And if you’re not doing settings, the classes are still very handy for making user input forms. They were used in all of the search forms used in the new version of Twitterrific.

To give you a quick taste of how it’s used, here’s a complete implementation of a table view controller that presents a single group with a text field and a switch control. In just six lines of code:

- (void)constructTableGroups
{
  NSMutableArray *cells = [NSMutableArray array];
  IFTextCellController *textCell = [[[IFTextCellController alloc] initWithLabel:@"Text" andPlaceholder:@"Placeholder" atKey:@"sampleText" inModel:model] autorelease];
  [cells addObject:textCell];
  IFSwitchCellController *switchCell = [[[IFSwitchCellController alloc] initWithLabel:@"Switch" atKey:@"sampleSwitch" inModel:model] autorelease];
  [cells addObject:switchCell];
  tableGroups = [[NSArray arrayWithObject:cells] retain];
}

The real beauty of this code is that it’s incredibly easy to change. Settings and forms tend to evolve over the lifetime of a project, so using these simple declarations for the table view layouts makes it much simpler to adapt to new requirements. If I need to change the switch control shown above into a choice list, I can do it in a couple of lines of code.

So without further ado, here’s the source code in a sample project. The code is well documented, so you shouldn’t have any problems figuring out how it all works. Start by looking at the RootViewController, then take a look at the SampleViewController, followed by the SampleAdvancedViewController. If you’d like to incorporate this code into your own project, just grab all the classes with the Iconfactory prefix (“IF”.)

The license

Previously, I’ve released source code on this site without any licensing at all. This time, I’m going to try something new. You can do anything you want with this code with one requirement: you need to give the Iconfactory some link love in your product.

For more details on the licensing terms, check out the Licensing.rtf file that’s included in the sample project. If you can’t abide by this restriction, please get in contact and we can try to work something out.

I hope this code saves you as much time as it has saved me. Enjoy!

A thought experiment

Assume the following:

  • You have an application that you’re selling on the App Store. This application, MyApp 1.0, works on both iPhones and iPod touches with the 2.2.1 firmware.
  • The compelling new APIs in iPhone SDK 3.0 allow you to implement a bunch of great new features in your product. Let’s say you add a Map View and release MyApp 2.0 (after SDK 3.0 is released.)

Now, what happens if you find a bug in MyApp? Let’s say it’s a simple thing like dereferencing a nil pointer that causes a crash: something that can be fixed with a single line of code. You easily fix this bug, but you can’t give this fix to all of your customers. Why?

The problem lies with iTunes Connect. It only allows you to upload a single binary. And that single binary is specified to work with a single version of the iPhone firmware. Even if you have branching tools in your version control system, you can’t use them to produce an update for both versions of the SDK.

This presents a problem for customers who are still running the 2.2.1 firmware: they can’t get your fix until they upgrade to the 3.0 firmware.

Despite the fact that there will be a lot of uptake on this new release and all its great new features, it still feels wrong that an iPod touch owner will need buy the update in order to get my fix. I don’t like it when customers have to pay for my stupidity.

If you agree, please dupe Radar ID 6735814. Thanks!

Front Row To Go

Everyone and his brother has a prediction about Apple and the mythical “netbook.” This is mine.

Before I get into the actual prediction, let me say that I’ve come to this conclusion by looking at Apple as a business, not as a supplier of shiny gadgets for our technolust. As much as we love the things they make, their goal as a corporation is to make the stockholder’s happy. They do that by selling lots of products. We’re just a means to that end.

A lot of the speculation regarding the netbook says that it provides functionality in the price gap between a $200 iPhone and a $1000 MacBook. While that’s true, it misses the point.

Apple would rather sell you another device in addition to the ones they already sell. They’re not interested in cutting into (presumably healthy) MacBook sales with a netbook. Likewise, selling a bigger touch device could cut into iPhone sales: keep your crappy cell phone and buy the netbook to throw in your purse or backpack.

One of the things that saved Apple was a simplified product line based around professional and consumer uses. Does it really make sense to have more than one consumer-level device for laptop computing? The MacBook already kicks ass in that department: having another device in that category just muddies the water.

But what if there was a device that could work in conjunction with your other Apple products? Something that extended their capabilities. Something that made each product better for a few hundred dollars.

Apple and their shareholders would love this: you’d buy the iPhone and the “netbook”. And eventually the MacBook. And maybe an Apple TV. And probably an iPod, too.

So what are some of the problems with the current hardware lineup?

  • iPhone / iPod touch – Small screen, small keyboard.
  • Mac – No touch screen, running Front Row prevents using your Mac for other things.
  • Apple TV – crappy remote, no keyboard.
  • iPod – Very small screen with no touch screen or keyboard.

So what kind of product could fill in these gaps? I call it “Front Row To Go.” Think of it as a second screen for the current hardware. Something that could:

  • Display photos on a larger screen than on the iPhones and iPods. It would also be effective as an adjunct to iPhoto on the desktop: Microsoft’s Surface prototype shows how effective it is to display pictures on a horizontal surface that can be manipulated by multiple viewers.
  • Provide a touch screen keyboard for the iPhone and Apple TV: a better input mechanism than hunting and pecking on chiclets. (Maybe this is the reason Bluetooth keyboards aren’t available for the iPhone.)
  • Show movies on a larger screen: anyone who’s taken a transoceanic flight knows that looking at the iPhone/iPod screen for more than a couple hours can be quite tiresome. An added benefit is that the player’s battery wouldn’t be consumed by the display’s power needs.
  • Provide touch input to desktop applications. Multi-touch is never going to happen on a vertically oriented display, so make a separate device that works horizontally. An obvious benefit to developers is that they don’t have to rewrite code: if it makes sense, multi-touch can be added to enhance current applications.

As with all other Apple products, Front Row To Go could obviously work as a standalone device. Sync your content onto the device and take it with you: no more dragging a laptop to a family reunion just because Aunt Bessie can’t see the tiny photos on the iPhone. Get your bookmarks and feeds from the Mac and surf the web using Front Row To Go’s version of Safari while you’re listening to music or watching TV.

As far as how these features would be implemented, that’s anyone’s guess. There might be an API for developers, or maybe it’s a closed system. The device might be able to play iPhone games or run multiple iPhone applications at once (much like the current Dashboard works in Mac OS X.) With a common base of OS X running throughout the product line, pretty much anything is possible.

And that gets to the real point of this essay: think about what Apple has learned from the halo effect surrounding the iPod (and now the iPhone.) If you have any doubt that this effect is alive and well, drop into an Apple Store on any weekend and take a look around: plenty of customers who are happy with one product and looking at others.

In my opinion, these consumers are the ones that Apple will target with a “netbook,” not the ones that are jonesing for a sexy little machine that fills a perceived gap in the product range. I hope I’m right, because I’d love to be one of those customers lining up to buy Front Row To Go.