this is totally gonna work…

The iPad

January 31st, 2010

iPad

After letting the dust settle around Apple’s announcement of the iPad, I wanted to take a more measured, less reactionary look at the new device. The coverage that immediately followed the announcement was even more biased to both extremes than coverage of the President’s State of the Union address which occurred the same day. I know that there’s a growing body of folks who just don’t like Apple, but I was surprised at the level of antipathy.

Those that damned the iPad seemed to come in two flavors: those that saw the iPad as the embodiment of corporate greed and walled gardens, and those that thought the device didn’t measure up to their personal expectations.

There is a sizable (and growing) population of folks that simply will not purchase an Apple product or participate in its eco-system for various reasons. I think that’s fine. While I personally enjoy their products, I don’t believe that everyone has to agree with me. I get no less enjoyment out of my MacBook or iPhone by someone else having a Lenovo ThinkPad or an Android Phone.

Unfortunately, that view isn’t shared by many. Take the flame-baiting in the aftermath of the iPad announcement and replace the term “iPad” with “gay marriage” and the arguments look nearly identical. Gay marriage is so upsetting to conservatives that they can’t imagine being in a world where it exists. It’s not that gays are coming into their homes and performing unspeakable acts, it’s that they can’t imagine even being on the same planet with them. So it goes with the iPad—there are the FSF types who can’t imagine living in a world where Apple controls every single thing that goes on a device.

The Prez

I’m not aware of anything in the President’s address that said every man, woman and child in the U.S. was going to be forced to use an iPad. As far as I know, people are still free to choose whether or not they wish to purchase and iPad and wander about in Apple’s walled garden. Don’t want an iPad? Fabulous. Don’t buy one.

Folks, it’s a big world out there. There doesn’t have to be a single winner. Even as Apple trumpets having over 50 million touch devices, that pales in comparison to the worldwide population of those who could afford such devices. That’s even without considering the fact that if you own one iPod/iPhone, you probably own another. In terms of real numbers, I don’t see a growing “collectivization” movement to dress everyone in Apple products. If Apple were interested in market share, they would charge a lot less for their products.

iPad Protest

Besides calling the iPad a freedom-killer, the other category of critiques were that the device was simply disappointing. This reaction particularly surprises me. Yes, there are certainly quibbles to make about various features of the device (no camera, no multitasking, etc.) but the dismissive observations that the iPad is simply “a big iPhone” I think misses the point. Yeah, it is a big iPhone, which has been a huge success by any measurement. If you love the iPhone, then the things you most wish it had were more of are screen real-estate and speed. So making one that is bigger and faster is totally logical. What did people expect? Roomba integration? A toaster? 3D goggles?

ReadWriteWeb attempted to break down the anger with this graph:

TweetPad

Looking at this chart, I would categorize 38% of the complaints as just pure snark. The next 27% that dismiss it as a “big iPhone” are missing the point. The remaining complaints are all valid and worth talking about a bit:

No Flash

Hooray, I say. I don’t run Flash on my desktop or laptop if I can help it. I simply do not like Flash. It rarely enhances my experience on a site and often pegs my CPUs for no good reason. Yes, I’m aware that Adobe has to do a lot of video codec work without the aid of hardware, but that doesn’t address the jarring user experience that is Flash. I have not missed Flash on the iPhone either. If you want Flash, don’t buy a iPod, iPhone or iPad. It’s as simple as that.

Oh, and if you’re running a Mac and feel the same way, do yourself a favor and install the Click to Flash plugin, which lets you ignore Flash on the web completely.

No Multitasking

I’m on the fence about this one. I’m not convinced that multi-tasking is essential for a device like the iPhone or the iPad. The truth is, I have not had many instances where I thought, “Damn! If only I could run two apps at once!” I think a lot of people think they want it because their computer has this capability.

I think that’s the point that is being missed. The iPad is not, in any way, being put forth as a general computing device. In fact, to categorize it as a “tablet PC” is to completely misunderstand the iPad’s underlying design philosophy. When I watched the presentation and demonstration video what I saw was easy execution of tasks. Nobody was demonstrating bit-rates, frames-per-second, or tail-call optimization. The underlying technology and “platform” are simply the means to an end.

This is a different enough device that people will have to change their thinking about their relationship with their computers. I don’t think it means a compromising relationship, but one that is different from today. Frasier Speirs eloquently called the inability to comprehend this shift as Future Shock.

Lock-In

Another major complaint of the iPad and the entire Apple/iTunes ecosystem is that it is a closed system. Users don’t get to mix and match devices freely from other manufacturers. The party-line from Apple is that they want to control every aspect to provide the best user experience. Detractors argue that it is part of Apple’s plan to own all of your content like Big Brother (as Microsoft has attempted to in the past).

I get why people feel uncomfortable with handing Apple control of their stuff. Personally, I have a lot of Apple products in my house and I’m happy to give them that control because, for me, it is a better experience. I will happily trade some vague notion of “freedom” for stuff that just works. Endless fiddling and integration of disparate technologies isn’t freedom at all—it’s an enslavement of the most precious resource I have, which is my time.

Not everyone is happy with that and they prefer an alternative. Hey, no problem. Live and let live. You want to run Boxee on Linux connected to an iRiver. More power to you. I won’t sneer at you or call you a fool. If it makes you happy, your choices don’t affect me in the slightest.

