Rock the iPhone with ASP.NET MVC

With much fanfare Apple announced the availability of the iPhone SDK. I downloaded it and someday plan to play around with it, though with the SDK already having gone through 4 or 5 beta releases (each a ~2GB download) I’ll probably wait a long time before cracking it open. However, for web applications the best way to integrate with an iPhone is still through the browser.

Unfortunately Apple didn’t provide much help in the form of html or css to make your website “iPhone-y”. They provide documentation on elements like iPhone specific events (”onorientationchange”) and details about how Safari works on the iPhone in terms of zooming, etc., but nothing that offers guidance on how to make an application look like it belongs on the iPhone.

Enter Joe Hewitt and iUI. iUI takes HTML that follows a simple set of conventions and does all the heavy lifting to enable you to easily build a version of your site that is tailored for the iPhone experience. I first started using iUI before ASP.NET MVC was publicly introduced, and I specifically remember thinking how much iUI was built for “webforms unplugged“. Let’s take a quick look at an example of how iUI works, and how to use it with ASP.NET MVC.

If you’re the type that likes to get their hands dirty first, download the code here.

CSS Zen Garden

iUI is literally nothing more than some javascript, some css, and a bunch of image assets. It’s how things are supposed to work with HTML and it’s beautiful, like the CSS Zen Garden. It also has some simple conventions that I’ll summarize like so: “write HTML the way it was intended”. <ul> or <ol> for lists, and <div> or <form> for dialogs and pages. Easy enough, right? There’s not a ton to iUI but for this post I’ll start simple. Let’s create a list of products that we want to display like so:

This is the HTML behind the list itself (not including the top toolbar, though the “title” attribute of the list controls the text shown in the center of the toolbar):

<ul id="products" title="Products">
    <li><a href="/products/index/1">Alice Mutton</a></li>
    <li><a href="/products/index/2">Aniseed Syrup</a></li>
    <li><a href="/products/index/3">Boston Crab Meat</a></li>
    <li><a href="/products/index/4">Camembert Pierrot</a></li>
    <li><a href="/products/index/5">Carnarvon Tigers</a></li>
    <li><a href="/products/index/6">Chai</a></li>
    <li><a href="/products/index/7">Chang</a></li>
    <li><a href="/products/index/8">Chartreuse verte</a></li>
</ul>

iUI does the heavy lifting to format the list in the iPhone style, and will dynamically load any linked content using an AJAX call and render it in-place, replacing the current list (“products”). iUI handles sliding in the new content from the right-hand side, just like a native iPhone application.

You could also reference another list defined within the same page, for example if you had a very short list of items and had each list item’s “linked content” also included in the page, like this:

<ul id="products" title="Products">
    <li><a href="#subproduct1">Product 1</a></li>
</ul>

<ul id="subproduct1" title="Related Products">
   <li>Sub Item 1</li>
   <li>Sub Item 2</li>
</ul>

The Root Page

iUI will dynamically render partial content into the current view, but it needs an initial root page describing the main layout. The easiest way to figure out what is needed is to look at one of the examples that iUI includes, but in a nutshell you’ll probably need at least two elements: the toolbar (the heading) and some content. To support the example above of a product list, our entire root page could look like this:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <title>Northwind Explorer</title>
    <meta name="viewport" content="width=320; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"/>
    <style type="text/css" media="screen">@import "../../Content/iui/iui.css";</style>
    <script type="application/x-javascript" src="../../Content/iui/iui.js"></script>
</head>
<body>
    <div class="toolbar">
        <h1 id="pageTitle"></h1>
        <a id="backButton" class="button" href="#"></a>
    </div>
    <ul id="products" title="Products" selected="true">
        <li><a href="/products/index/1">Alice Mutton</a></li>
        <li><a href="/products/index/2">Aniseed Syrup</a></li>
        <li><a href="/products/index/3">Boston Crab Meat</a></li>
        <li><a href="/products/index/4">Camembert Pierrot</a></li>
        <li><a href="/products/index/5">Carnarvon Tigers</a></li>
        <li><a href="/products/index/6">Chai</a></li>
        <li><a href="/products/index/7">Chang</a></li>
        <li><a href="/products/index/8">Chartreuse verte</a></li>
    </ul>
</body>
</html>

The site will initially show the list of products, and when the user clicks on a product, the <ul id=”products” title=”Products” selected=”true”>…</ul> element will be wholesale replaced with the content loaded by an AJAX call to “/products/index/[number]”.

Hooking up iUI to MVC

First things first – download the latest iUI assets from the google code repository trunk. You’ll get the latest bug fixes and features, which I’ve found to be helpful. As a side note, you can view some samples directly from the repository itself – like the music example. Put the downloaded files in the Content directory:

Define your main page—the main entry point to the site. I chose /home/index in my example. This is where you’ll reference the iUI javascript and css assets, and define the initial structure of your page.

One big catch that I already mentioned with iUI is that it expects links (whether AJAX-loaded or in-page references) to return HTML fragments. It literally takes the results of an AJAX call to a given URL and sets the innerHTML of the content to replace.

This means that every other page in our application should return partial content. For example, when I click on “Products” this is the only content of the view page that lists the products:

As you can see, it’s simply building the list itself and rendering the partial HTML content as a response.

You can connect with an iPhone on your local network with a wifi connection, but it’s much easier to install and test with Safari for Windows. Both Safari for Windows and the iPhone’s mobile Safari use the WebKit engine so the rendering experience is about as close as you can get. Shrink the browser to approximately the size of the iPhone screen and you’d never know you didn’t spend the $400+ on an iPhone. ;)

You can download the first version of my example project here.

Up Next

In future posts I’ll explore some more of iUI’s features such as adding a product page to view details of a product in a friendly way (I’ve included this in the example project already), rendering partial lists (allowing the user to expand the list incrementally), detecting the user agent and loading iPhone views vs. “normal” views, and more. I’ll update the example project as we go!

kick it on DotNetKicks.com

This entry was posted on Sunday, June 8th, 2008 at 7:30 pm and is filed under asp.net, asp.net mvc, iphone. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

13 Responses to “Rock the iPhone with ASP.NET MVC”

  1. Dew Drop – June 9, 2008 | Alvin Ashcraft's Morning Dew Says:

    [...] Rock the iPhone with ASP.NET MVC (Aaron Lerch) [...]

  2. Daily Find #77 | TechToolBlog Says:

    [...] Rock the iPhone with ASP.NET MVC [...]

  3. Wöchentliche Rundablage: Silverlight 2, WPF, ASP.NET MVC, jQuery… | Code-Inside Blog Says:

    [...] Rock the iPhone with ASP.NET MVC [...]

  4. Weekly Links: Silverlight 2, WPF, ASP.NET MVC, jQuery… | Code-Inside Blog International Says:

    [...] Rock the iPhone with ASP.NET MVC [...]

  5. Chad Campbell Says:

    I know this guy!

  6. Weekly Web Nuggets #16 : Code Monkey Labs Says:

    [...] Rock the iPhone with ASP.NET MVC: Is there anything cooler right now than the iPhone? Yes…your ASP.NET application running on the iPhone! Aaron Lerch writes about how to combine ASP.NET MVC with iUI, a toolkit that takes care of the heavy lifting of the iPhone markup. [...]

  7. HOW TO debug Javascript in Safari 3.1 on Windows » 70 Tricks Says:

    [...] Safari for Windows and the iPhone’s mobile Safari use the WebKit engine, this browser debugging technique could be of use to developers testing ASP.NET applications for [...]

  8. Vijay Dubey Says:

    Hi Aaron,

    I downloaded your code. I created a virtual directory named iuisample. but when i am running the sample application i am getting error. I checked out the code of /views/home/index.aspx. The second line of code is

    In the zip file index.aspx.cs file is missing. I am getting the following error:

    Server Error in ‘/iuisample’ Application.
    The resource cannot be found.
    Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.

    Requested URL: /iuisample/views/home/index.aspx

    Version Information: Microsoft .NET Framework Version:2.0.50727.3053; ASP.NET Version:2.0.50727.3053

    Can you tell me somthing about this error. Is that error related to index.aspx.cs file or it is refering somthing else.

    I am very new to MVC and iphone, i just started exploring MVC with your project reference. Please help me if you can.

    Thanks in advance.
    Vijay

  9. Clint Mers Says:

    Excellent article, extremely helpful. Thanks for taking the time.

  10. Ian Harkin Says:

    Anyone following up on Vijay’s question, you shouldnt need an index.aspx.cs file but you will need to add a Default.aspx.cs file containing the standard lines:

    using System.Web;
    using System.Web.Mvc;
    using System.Web.UI;

    namespace BankTransferWeb
    {
    public partial class _Default : Page
    {
    public void Page_Load(object sender, System.EventArgs e)
    {
    HttpContext.Current.RewritePath(Request.ApplicationPath, false);
    IHttpHandler httpHandler = new MvcHttpHandler();
    httpHandler.ProcessRequest(HttpContext.Current);
    }
    }
    }

  11. Ian Harkin Says:

    Ooops without the namespace
    and add the following as the very first line of Default.aspx:

  12. Ian Harkin Says:


  13. Ian Harkin Says:

    oops the site is cleaning out aspx directives form comments :-)
    as the first line include
    a Page Language direct and set CodeBehind=”Default.aspx.cs”
    and something like Inherits=”._Default”

Leave a Reply