This past weekend I rolled out an iPhone optimised version of Muffin. Muffin on the iPhone was useable before but it was always a bit fiddley and it didn't fit on the screen very gracefully. My main goal was to simplify and trim down the UI for iPhone users. I thought that it would be better if I designed a better way to do 80% of what Muffin does rather than try to squeeze an entire desktop UI into a 320px by 480px screen. But of course it isn't really 320px by 480px is it! In the iPhone's Safari you've got the status bar at the top (time, wireless strength, battery icon etc) which is 20px high and the button bar at the bottom (Back, Forward etc) which is 44px high. So that leaves the true visible area at 320px by 356px. Of course I had photoshoped a few mockups at 320px by 480px before I remembered that! These measurements came from Apple's "Safari Web Content Guide for iPhone OS" which has a ton of useful pointers and information about creating content for the iPhone.
(Link. Apple Developer Connection membership is required, but the Online membership is free.)
I started by looking at Muffin and deciding what bits were not essential to an iPhone user and what bits could be abridged in order to reduce "clutter" and increase the amount of free space I could control. I decided that for any non-essential features or functions I would allow the user to use the desktop UI. I didn't want to shoehorn the whole app into a paired down UI and didn't feel that I needed to try.
How it's done
Rails, as of 2.1 (I think), allows you to specify your own (even arbitrary) MIME types and makes it ridiculously easy to use them!
Go to config/initializers and open mime_types.rb and there just so happens to be one already made for iPhone that you can uncomment! Mime::Type.register_alias "text/html", :iphone will correspond to the iPhone's User Agent string of "iphone". Now apparently (according to that same Apple document listed above) the iPod Touch has a User Agent string of "ipod" but in my own limited tests faking the User Agent of my browser (Cruz) Rails responds to "ipod" just as it does "iphone" but I haven't looked into this thoroughly so use at your own risk!
Now the whole point of registering a new MIME type like this is that when someone with that "iphone" User Agent requests a page we can add to our repsond_to block format.iphone (just like you would format.html or format.xml) and if you have a corresponding view called index.iphone.erb (just like you would have index.html.erb) your app will render something different for an iPhone user as it would just with a regular HTML or XML request.
You can then take that opportunity (as I did) to include a different CSS file in that index.iphone.erb file and have complete freedom designing the iPhone page without in anyway effecting what the app renders to regular HTML requests.
Two possible gotchas.
Gotcha one. Remember you'll need to add the format.iphone to each repsond_to block in each action of each controller in which you want to render something different for the iPhone.
Gotcha two. It will still use that controller's default layout so you'll want to either make a new layout (eg views/layouts/application.iphone.erb) or tell Rails not to issue the layout at all by putting render :layout => false inside of a block inside of the respond_to block.
respond_to do |format|
render :layout => false
(Hat tip to Slash Dot Slash for that.)
To make this work with iPhone users who want to use the original desktop UI (and there's cleaner way of doing this I'm sure, but it hasn't come to mind yet) I enclosed the format.iphone line (in the respond_to block) in a simple if statement and used a session variable to set if this format.iphone is called or skipped. If it's skipped the format.html is called instead.
And that was it really. Rails makes this kind of thing easy - once you know how it's done!
And one quick tip to close on. If you're designing an icon solely for the iPhone, remember that the iPhone has an effective resolution of 160ppi (which has a lot to do with why everything on the iPhone looks to great, even at small scale). Most people (well me at least) tend to design for websites at 72ppi so maybe try it at 160ppi and see if it's worth it for your project.
And another quick tip. If you're on Mac, Cruz is a free browser that allows you to use different User Agents in two clicks which made this whole process a heck of a lot easier for me! Check out Cruz at cruzapp.com.
And just one more tip since I'm in the mood for giving free advice. I was using iPhoney to simulate how my design would render on the iPhone but I'm not convinced it's 100% acurate. So what I did, since I was obviously working on my local machine and your iPhone can't load http://localhost:3000 if the localhost is your Mac not the phone, was I uploaded the CSS to a test domain online. I then took the rendered html from my app (view source, copy and paste) and uploaded a static .html file and loaded that in my real iPhone. Extremely useful when trying to gauge the right space to leave between links so users don't struggle to tap only the link they want, not the three other links next to it!
Was it worth it?
Designing for the iPhone was a lot of fun. The size limitations were extremely liberating for me! Designing a website that you know for sure the browser window size was enough in itself to get me giddy! Plus I love my iPhone but some things are just a thousand times easier to do on your laptop when you get home. I love using Muffin, but sometimes it felt a bit awkward to use on my iPhone. A very happy to say that's all a distant memory now!
Some before and after pictures
I've uploaded some screenshots to flickr - take a looksee here of the UI in normal mode and the UI in iPhone mode.