As an aside, if anyone complaining about the lack of Flash is also complaining about lock-in, that person needs to be hit repeatedly with a rake.

No Camera

Sigh. Yeah, this one is a bit disappointing. I don’t really care so much about having for video chatting (which I do maybe once a year). But I really like using a camera to capture things I would otherwise have to take a lot of effort to write down. How cool would it be to have your iPad in a brainstorming session where you can still jot a few notes down then associate a snapshot of the whiteboard?

Now there is an interesting design conundrum here. Do you put the camera on the front or the back? Depending on the tasks you expect to perform, this makes a huge difference. If you want people to see you, you put it on the front and figure out how to give the user the user visual feedback so they can position the camera.

If you want to take pictures of other things, you put the camera on the back and use the video display as the viewfinder. However you can’t reasonably reverse the tasks for these two positions. OK, so do you put two cameras on? I don’t know. How do you control them? Does each bit of software implicitly decide which camera to enable? Does the user have to decide?

I don’t know the answer, but I would be very surprised if a camera didn’t show up in the next version of the device. They put cameras in the iPod Nanos for cryin’ out loud. Surely they can figure out how to stick one in an iPad.

More AT&T

The amount of bad press AT&T has received via the iPhone has to make them wonder what sort of devil they’ve made a deal with. Are there serious issues with AT&T? You betcha. Do they effect everyone? I’m not convinced. Coverage in San Francisco and Manhattan seem acutely poor, but in my corner of the Northwest coverage is pretty damn good.

The non-iPhone types love to make fun of AT&T, fueled largely (I think) by schadenfreude. I’d be very curious to see how other carriers handle a similar load. I used to work in that industry and the mentality among carriers is all the same. They all want to wring every penny they can out of you by charging for every bit you use. Let’s not kid ourselves.

Kudos to Apple for making a WiFi-only version. For me, this is a pretty compelling configuration. I’m an urban kid. There are few places I go where I can’t get some kind of access to WiFi. In the cases where I can’t get WiFi, I have an iPhone. Plus, I imagine using an iPad primarily at home, or on vacation, but not for commuting.

I’m no AT & T apologist—there are some serious issues they need address— but I’m not convinced that this makes the iPad a “failure”.

Conclusion

Am I an Apple apologist? I hope not, but people are notoriously bad judges of their own character. What I can say is that there are certainly things about the company that frustrate both as a user and developer. However, I am still more delighted by their products than I am frustrated with them. When that balance changes, I’ll move on to something else.

I’m pretty jazzed about this device, both as a consumer and as a developer. What sucked me into the iPhone was how it just oozed with utility. Not in terms of potential energy, but in that it fulfills the notion of computers as and extension of our own minds. The iPad just takes the next step forward. I can’t wait to see how it all unfolds.

P.S. Just I’m glad to see the iPhone finally get some competition, I’m also looking forward to somebody putting up a good fight against the iPad.

Posted in Apple, UX | 7 Comments »

Prototyping with Briefs

January 10th, 2010

One of the best sessions I saw at the 2009 WWDC was titled “Prototyping iPhone User Interfaces”. In this session, Bret Victor laid out a strategy and some techniques for building cheap prototypes on the the device in lieu of “static” mockups.

After returning from WWDC I was inspired to try this technique out and after playing with the idea for a bit, it was clear that there was a lot of repetition in the process. To really make prototyping cheap, we need a simple framework that makes the process fast and easy. Enter Briefs, a lightweight iPhone application that allows you to embed and run simple prototypes built with nothing more than images and a property list.

With Briefs, you don’t write a separate application for the device (imagine the provisioning headaches), but instead embed separate prototypes (called “briefs”) into a single Briefs application. Briefs is still pretty new and I expect to see (and contribute) many enhancements, but if you like this style of application development, it’s certainly worth spending some time with Briefs.

Let’s look at how it works. We’re going to start with the goal of prototyping the built-in Photos application. Now obviously, nobody is going to actually re-write the Photos app, but since we all have familiarity with it, it’s a good example to see how a working application can be expressed as a Briefs prototype.

Getting Briefs

Before we do anything, we need to get Briefs on our local machine. Briefs is distributed in source-only form via GitHub. You’ll need to find a nice place to check out the two main Briefs project, then do the following:

1
2
3
4
$ git clone git://github.com/capttaco/Briefs.git
$ git clone git://github.com/capttaco/Briefs-util.git
$ cd Briefs
$ git submodule update -i

In order to put our first Brief together, we need to build a command-line tool that is part of the Briefs project. Open the Xcode project in the Briefs folder (Briefs.xcodeproj) and select the “Briefs Compactor” target and set the architecture to “Base SDK”.

Screen shot 2010-01-10 at 7.50.17 AM.png

Now execute the target to build the compact-briefs executable. When it’s finished, Xcode will put the final binary in build/Debug/compact-briefs in the Briefs project directory. Copy this file to a location in your $PATH. Personally I like to keep such stuff in ~/bin. We’ll need this command in a little bit.

How it Works

Before we dive into our project, we should get a little terminology under our belt. Each application prototype you create is called a “Brief”. Each Brief is composed of one or more “Scenes”. Scenes usually have an associated image, so you can think of a scene and a screen in the application as being more or less equivalent.

Scenes can also have any number of “Actors”, which are regions on the screen that perform some action when touched. For example, to mimic navigating to a new view via a view controller, a region on a table view could be rigged to an action that slides another scene into place.

