Monthly Archives: June 2007

Wii Transfer 2.3

I finally released “Wii Transfer 2.3”:http://www.riverfold.com/software/wiitransfer/ late last night. This is the version I demoed in “my interview with The Unofficial Apple Weblog”:http://www.tuaw.com/2007/06/18/video-wii-transfer/. The most notable changes are AAC support, an improved music player interface, and better use of the Wii remote buttons.

This release sports a new icon, designed by Jordan Langille of “OneToad.com”:http://www.onetoad.com/. As much as I enjoy tinkering with Photoshop and Illustrator, I knew I didn’t have time to do a quality icon. I wanted something fun that still captured a part of the original icon, and this concept has really grown on me since it was finished almost 2 months ago.

I also took this opportunity to refresh the “Riverfold web site”:http://www.riverfold.com/software/wiitransfer/ design a little. Just don’t tell anyone that it still uses HTML tables.

WWDC 2007 in one post

Moof Along with most of our house, my office is packed up and ready to move this week. The photo to the right is of one of the handful of items in a box labeled “Manton’s desk,” or, if someone else had her way, “Random junk Manton saves to remember the past but which should really be in the trash can.”

It’s unopened Moof beer from WWDC 1996, my first WWDC. At 20 I was too young to drink, but I probably would have saved it anyway. That was back when Apple gave you cool stuff and not just another cheap laptop bag.

This year’s WWDC will probably go down as one of my favorites. The keynote was a bit dull, but it was offset by the reality that Leopard is a mature and usable system. I have been running all my primary apps off of it since last week, including Mail.app, NetNewsWire 3.0, and Xcode.

I couldn’t place the feeling at the time, but now I realize that last week’s sessions were, in a way, relaxing. There was no sense of urgency. Most of the sessions I attended were practical, full of hands-on advice for preparing for Leopard and many applicable to Tiger development as well. I got a lot out of the week, and when I decided to skip out on Friday it didn’t feel like the world would come crashing down because of it.

James Morrison Other highlights of WWDC 2007 were away from the sessions: walking Chinatown with Willie on Sunday in search of the illusive bakery item; hitting the SF Mac Indie party that night and hanging out with fellow developers afterwards; Buzz Andersen’s party Monday, catching up with Lane and the host; the Dan Benjamin annual breakfast; Apple Design Awards on Tuesday, which had a record number of wins for apps I’ve actually used; accidentally walking into a James Morrison concert at the Apple Store (left photo); being interviewed by Scott McNulty of TUAW, though I secretly hope they will decide not to air it; enjoying great Italian with the VitalSource team on Wednesday before catching the tail end of CocoaHeads; plus the Apple Bash and more drinks and discussion Thursday night.

Like at SXSW earlier this year, Twitter proves both cool and useful. I was lucky enough to meet many of the people on my Twitter friends list for the first time last week.

Of course it wasn’t all fun and games. I sifted through more legitimate Bookshelf bug reports than usual; I was exhausted pretty much every day; and there were a couple developers I had hoped to seek out that I just never made the time to.

All in all, though, a good week and now I’m ready to get back to coding.

New software releases (plus screencast)

Today is a good day to release software. “MarsEdit gets a nice update”:http://www.red-sweater.com/blog/346/marsedit-12-growl-picasa-and-vox and “NetNewsWire 3.0”:http://ranchero.com/?comments=1&postid=1646 ships. At VitalSource we also just released “Bookshelf 4.6”:http://www.vitalsource.com/index/bookshelf today, which lays the foundation for media-rich textbooks and adds a highlighter rating UI for any subscribed highlighters you have. This data will bubble up in a few places in the future to allow you to discover people and books, although for now it’s one-way.

Here’s a “short screencast of the rating interface”:http://www.manton.org/screencasts/2007/bookshelf_rating.mov (12 seconds, 700k). The star widget is a simple Cocoa control that hits a web service in the background. It was fun to write and surprisingly not very much code.

The /Applications social network

Brent Simmons, from a “TUAW interview”:http://www.tuaw.com/2007/06/05/5-questions-with-brent-simmons-creator-of-netnewswire/:

“One of the things I love about being a Mac developer is getting to meet the folks who make the apps I use. In a way, my /Applications folder is also my social network. Which is cool.”

I never thought about it that way, but it’s definitely a great aspect of the Mac developer community. I hope to add a few more people to my /Applications social network next week at WWDC.

I’ve been to a bunch of WWDCs now, but I’m particularly excited this year because it will be the first time I’ve attended as representing both a “large-ish company”:http://www.vitalsource.com/ and an “independent one-man shop”:http://www.riverfold.com/.

I will be carrying VitalSource business cards in my wallet, but I also hope to have a printed batch of Wii Transfer serial numbers to hand out. I know a lot of Mac developers have a Nintendo Wii and it’s a shame I haven’t given out more copies. If you have a Wii and see me (I look “something like this”:http://www.manton.org/me/), please get my attention so that I can correct this oversight.

Learning from Rails design

Since version 2.0, “Wii Transfer”:http://www.riverfold.com/software/wiitransfer/ has had a built-in web server for serving music and photos to the Nintendo Wii. The server was written in Cocoa and the code became very unwieldy as I continued to add features. Dozens of methods for processing different parts of the URL, and many if statements for conditionally branching based on the URL, splitting the URL parameters, and more.

The code looked something like this (only worse):



if (path startsWithSubstring:@"/albums") {

[self processAlbumsRequest:path];

}

else if (path startsWithSubstring:@"/artists") {

[self processArtistsRequest:path];

}

else {

// ...

}

(void) processAlbumsRequest:(NSString *)inPath

{

// split out the parameters and request extensions from the URL path

// ...

if ([e isEqualToString:"xml"]) {

// ...

}

else if ([e isEqualToString:"html"]) {

// ...

}

}

Multiply that times 10 for all the different URLs that Wii Transfer knows how to process, and you can see how it worked fine for a couple simple things, but quickly became a mess as I added features.

For the upcoming version 2.3, I redesigned most of the URLs to follow a common structure, patterned after the default URL syntax that Rails uses: /controller/action/id. Now, instead of if statements, I dynamically route the URL requests using NSSelectorFromString() and performSelector:withObject:.

Consider this code (as above, simplified from the real thing):



// extract the values from /controller/action/id URLs

NSArray* pieces = [[path stringByDeletingPathExtension] pathComponents];

NSString* controller = [pieces objectAtIndex:1];

NSString* action = [pieces objectAtIndex:2];

NSString* param_id = [pieces objectAtIndex:3];

// call a method named controller_action, passing it the id

NSString* sel_name = [NSString stringWithFormat:@"%@_%@:", controller, action];

SEL method = NSSelectorFromString (sel_name);

[self performSelector:method withObject:param_id];

Now if I need to invent a new URL, say “/tracks/play/1234.mp3”, all I have to do is write the implementation for that method:



- (void) tracks_play:(NSString *)inParamID

{

// ...

}

The web request calls through to this new method without any additional glue code, in this case passing “1234” in the single parameter.

(The underscored method signatures aren’t very Cocoa-ish, but this is actually a plus because I can quickly spot the chunk of the controller that processes a set of requests, and I like that they read just like the URLs. I’m also currently using a single controller instead of having separate controller objects for the different types of requests, but I may expand that later.)

This convention has also allowed me to simplify all the URLs that Wii Transfer uses. Other examples include “/covers/search/U2” or “/artists/show/5”. I’ve eliminated a bunch of code, and it fits nicely with how I serve application resources and the start of a HTML template system.

Could it be taken further? Sure. I remember in the Mac OS 9 days building a web interface for a product using only compiled AppleScript scripts stored in the resource fork. Lately, folks like “Gus Mueller”:http://gusmueller.com/blog/ and Adobe’s Lightroom team have been doing interesting things with “embedding Lua”:http://www.sqlabs.net/blog/2006/01/adobe-lightroom-and-lua.html. I don’t want that level of extensibility yet, but it seems like a logical next generation when I outgrow even this new web architecture in Wii Transfer.