The iPhone has been all the rage lately, from complaints to praise it has all been heard. Whether you hate it or love it, the fact remains, as a developer you cannot ignore it. And here at DZone we could not ignore the chance to provide even more means by which you can access your development links. In this article I will share with you how we went about recreating DZone for the iPhone.

First things first, get your development environment set-up. I chose to go with an old favorite, Aptana Studio. After you have downloaded Aptana go ahead and install the iPhone development tools which you will find available from the studio's welcome page. After all of the components have been downloaded, select install all and restart your workbench. You are now all set to start building your first iPhone app.

Next, click on File > New Project and then select the iPhone project. Give your project a name and you will next be presented with an option screen to import some JavaScript libraries. For theDZone project we decided to go with iUI but feel free to choose which ever libraries you feel comfortable with. When you click finish you will see that Aptana starts to create your project. Once completed you will be presented with a base HTML page that contains some CSS and JavaScript. This is a good starting point and will give you a feel for the new tools. You will also notice that at the bottom of the screen where you used to have source, Firefox and IE, you now have a new tab entitled iPhone. With the HTML page still open, click on the iPhone tab to see an emulation of how your page will look once viewed on the iPhone.

You will also notice that when you click on any of the black empty areas around the iPhone the phone will rotate and your layout will also dynamically change. This layout change is not automatic but is made possible by a small script that was added to the page automatically byAptana, it looks as follows:

After I completed playing around with the new tools and seeing how the emulator works I decided thefirst thing I want to do is to separate the structure from the style and the presentation, I wouldcertainly suggest you do the same, it just makes for a much more maintainable application in the longrun. My first step was to move the CSS embedded in the page out into it's own file. I created a newfolder called, you guessed it CSS, and created a new CSS file and called it screen.css. I next copied allof the CSS from the HTML page and pasted it into the CSS file. The last step here was to include theCSS file in the HTML page. So you need to add the following tag to the HTML page.

But then, create a new folder called js and a new JavaScript file entitled updateLayout.js. Next go ahead and copy the script and save. Back on the HTML page, you need to add a tag to include this new JavaScript file we just created. Add the following:

<script type="text/javascript" src="js/updateLayout.js"></script>

To make sure that everything still works as before, click on the iPhone tab. Everything should still look and work the same, Now that we have the stage set, let's get started putting this iPhone version of DZone together. There are a few sites that has been the choice of so many is because it makes it much simpler to create webapps for the iPhone that feels a lot more • Create Navigational Menus and iPhone interfaces from standard HTML

Use or knowledge of JavaScript is not required to create basic iPhone pages

Ability to handle phone orientation changes

Provide a more "iPhone-like" experience to Web apps (on or off the iPhone)

To enable us to start using iUI we need to include two files in the head section of our document. So go ahead and add the following:

That is the default styling provided by the iUI library for the the toolbar CSS class. That was not exactly what we were after so we had to over rule that style rule inside our own iphone.css file. With this said, it now becomes important that the order of the included style sheets are correct. As we know the cascade of CSS works from top to bottom, external to inline so, it is important that you include the style sheets as follows:

Now if you click on the iphone tab in Aptana you will find no difference. Why is this? Unfortunately I have no idea other then that the emulator does not do the best job and I needed to find an alternative approach. Being on Windows I did not have the option of installing the iPhone SDK from Apple as this is currently only available on Mac so, short of installing VirtualBox and running the Mac operating system inside it, I had to find another alternative. As Safari is the browser that runs on the iPhone and with Safari now being available on Windows, I switched to using the Safari browser for further testing.

However, I need to see what the layout looked like in the same aspect ratio of the iPhone screen size so I searched for a web based iPhone emulator. I found iPhoneTester.com and for the most part it workedrather well but, I could not really be sure that what this emulator showed me was accurate. Luckily a fellow developer working with me on this project had a Mac and installed the iPhone SDK. The situation was not ideal though as we were working remotely so I had to send him a zip of the work I have done and he had to send me screen shots and feedback on what he was seeing.