Briefs are expressed as Property List (Plist) files in the Briefs application. If you like writing XML or are proficient with the Property List Editor application, then you’re golden. Otherwise there is another format in which you can write your brief that compiles down to a final Plist. This is the route we’ll explore in our prototype.

Protyping Photos.app

Generate Image Files

Now let’s generate the image files for our prototype. In the case of the existing Photos app, I just screen-captured the running application on the simulator. Obviously, you won’t be in the same position with a new application, so you’ll need to generate some images by hand.

If you use OmniGraffle, there are several good iPhone stencil sets on Graffletopia. If you prefer Photoshop, checkout the exhaustive iPhone GUI PSD. Either one of them will generate the appropriate files. There’s no requirement that the image files look like the iPhone. You could use a tool like Balsamiq or scan hand-drawn sketches to generate very simple wireframe sketches. Regardless, all you need to do is produce PNG, GIF or JPEG files that fit within the normal iPhone dimensions (320 x 480).

Let’s create a folder called “photos app” and put our image files in it. I’ve created a tar-ball of this entire project, which you can download, explore and run.

Writing the Brief

Let’s think a bit about the flow of our application. We’re only going to implement a sub-set of Photo.app’s full navigation—we’ll just implement the flow for the Hawaii photo album. We have a top-level screen that shows all of the photo albums. From there the user can select “Hawaii” and drill into a display of a few images in the album. Touching any of the images will take the user into the image browser where users can go back and forth between the various images. Each screen has a common “back” button in the top-left. The overall screen layout and flow looks like this:

photos-app-flow.png

The pink boxes highlight the touchable areas in each scene. The arrows between them show which scene a particular area navigates to. In Briefs-parlance, each screen is a “Scene” and each pink box is an “Actor”.

Let’s step through the Brief (the photos.bs file), a bit at a time. If you get lost, refer back to the application flow diagram above.

First we declare that our starting scene is the “Home” scene. Next, we define that scene with the image home.png as the background image and one actor that will navigate to the next scene. The position and size of this actor corresponds to the table cell labeled “Hawaii”. If we wanted to support the table rows, we’d need to add an actor for each one.

When the user touches the “Hawaii” row, we’ll transition the “Hawaii” scene (defined shortly) by executing a “push left” animation. This will mimic the standard animation of pushing a new view controller onto the navigation controller stack:

1
2
3
4
5
6
7
start:Home
scene:Home
  image:home.png
  actor:HawaiiPictures 
    position:0,123 
    wh:320,53
    action:goto(Hawaii, push left)

Next, we’ll define a scene that shows the thumbnail images for each photo in the Hawaii album. This scene will display the hawaii.png background image and has an actor for the return navigation button in the upper-left as well as for each thumbnail image. Note the differences in the direction of the push animation in the actors. The “back” button pushes right (like the normal return navigation animation), while the thumbnails push left.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
scene:Hawaii
  image:hawaii.png
  actor:Home 
    position:17,30 
    wh:87,24 
    action:goto(Home, push right)
  actor:image1 
    position:5,69 
    wh:72,72 
    action:goto(Image1, push left)
  actor:image2
    position:84,70
    wh:72,72
    action:goto(Image2, push left)
  actor:image3
    position:162,70
    wh:72,72
    action:goto(Image3, push left)

Now we’ll define the scenes for each of the three images. Each image scene has an actor for the return navigation button in the top-left. The first image also has two actors to navigate to the next image. The NextImage actor is for the navigation button in the toolbar, whereas the NextImageSwipe actor covers the right side of the image itself. This is done to mimic the swiping motion normally used to navigate photos. Right now, Briefs only supports single-touch interactions so it won’t behave exactly like the real application in supporting swipes.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
scene:Image1
  image:image1.png
  actor:NavigateBack 
    position:14,33 
    wh:44,23 
    action:goto(Hawaii, push right)
  actor:NextImage 
    position:202,450 
    wh:23,17 
    action:goto(Image2, push left)
  actor:NextImageSwipe 
    position:156,60 
    wh:160,380 
    action:goto(Image2, push left)

The “Image2″ scene is a lot like the “Image1″ scene, except that it has button and swipe actors for both the previous and next images:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
scene:Image2
  image:image2.png
  actor:NavigateBack 
    position:14,33 
    wh:44,23 
    action:goto(Hawaii, push right)
  actor:PreviousImage 
    position:94,452 
    wh:23,17 
    action:goto(Image1, push right)
  actor:PreviousImageSwipe 
    position:0,60 
    wh:160,380 
    action:goto(Image1, push right)
  actor:NextImage 
    position:202,450 
    wh:23,17 
    action:goto(Image3, push left)
  actor:NextImageSwipe 
    position:156,60
    wh:160,380 
    action:goto(Image3, push left)

Finally, the last image scene. It only has “backward” navigation in the photo set since we’ve only put three photos in our album:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
scene:Image3
  image:image3.png
  actor:NavigateBack 
    position:14,33 
    wh:44,23 
    action:goto(Hawaii, push right)
  actor:PreviousImage 
    position:94,452 
    wh:23,17 
    action:goto(Image2, push right)
  actor:PreviousImageSwipe 
    position:0,60 
    wh:160,380 
    action:goto(Image2, push right)