With Safari on Windows, at this point I have to rant a little bit and ask Why oh Why Apple, do we not have an iPhone SDK for Windows. With my rant aside, this is the route we followed from here on. I would preview the app in Safari on Windows and send him the code to verify whether what I was seeing was what users would see using an iPhone. But we have another problem, simply viewing the app in Safari is not enough as the viewport size of a browser on the desktop and the viewport on the actual iPhone differs greately.

The kind folks at Manning Publishing has given us a chapter to offer to readers of this article for free. The chapter is from the yet unpublished book iPhone in Action to be published December 2008. Download SDK Programming for Web Developers

To overcome this, I again loaded up iPhoneTester.com and resized my Safari browser to be the same size as the emulator screen real estate.

Ok, so now we have a home grown iPhone SDK on Windows that might not be 100% accurate but gives us a basic idea of what to expect and hopefully less round robin with my fellow developer that has the real SDK installed. With our environment set-up let's add two more elements to our toolbar. Next we add a login link to our toolbar that will launch a dialog where users can log in. So inside your toolbar div add:

<a class="login" href="login.html">Login</a>

After adding the CSS below to you stylesheet refresh Safari to see our new login link added:

Wow! Now here you see some of the magic of iUI, a really nice iPhone style dialog popping up. One thing you might be thinking is, where does the form come from. Well, you need to create and link to it. If you look back at the line we added for the login link you will see it links to a page called login.html. Here it is:

One important point. The login.html page contains exactly what is presented above, nothing more, nothing less. When you click into the username or password fields you will see that the background text stays right there. No worries, we will take of that a little later. For now, let's move on and add another item to the toolbar. As there is various categories/tags that links are posted as we want the user to be able to narrow their view to the only items categories they are interested in. So next we add the category link to the toolbar. To this we add one more line to our toolbar div to end up with:

Of course this is all hard coded and you might want to hook this up to your back-end solution to have the options dynamically generated. Now go ahead and click on the 'Tags' link. As with the login form you see a dialog launch:

By the way, if you are new to this you may wonder, now how do I get rid of the dialog? Easy, clicking on any part of the dark area outside the dialog will take you out of dialog mode. So now that we have out toolbar complete we need to start working on the content area of the app. We basically want to display the list of links in the popular queue you would see when you go to dzone.com with your desktop browser. Because of screen size we have to however limit the amount of links per page and instead of the 'endless scrolling' used on DZone we needed to implement pagination between each set of links.

To start building our content add the following to your index.html file after the closing div of our toolbar:

This is the basic styling that the iUI toolkit applies to unordered lists. As mentioned before this reflects the native look and feel of other apps on the iPhone. The basics of this is fine but we needed to fine tune this a bit for our needs. First stop is to override the style applied by iUI for links inside an list item. Add the following to your iphone.css file:

That changes our link text size to a more manageable size and allows us to add more links per page as we would have been able to with the larger text size. Next we need to add the style rules for our zone-count class:

NOTE: If you are following this article using the iPhone SDK on Mac, you may need to adjust the pixel dimensions slightly as Safari on the desktop does not render the items exactly the same as Safari on the iPhone. This was one of the headaches we had to cope with as I was doing the front end on Windows and did not have access to the SDK.

Next let's fix up the link text so that it lines up better with our zone counter block. Change the style rule for links in list items to the following:

If you refresh your browser now, you will see at the bottom we have another item added to our list with the same style as the other links except without the zone counter. However, we decided that we wanted to style this a little different and make it stand out more. We will also not only need a next page link but also a previous. With that said add the following to the list item we just added:

Now we need to style these two elements and float the one to the left of the screen and the other to the right. For our container pagination list item we need the following style rule to add some breathingspace as well as remove the bottom border that will be added by default due to the list item rule we defined earlier:

With that our landing page is done and we can move on to the story page. One thing to note here is that you will see we made the previous and next images as well as text much larger then the link text. The reason for this is simply to make it easier for users to interact with the interface by giving a larger hit area then would have been available had we made the icons and text as small as the links. Thelinks automatically provide a larger hit area as the entire line in width and height is clickable.