We’ve just done simple scene-to-scene transitions in this Brief, but there are also several transitions you can perform directly on actors such as moving them, fading them in and out and others. I’ve created a syntax cheatsheet which you can use as a reference for your own Briefs.

Compiling the Brief

Once we have our photos, it’s time to start writing our Brief. As mentioned earlier, the Briefs application consumes Plist files. However you can’t just create one out of the box because it will only have image file references in it, but not the actual data. The reason we built the compact-briefs command earlier, was so that we could take our intermediate Briefs file (usually called a source brieflist) and embed the image data directly in the final product.

However I find editing XML tiresome, whether it’s by hand or with a tool. Briefs provides an alternate syntax in which to write briefs which is transformed by a Ruby script into the intermediate Plist format. You can then compile the source brieflist to the final format using the compact-briefs command. The flow between formats and tools looks like this:

briefs-flow.png

In the Briefs-util project (which you checked out earlier), you can find the Ruby script in BS/bs. I run these tools all at once in a script named compile:

1
2
3
#!/bin/bash
~/Development/Briefs-util/BS/bs photos.bs > photos-source.brieflist && \
	~/bin/compact-briefs photos-source.brieflist ~/Development/Briefs/sample/photos.brieflist

Installing the Brief

The next step is to build the Briefs application with our newly-compiled Brief. Switch back to the Briefs Xcode project and choose the “Briefs” application target. If you haven’t yet added the new brief to the Xcode project, right-click on the “My Briefs” and choose Add > Existing Files. Select the photos.brieflist file in the samples directory and in the following dialog make sure the checkbox at the top is unselected.

Screen shot 2010-01-10 at 2.08.27 PM.png

Now you can build the Briefs application for either the simulator or the device. If you’re building for the device, make sure you have a proper provisioning profile in place that matches the bundle identifier of the project. Now we can Build & Run the project, and our photos.brieflist should appear in the list:

Screen shot 2010-01-10 at 8.54.47 AM.png

Select our new Brief and play with the application. To exit a Brief, touch and hold your finger down until a new screen appears asking you if you want to exit the current Brief.

Screen shot 2010-01-10 at 11.54.51 AM.png

Distributing the Brief

The idea behind these prototypes is putting a tangible example in front of users to get their feedback. So what do you do if you want to distribute Briefs to a wider audience? Ad-hoc builds are a pain and require access to the physical device. Fortunately, Briefs provides a tool called “Briefcasts”, which is simply one or more Briefs embedded in an RSS feed. The Briefs application can retrieve Briefcasts via HTTP, so distributing Briefs is a snap if you have a web server to serve new Briefcasts from. This means you can install the Briefs application once on a device and provide updates anytime without having direct access to the hardware.

Currently, there isn’t a tool to easily create a Briefcast directly out of a list of Briefs. For now, the project web site recommends copying and modifying the RSS template below:

<?xml version="1.0"?>
<rss version="2.0">
  <channel>
    <title>Briefcast Demo</title>
    <link>http://island.local/~alex/briefcasts/</link>
    <description>Demonstrate how awesome it is to use a briefcast to get briefs on the iPhone.</description>
    <language>en-us</language>
    <pubDate>Thu, 12 Nov 2009 03:05:00 GMT</pubDate>
    <lastBuildDate>Thu, 12 Nov 2009 03:05:00 GMT</lastBuildDate>
    <item>
      <title>Photos.app Sketch</title>
      <enclosure url="http://island.local/~alex/briefcasts/photos.brieflist" length="954708" type="application/brief" />
      <description>An example brief of the built-in Photos.app.</description>
      <pubDate>Sun, 13 Sep 2009 03:05:00 GMT</pubDate>
      <guid>http://island.local/~alex/cast/1#item1</guid>
    </item>
  </channel>
</rss>

The bits marked in bold need to replaced with your particular details. In the example above I only have one Brief, but if you had more than one, you would just include additional <item> elements. You need to have this RSS file on disk as well as the brieflist file referred to in the <enclosure> tag.

Assuming that you have your web server all setup with the RSS file as well as the Briefs files, you can launch the application and add the Briefcast by selecting the “+” button in the top-right of the home screen. Enter the details on the next dialog and touch the “Save” button:

Screen shot 2010-01-10 at 9.20.37 AM.png

On the next screen you’ll see the details of the Briefcast. Each Brief in the Briefcast will be listed under the section titled “Enclosed Briefs”. Touch the “Download this Brief” button to retrieve the associated brief.

Screen shot 2010-01-10 at 9.20.49 AM.png

Once the brief is downloaded, you end up on a rather unhelpful confirmation screen:

Screen shot 2010-01-10 at 9.16.27 AM.png

You have to touch the screen, then navigate back to the top. Then you’ll find the new Brief in your list of briefs. To update the Brief, you navigate back into the Briefcast section from the home page and download the correct Brief again.

One nice enhancement I’d love to see is a custom application URL for Briefs so that you could just email the link to someone. They could read the email from their device, select the URL and Briefs would launch and download the newest Briefs.

Conclusion

Briefs is a great tool for building live prototypes. Since it’s a relatively young project, it still has a lot of rough edges, but I expect it to mature over time.

Don’t hesitate to dive into the code behind Briefs. There are occasions when Briefs (the application or the command-line tool) will crash without much detail. I found that this is usually the result of bad syntax in the Briefs so a little sleuthing may be required to get things working.

Resources

Here’s a list of related resources:

Tools of 2009

January 6th, 2010

I suppose if I were really on the ball I would have posted this right after New Year’s Day, but I needed to ruminate a bit on what was worth summarizing for 2009. In the end I decided to talk about the tools I found in 2009 that really made a difference in my life.

LaunchBar

When I first switched to the Mac, I discovered Quicksilver and it was like discovering something essential that you didn’t know you needed. QS was a revelation to me because it drastically reduced the mental distance between the what I wanted to accomplish and executing it.

Over time though, I found some things in QS that just didn’t work consistently. It would crash and some of configuration was pretty clumsy. It became pretty clear that there was little, if any, forward progress being made on it. So, on the advice of several local Ruby/Mac nerds, I tried out LaunchBar. At first I was disappointed that it didn’t have the breadth of QS, but after investing a little time and effort I found that it handled 99% of the things I wanted. More importantly, there was somebody actually working on it which meant it was going to evolve and improve.

Now I can hardly use a machine that doesn’t have it installed. I can’t believe people use the dock to launch apps. Yuck.

Mailplane

By and large, I’m biased to using the built-in Apple-given tools where possible. Apple usually gets it right and most other tools are designed to work with these apps. I’ve used Mail.app since I switched to the Mac, but always felt the interface to be inferior to GMail’s tag-oriented structure. But since I had some non-GMail accounts, and I wanted to have a single app, I stuck with Mail.app.

However, once I dropped my last IMAP-only account I was ready to switch back. The only parts I really missed were the tight integration with the desktop that Mail.app brought. Lo and behold, along comes Mailplane to fill the gap. It is, essentially, a WebKit view of GMail with some extra bits to glue the web application to your desktop. I think it’s brilliant and was happy to part with some hard-earned money for the privilege to use it.

zsh completion

My introduction to zsh came many years ago from a co-worker who boot-strapped my entrée into zsh-land with his configuration files. For the longest time I treated them like mystic, sacred tablets to be worshipped, but never to be understood. But over time I found little gaps I wanted to fill in with my zsh setup, especially with command auto-completion.

I’m a keyboard kind of guy. I like the command prompt. I also like going fast, so anything that makes me faster in the command prompt is like gold to me. I love shell auto-completion and found lots of things I wanted completion for, like RubyGems. So this year I finally pounded through enough documentation and samples to put together a few home-grown completion bits. I still don’t understand most of the incantations that make it go (guilty as charged of cargo-culting) but it has made my command-line work-flow that much better.

Dropbox

Since switching to the Mac, I’ve always had at least two machines that I needed to share files between. For the longest time I used to store files in S3 then sync them back and forth. This worked, but it sucked because I had to do it manually and I had to get the order right so I didn’t clobber any files.

When Dropbox came along, the clouds parted and the golden light of heaven shown down from above. Dropbox makes sharing files super-duper, idiotically simple. Combined with tools like 1Password, having consistent data across multiple machines is like magic on a daily basis—it just works and I don’t even have to think about it.

One Bus Away

The thing I love about the iPhone is how it’s an Swiss Army Knife for information in the modern age. You can find apps that do very specific things, very well and put them in a single box that you keep in your pocket. The One Bus Away app is one of my favorite iPhone tools.

I ride the bus a lot and to have real-time transit data in the palm of my hand is fantastic. No guessing about when the next bus is coming. No extra waiting. I know just when to leave to catch my next ride.

Mint.com

I was a long-time Quicken user but finally had it last January. It’s a bloated app with serious usability issues. I finally reached a point where using Quicken had a net-negative impact on my life. It simply drove me crazy to use it.

Enter mint.com. At first I was very hesitant to give my information to these guys. But eventually I was convinced to try it because:

  • if I use Quicken another minute I’ll go postal
  • sometimes the future doesn’t start until you acknowledge it, and this looks like the future to me
  • I’m probably already more open to financial security risk anyway, so what the hell?

I get exactly what I want out of mint: a high-level dashboard that just updates itself. I use a few of the budgeting features which are nice, but really it’s all about automated data acquisition and display. Oh yeah, did I mention that they have an iPhone app too?

Instapaper

Several years ago I built my own news-feed reader and one of the features I really wanted to implement was a temporary “holding pen” where I could put URLs to visit later. These were things that didn’t quite warrant a Delicious bookmark, but I wanted to get back to.

By itself, Instapaper satisfied my original need and worked great as a bookmarklet in my browser. However it went from a convenient curiosity to an essential tool once other apps started integrating with it (e.g. Net News Wire, Tweetie 2) and Kindle integration (see below).

Oh yeah, did I mention that there’s an iPhone app for that too?

Kindle (device and app)

The final tool of 2009 that made itself indispensable was the Kindle. It’s a great example of “good enough”. The Kindle is fraught with polish and usability issues, but they don’t overwhelm the utility of the device.

I’ve been on a long dispense-with-all-physical-media kick, with books being my primary target. I have lots of books, but I don’t have lots of space. Since I’m not emotionally wedded to the form-factor of paper books, the Kindle solves my reading-appetite vs. space problem quite well. I can stuff that thing full of books and not take up an inch of extra space in my house.

Like so many of the other tools I’ve listed, it’s the other things that integrate with the Kindle that multiply its utility. First, the Kindle has gained a lot of adoption by other publishers. The Prags and O’Reilly, in particular, have been eager to jump into the e-book biz with first-class Kindle support. I probably go through about fifteen to twenty tech books a year and having them on the Kindle is great.