Now lets add a story. Initially we created a story.html page and linked to that page to display the content of a story but, in the end we decided to move back to the one page style that most other iPhonized sites have stuck to. We might change this as the development moves forward or it might not. Anyhow, for the purposes of this article I will stick to the one page concept. Inside your index.html after the closing unordered list tag add the following:

Make sure that the href of your links link to #103776 to ensure your links work as expected. Go ahead I know you want to. Click on one of the links and see what happens. Pretty awesome I think, I nice sliding transition effect thanks to iUI. Before we add our styling for the story page let's look at how exactly this transition works. At line 150 of the iui.js file located in lib > iUI you will see the following line:

addEventListener("click", function(event)

So here is where the event listener is added for click events such as when you clicked on the link. When the click happened this listener was notified and it sprung into action. The first thing we need is the hash of the current node that initiated the click event:

var link = findParent(event.target, "a");

Here we assign the value returned by the function 'findParent' to the variable link. This is how the function looks:

When we enter this function from the click event that resulted from the anchor link, the first check in the while loop will pass but, our current nodeType is 1 and as our localName is "a" so both conditions inside the brackets will fail causing the script to jump out of the while loop and simply return the node and assign this to the var link. Next we jump over the first if statement but move into the second:

The fist thing this script does is set the value of the 'selected' attribute to true. If you are stepping through this script you will see that after this line has executed the background color of the link changes to blue. The next line calls the function that creates the sliding transition effect. We call the showPage function passing in the element we are linking from. We call a little utility function to retrieve this element for us based on the id. So in our case we are doing the following:

iui.showPage($(103776));

The utility function looks like this and is pretty self explanatory:

function $(id) { return document.getElementById(id); }

This will then return our DIV that contains the story we are linking to. Next we pass this showPage function listed below:

When we enter the script here 'backwards' will be undefined and 'page' will contain the content of our DIV. Our first condition passes and we step into the condition block and the next conditional statement. If you look at the top of the uiu.js file you will see that 'currentDialog' is initialized to null and, as we are not triggering a dialog here, this is what it will still be so this condition will fail and we will move to the next condition. This condition will again fail as our current node does not contain a class with the name 'dialog', with that, we step into the else.

As we move into the else block the script's first task is to initialize the variable 'fromPage' with the value of 'currentPage'. Next we overwrite the value of currentPage with the value of our story page. The script next checks whether fromPage is null and if not moves into the setTimeout function calling the slidePages function. Because the call to setTimeout is called with a 0 millisecond wait time the slidePages script will wait to execute until the current call stack has completed it's execution. So from here we return to event listener and the following line is executed:

setTimeout(unselect, 500);

The unselect function looks as follows:

function unselect() { link.removeAttribute("selected"); }

So after a 500 millisecond wait, the unselect function will remove our 'selected' attribute and call the following function to stop the default action the browser would have taken for this event:

event.preventDefault();

Having left the event handler the function that will check whether the orientation and/or location has changed and make the needed changes is called. This utility function looks as follows:

For our current scenario both conditional blocks are skipped and the the checkOrientAndLocation function is exited without executing any of the code. When we exit this code block the current call stack is complete and the slidePages function and execute, this is what that function looks like:

This is then finally the script that is going to cause the nice transition effect of sliding in our new content instead of either loading the new page or, in our case, jumping to the content as would normally be the case with anchor links. After the first line has executed the var axis is equal to null. This means that our first conditional block will be skipped as 'axis' does not equal 'y', instead 'toPage' which is our story DIV, is given a left position that is 100% from the left of our screen. This will place our DIV just of screen to the right of our link list. The content is given the selected attribute and is set to true after which the content is scrolled up to get it into position for the transition.

When the document was loaded initially we called the checkOrientAndLocation function using setTimeout and assigned the id for this timer to the variable checkTimer, we now use this id to clear that timers interval and prevent the timer from triggering the execution of the script. Next we initialize 'percent' to equal 100 and call the slide() function. The slide function does basically two things for us, with each iteration it decreases the value of percent by 20% and increases the style.left set on 'fromPage' by 20%. This means that after five iteration we would have swapped the links with the story content. One thing to not is that after out first iteration we start a timer to execute the slide function with a wait time of 0, remember what this means.

The last time we execute the slide method and percent is equal to 0 we execute this block:

There is some really clever stuff happening here. So, the first thing that iUI does for us after so gracefully sliding the stories content into place is stop the timer that was executing the slide function. Next it re-initializes the checkOrientAndLocation function to execute every 300 milliseconds and saves the id on the checkTimer variable. Finally it starts a new timer calling the updatePage function with a 0 second wait time. So again as before, remember what this means, the current executing stack will complete after which the updatePage function will be executed. When update page is executed this is the code that runs:

Another reason for using iUI is that it assists us in keeping our history intact and allows users to freely use the back button on the phone for navigation purposes if no other means are provided or the user simply prefers this. And it is in updatePage where this happens. The first thing that it does in our case is update the href in the location bar to #_ and the id of our current page, which is currently is 103776. Next is adds this page id to the pageHistory[]. It will then look for a id of pageTitle and set the new document's title to the value of the title of this element or skip this if there is no element with such an id or it is empty. And that is it, the rest is skipped as we are not working with a form or using a link with an id of backButton.

Now that we have our content sliding into view when we click on a link we need to style our content and add some additional fields and a back link to return to our links. First let's style the content already present. Add the following to your CSS style sheet to style the H3 and the paragraph:

No need to anything else, the style has already been added earlier when we added the previous link to our pagination navigation elements. Before I close of this article I want to point you to something. Click on the login link again and then click inside the text field to add your username and/or password. What is wrong here? Yip, the insert point is almost half way down the length of the text area and the 'background' text does not go away when clicking or even typing in this box. Let's solve these issues and while we are at it, let's tighten up the look and feel of both our dialogs.

Add the following styles for the fieldset and the H1 inside out fieldset:

At this point you can go ahead and refresh the browser and test out the login input boxes. Much better right? The background text is still there though, we will take care of that in a second. Let's refine the rest of the dialog elements. For the bottons and the select drop down add the following to your CSS file:

Your dialog should no look a ton better and resemble the following screen: (remember if you are using an actual iPhone or the SDK on Mac, you may need to tweak some of the dimensions to get the same result)

Only one thing left, get rid of that annoying background text inside the username and password fields. For this we add some jQuery goodness. Create a new file inside the js folder and name it iphone.js. Add the following code snippet to this file and hit save:

Now in the head of the index.html page add the following to add the JavaScript file to our page:

<script type="application/x-javascript" src="js/iphone.js"></script>

If you do not have jQuery yet, then go ahead and download jQuery, save the file to the js folder and add the following to the head just before the iphone.js line:

<script type="application/x-javascript" src="js/jquery.js"></script>

Now go ahead and refresh the browser, launch the log in dialog and test out those form elements. What? It still does not go away? Not to worry there are two small things we have to change to our current set-up to get this to work. In the toolbar section of the index.html page change the link to the login form as follows:

<a class="login" href="#loginForm">Login</a>

Copy the code from the login.html file to the index.html just after the closing DIV of the story. Save everything and refresh the browser again. This time when you click inside the username or password fields the background text goes away. And that is it! That is how we got DZone on the iPhone. There are still some enhancements we would like to make and this article does not cover how the back-end was hooked up to this interface but I am sure most of you can figure that one out as there should not be to much of a difference, if any, then the way you are currently doing it with your desktop browser based apps. I hope you enjoyed this article, found it useful, learned something new and will start building your own versions for the iPhone using iUI. We encourage you to use the iPhone version of DZone at http://dzone.com/iphone and send us you feedback on how we can improve on what we already have and what you would like to see in future versions.