Another great bit of integration is how Instapaper delivers me a weekly digest of links I’ve captured right to my Kindle. I can read the full content of every page I bookmarked right there on my Kindle without the need for a network connection. This is a great for travel.

So?

Looking over this list, if there’s one theme that emerges, it’s all about ubiquity and convergence. (Did I really just say that?) Despite all of the queasy feelings those “market-tecture” terms give me, I don’t quite know how else to define it. For me, 2009 was the year that I could get to my stuff whenever I liked, however I liked, through a multitude of channels.

I wonder what the theme of 2010 will be?

All-Time Lineup

December 14th, 2009

A little while ago, I was encouraged to put together my “All-Time” baseball lineup. Now, personally I think the game is more difficult to compete in now than ever before. While the old-timers love to gripe about players in the Steroid Era, I don’t think those guys had to play with such a uniformly strong level of competition under such high pressure. But that’s just my gut feeling. I don’t really have the evidence to back that up. I also think that baseball fans have a tendency to romanticize the players of baseball’s so-called “Golden Era”, making any rational debate even tougher.

With the exception of Gehrig, I’ve purposely ignored anyone before the 50’s. In my opinion, the game is just too different. I don’t feel like I can trot Cy Young out as my starting pitcher just because of 511 wins. Those wins don’t compare at all to wins in the 60’s, 70’s, 80’s or 90’s.

I’m also not penalizing anyone for being part of the Steroid Era or for even having used PEDs. There are, no doubt, some effects of these substances on the game, but I don’t see the evidence being as conclusive as some would have you believe. Did Barry Bonds cheat? Yeah, I’m pretty sure he did. He was a helluva ball-player before he started and he still would have put together a Hall of Fame career without them. Steroids (a rather inaccurate term for PEDs) don’t make you see the ball any better or improve your hand/eye coordination. At best they allow athletes to recover faster from working out. They don’t build muscle, they amplify the body’s own healing process in order to work out more. You can call steroid users cheaters, but I wouldn’t call them lazy.

So this is my list. If you have a different one, I’d love to hear about it. So, without further ado, here’s my list.

Catcher: Roy Campanella

Great all-around athlete, hit the crap out of the ball, threw runners out and worked well with pitchers. He was probably one of the most complete catchers to play in the majors.

First Base: Lou Gehrig

OK, I cheated a little bit here and dipped back in time further than I said I would go. But c’mon—it’s Lou Gehrig.

Second Base: Jackie Robinson

They retired the number 42 for lots of reasons—those are the same reasons he’s my starting second baseman.

Third Base: George Brett

Brett is the last guy to come close to hitting .400. He ended the 1980 season with a .390 average. What’s even more impressive is that he had more home runs than strikeouts that year. He’s got the longevity, the ring and the career to put him on my list.

Shortstop: Alex Rodriguez

Does A-Rod’s admission to using PEDs damage is Hall of Fame credentials? Maybe, but as I contended earlier, I’m not convinced that they can carry a player to greatness. We love to dump on A-Rod’s failures, but it’s really only because he’s been spectacularly successful in his career. Drugs or not, he’s my starting shortstop. This, coming from a jilted M’s fan too!

Left Field: Ted Williams

The Splendid Splinter. The greatest hitter of all time. Period.

Center Field: Willie Mays

Hard to find a better combination of offensive and defensive skills.

Right Field: Hank Aaron

How could I possibly leave Hank Aaron off the list?

Designated Hitter: Edgar Martinez

Edgar Martinez presents a serious conundrum to Hall of Fame voters. He’s really the first “pure” designated hitter that voters will have to face. His career are numbers are impressive for the time he played, but he doesn’t have some of the magic totals people like to see. That said, he’s my vote for DH. Plus, I named my dog after him.

Starting Pitcher: Sandy Koufax

There’s probably no roster spot that would engender more differences of opinion than starting pitcher. There are so many great ones to choose from. Koufax didn’t have the career longevity like Satchel Paige or Tom Seaver, but at the height of his powers he was simply jaw-dropping amazing. His years from 1963 through 1966 are some of the sickest consecutive years a pitcher ever put together.

Relief Pitcher: Mariano Rivera

While there may be controversy over starters, the choice for reliever is pretty straight-forward. Seriously, is there any disagreement here?

Manager: Earl Weaver

He managed Hall of Fame players, he won a couple of rings, he wrote the seminal book on baseball strategy and he had a video game named after him. Yup, that fits my criteria.

Building a Knowledge Base

December 11th, 2009

Many years ago, I had the fortune of working for a family friend who was a financial planner. Not only did I get to learn a lot about personal finances at an early age, but I also picked up some great professional habits too. One of the things she did was maintain a gigantic set of folders of things she found interesting or useful. She had a four-drawer filing cabinet filled with various tidbits of information she had collected. She had a pretty good index in her head of where these things were and was amazingly proficient in recalling where she had filed things.

I always wanted a personal knowledge base like this, but I couldn’t do it the way she had. First, I have never had the space to collect that much paper. I cannot have, and do not want, a giant filing cabinet of folders. Second, I don’t have the kind of recall she did to find that stuff. I could certainly remember that I once filed something, but wouldn’t have a clue where I filed it. Which brings me to the third issue, which is suffering with the restriction of filing information under a single hierarchy.

When I first started using GMail I had a major epiphany about the differences between organizing information in folders versus tagging. These days that seems about as earth-shattering as realizing our galaxy is helio-centric, but it seemed like a pretty radical idea at the time. I flat-out love this style of organization. I may not remember where I filed something, but I’m pretty consistent when it comes to labeling things. With systems like GMail and Delicious, I just slap as many tags as I think are reasonable for a message or bookmark and I have a really good chance of finding it again when I need to.

But email and bookmarks aren’t a knowledge base. For me, they are a reference, but usually aren’t in a succinct enough format to be a good reference. I want to boil down newly-acquired knowledge into some quick, efficient prose. What I needed was a system that:

  • Works across multiple machines (e.g. work and personal)
  • Is fast to add and edit content
  • Is (relatively) searchable
  • Has some structure
  • …but not so much that I fight with it

So over the last few years I’ve started building a personal knowledge-base in earnest. It’s not overly complicated or too involved. I simply keep a set of text files (specifically, files compatible with org-mode) in a special Dropbox folder. Dropbox makes synchronizing stupid-easy. I just treat these files just like local files and they appear on both my work and personal machines.

For a while I used VoodooPad, which is a very cool program. But I like having a little structure in my notes and imparting that structure in VoodooPad took more effort than I wanted. Later, I discovered Emacs’ org-mode, which turned out to be a perfect fit for me—it’s a relatively lightweight structure on top of simple text-files. The only thing org-mode doesn’t do well is handling non-text media. I’ve considered moving to something like OmniOutliner, but I’ve found that org-mode works surprisingly well.

The technology isn’t particularly interesting, nor is it what makes this work for me. Rather, it’s the discipline of writing down little notes on various topics of interest. For example, I can never remember how to enable zombies for Cocoa debugging. I looked it up once, then added a section to my xcode.org file on NSZombieEnabled. I get two benefits out of this: first I’ve got it somewhere handy that I can easily look up again (via spotlight, grep/ack, whatever). Secondly, the very act of formulating a paragraph or two on the concept somehow reinforces it into my brain. In fact, it’s very likely that I won’t ever have to look up how to track zombies again.

Cleaning out the Closet

November 7th, 2009

I’ve had a couple of nascent Ruby gems lurking in my Github account for what seems like ages. So, on a rainy Saturday afternoon, I did a little cleanup and pushed a couple of new gems out to Gemcutter.

The first, is a gem I started over a year ago, called word-salad. It uses the built-in dictionary file to randomly pull words out. This is great when you just need to generate a bunch of English-like text, but don’t want to fall back on the boring old “lorem ipsum…” routine.

1
2
3
3.words ==> ['draw', 'ameliorate', 'bonanza']
2.sentences ==> ['Shoot jonesing the make castle.', 'Blue murdered slight bastion.']
2.paragraphs ==> ["Brachypterous gastropod pheretrer overeager toploftily denaturalization stokesite demented benzalhydrazine archaeologic. Haverer hypophonous lenticularly brickliner urocele paucipinnate pik unprintably perhalogen. Subglenoid bearish gesticulative staircase gallop vesuvianite pneumatically overyear conterminous dreamish. Nonalliterated galliwasp superconfirmation Comandra entoil millionth parcellize rarefaction Cynoidea. Podolian metamorphosable nativeness integriously protonematoid undoctor stochastically dissatisfactory unchastity.", "Increate unloquacious unsatisfiedly flareboard internuncio beguine equivocation snowshoe Rhynchonellacea. Parochially curliewurly vermix consistorial cond consciencelessness Anaxagorize recoct sempiternally Campanulatae. Scorpionida Castalides homoanisic semipenniform Novemberish assessor preterlethal acrotarsial knoller hartin. Procrastination boatwise canonize differentiate faunlike countermarriage obstinance dilatableness drumloid. Gerate squirr Silvanus Physostigma booting thyroarytenoid diminutival legpuller medisance radiobserver."]

The second is a gem for automatically retrieving and locally storing sales reports from the iTunes Connect site. If you have an iPhone app in the App Store, you already know how much (anti-)fun it is to get reports from Apple’s site. So I put the itunes-connect gem together to help out. It’s pretty basic for now, but will probably grow more capabilities as time goes on.

Posted in Ruby | No Comments »

The Cleverest Git Maneuver I Ever Pulled Off

October 9th, 2009

So there I was, reviewing a series of commits, sucking air between my teeth and cringing when I came upon one of those lazy commits that has way too much stuff in it to reasonably digest. I needed a way to go back and split that commit into two or three separate commits. This is pretty easy to do with git rebase. You can just do a mixed reset of the last commit, stage the bits you want in one commit, stage the next bits and put that in a separate commit.

This all works great—until it doesn’t. The ability to stage parts of a file is one of my favorite features of git, but there are times when you have changes that git won’t let you split apart. Usually I give up at this point and just abort the rebase.

But yesterday I must have had too much coffee because I was determined to figure out how to do this. The changes that I wanted to split out were pretty easy to find. It was easy to remove them by hand and commit those. But I didn’t want to have to manually add them back—that was too mistake-prone. What I needed was a way to invert the commit that removed those lines. What I needed was git revert. If I could revert my subtractions (in effect, adding the changes back), then I could squash the commits and rewrite history.

So here’s what I did:

  1. Started an interactive rebase session (git rebase -i)
  2. Marked the commit I wanted to split as an “edit”
  3. Manually removed the code I didn’t want in the first commit, staged the changes and made a new commit
  4. Revert the subtraction with git revert HEAD
  5. Complete that rebase with git rebase --continue
  6. Start a new rebase and squash the original commit with the manual changes one

Note that I didn’t use git reset after step 2. It wouldn’t have helped me because interactive staging wasn’t working for me. I also marked all the commits in the second rebase as “edits”, so I could fix the commit messages.

Put another way, the commits transformed like this, from left to right:

git revert.png

Maybe I’m overly fussy about clean commits. I’ll admit that at times that my attention to cleanliness borders on the obsessive, but having the ability to go back and clean things up is one of my favorite things about git. Maybe I’m just not smart enough, but I usually don’t know nearly as much at the beginning of a commit as I do at the end. With git, I can make it look like I do.

Posted in Git | 3 Comments »

clip version 1.0.2 has been released!

October 3rd, 2009

You like command-line parsing, but you hate all of the bloat. Why
should you have to create a Hash, then create a parser, fill the Hash
out then throw the parser away (unless you want to print out a usage
message) and deal with a Hash? Why, for Pete’s sake, should the parser
and the parsed values be handled by two different objects?

Changes:

### 1.0.2 / 2009-10-02

* Merged patches from Adam Salter:
* Added new “presence” method for options.
* Updated rspec usage to match the latest & greatest syntax
* Make descriptions optional for flags and options

*

Posted in Uncategorized | No Comments »

The End of an Era

October 2nd, 2009

Well, this is it kids; the end of my time at Evri. While I have cultivated a long-standing antipathy towards the Grateful Dead, I’ll co-opt one of their song titles and simply mutter, “what a long strange trip it’s been”. I started out at Evri when it was still just a twinkle in somebody’s eye. Since then I’ve seen it grow and mutate in ways I would have never imagined. I got to work on a lot of cool stuff and learn a bunch of new things. The best part, like any good job, was having the opportunity to work with some really great people.

But now it’s time for a change. My professional clock is set to about three years—when that bell rings it’s time for me to move on. This was as true at Evri as it has been anywhere else, with one major difference: I made a career-change along the way.

OK, I haven’t given up software to become a sous-chef or to take troubled kids out into the woods to teach them discipline. But I think I have reached the end of my professional Java programming career. This is kind of a “Big Deal”, because I’ve been doing it for a decade. I know, I know: never say never. It’s entirely possible that I’ll eat my words a year or two down the road, but for now, I can’t help but feel like I’m closing a major chapter in my professional life.

I’ve been with that language for a long time. Lately I’ve made a sport of complaining about it a lot, but honestly that’s simply contempt bred from familiarity. There is a lot of good about the language and, despite my railings, the baby needn’t be thrown out with the bath-water. What it comes down to is that I simply don’t enjoy it anymore. It used to be fun to put those pieces together, but not any longer. So I’m trading in my Java hat for my two new loves: Ruby and Objective-C.

IMG_1047.JPG

I may be stupid, but I’m not foolish enough to think that these languages will be the only remaining languages of my career. First of all, I’m not in the habit of defining my identity from the particular technologies I work with. Secondly, these are simply the environments I’m in love with now. I’m a dedicated family-man when it comes to people, but when it comes to programming languages, tools and environments I’m as bad as Liz Taylor. But jeez, why not embrace change? I don’t do this for the paycheck. I do it because I love it. Why spend my time on things that aren’t making me happy anymore?

With that question burning a hole in my brain, it became clear that, for now, the twisting road that is my professional career is going to take a long detour through Ruby and Objective-C. I hope it gets some time with Erlang too—I’ve only dabbled with it a little bit, but found myself quite attracted right away.

As I realized that my time was at an end at Evri, the question of “what next?” loomed large. Was there someone out there that wanted someone with the skills I wanted to cultivate? If so, were they doing something cool? Was I going to go “indie”? What would that look like? Questions, questions, questions. Fortunately I stumbled across a gig that is going to let me scratch most, if not all, of those itches.

I’m taking October off to continue and complete the series of iPhone screencasts I’ve been writing for PeepCode. In November I’ll pick up my full-time gig and kick off the next phase of my professional life. You can’t imagine how humbled and fortunate I feel to be able to do this.

Posted in Work | 2 Comments »

iPhone Screencasts

September 14th, 2009


I’m pleased to announce the release of the first in a series of PeepCode screencasts for the iPhone SDK I’ve been co-writing with Geoffrey Grosenbach. The first one (done in two parts) covers View Controller basics. We decided to start with View Controllers because they are at the core of all “productivity”-style applications. Once you have them down, you can start to put some meat on the bones of your iPhone apps.

Once we’ve covered those, we’ll work our way through the entire MVC Holy Trinity, one bit at a time. Along the way we hope to deep-dive on a few ancillary topics like Core Location, Game Kit as well as provisioning and unit-testing. We also hope to look at visual technologies like Core Graphics and Core Animation, as well model-related APIs like Core Data and web service-related libraries.

The iPhone SDK is huge and there’s a ton of material out there to cover. We’re very excited to kick off what we hope will be a useful and successful instructional series for perspective iPhone developers out there. Let us know what you want to see.