Guide to iOS Web Apps

This is a post from my original Wordpress blog. It has some valuable information so I decided to reinstate some of these old posts. Originally posted on October 21, 2010.

When I first started toying around with the idea of making apps, I came to the brink of buying an Apple Developer's SDK along with a Macbook Pro just to be able to develop my own applications. I wasn't really interested in the money that comes with the App Store, just spreading my ideas and learning new technology.

I ditched the idea of spending big bucks on a computer and an SDK and decided I'd make web applications that did the same things as native apps. I used jQuery for some animations and called it a day. However, when I opened up my site on my iPad it ran terribly. I tried using the site for a while, but it just felt awful, so I gave up.

I soon found out that iOS web animations were a tricky breed. I found this demo and it ran perfectly on my iPad. I immediately began researching how to make everything run smoothly. The more I learned about hardware acceleration, the more I wanted to make something new, something smooth.

That's when I realized that you can actually save websites to your homescreen and have a custom icon, just like an app! I've been studying web app techniques and after learning all that I can from Googling have finally pushed the boundaries to where I am exploring technologies and techniques not practiced publicly.

So without further adieu, I present my guide to creating the perfect web application.

Quick Links

Toolbox

Here is what you need to know, some of which you need to know pretty well, to create a solid iOS web application:

HTML5

You don't need to necessarily be an HTML5 guru to create web apps, but the more the know the more you can do. Mobile Safari supports a lot of HTML5 features, and in the upcoming iOS 4.2, it's gaining even more.

Links:

CSS

You will need to be able to style your pages pretty well. But on top of this you should really read up on all of the new CSS3 properties. In combination with the <canvas> element, you should be aiming to reduce the number of images on your page by creating your own gradients, shadows, transformations, and animations. Remember that iOS devices usually don't have an amazing amount of memory. The more images that are loaded, the more memory is used. Using CSS will still use system memory, but you will take less of a performance hit.

Links:

Javascript

To make a web application feel like an application and not a website, you need to have a very good understanding of how javascript works and how you can properly optimize your javascript, both in size and speed. The larger your code is the longer it takes to load, and the more complicated and sloppy your code is the slower your application will run. You need to conserve resources in your application as best as possible.

Special Note: I know that everyone loves to use jQuery, but in many cases jQuery can take very long to perform relatively simple tasks. Use jQuery with caution. Store DOM elements as variables, avoid searching the DOM every time you want to call an object. Also never use $.animate(). Ever. Here is a great site for optimizing your jQuery code.

Server Side Control

You don't need to be an expert in server-side controls to create a web app for iOS. However, the better you are, the better your apps will be (see the next technology). The biggest thing that you should be able to do is detect an iOS device on the server side and then redirect, or filter, the content that is displayed. In PHP I use this simple script to determine what the user agent is, and then tailor the content I display to fit the limitations of the user:

<?php
if(strstr($USER_AGENT,'iPhone') || strstr($USER_AGENT,'iPod')){
    $browser = 0;
}elseif(strstr($USER_AGENT,'iPad')){
    $browser = 1;
}elseif(strstr($USER_AGENT,'MSIE')){//internet explorer
    $browser = 2;
}elseif(strstr($USER_AGENT,'MOZILLA')){   //firefox
    $browser = 3;
}else{//chrome or safari (webkit)
    $browser = 4;
}

As far as languages go, I prefer PHP for my server side control when developing for iOS devices. I initially started using ASP.net, but the more that I got into using AJAX, the more ASP.net was trying to do than was necessary. In general I find ASP.net to be a solid language, but when it comes to minimization and optimization, it usually does more than I ask. Stick to something simple that will control your HTML, CSS, and Javascript output. I have not gotten a chance to experiment with Ruby or even HTTP via Python, but I have heard good things about them.

AJAX

Short for Asynchronous Javascript And XML, AJAX provides an incredibly fast method for updating a page's content. You can create images, access databases, and even change an entire page's DOM with AJAX, avoiding that "page flicker" that ruins the immersion of using a website as an application. I usually use jQuery's $.ajax() method because it's syntactically simple, but feel free to use whatever you are most comfortable with. Just please, please avoid ASP.net's <asp:UpdatePanel> control, it will send and receive way too many requests than is necessary.

Links:

Creating an Icon

Open up whatever image editor you want and create a blank 114x114 pixel PNG. This creates the maximum icon size for the Retina display. Once you have created and uploaded the image, link to it like so:

<link rel='apple-touch-icon' href='/images/icon.png' />

or if you don't want the gloss overlay:

<link rel='apple-touch-icon-precomposed' href='/images/icon.png' />

The image will automatically be glossed (unless you use the second link) and the corners rounded, so don't worry about applying any of those effects in your image editor.

Creating a Splash Screen

Just like the icon, add the following meta tag to the head of your html:

<link rel='apple-touch-startup-image' href='/images/splash.png' />

For the iPhone/iPod, you need to create a PNG that is 320x460px, and for the iPad the image needs to be 768x1004px. Make sure that you create portrait oriented images. Currently the iPad will load an app in landscape mode, but it will still use the 768x1004px image which leaves a blank, see-through, space on the left side of the screen. I haven't found a fix for this, so if anyone has any ideas, let me know!

Update: I would love if Apple could address the orientation of startup images for the iPad. It may have changed in 4.2, but it seems now that if you start a web app with a startup image from landscape orientation, iOS will not load the image. You have to start the app in portrait mode to see it.

Removing the Address Bar

This is very simple. In my opinion you should always remove the address bar to give your web app a native app appearance.

<meta name='apple-mobile-web-app-capable' content='yes' />

Stop Zooming and Scrolling

If your app fits inside the window and you would like to prevent the user from scrolling, or if you want to prevent zooming in and out, add the following:

For scaling, add to the head:

<meta name='viewport' content='user-scalable=no, width=device-width' />

For scrolling, add to your javascript:

function block(e) {
    e.preventDefault() ;
}

and to the body element:

<body ontouchmove='block(e)'>

Change the Status Bar

This is another simple aesthetic change. I'd prefer Apple allow the status bar to be removed so that we can take advantage of the entire 1024x768 resolution, but it is always present.

<meta name='apple-mobile-web-app-status-bar-style' content='default' />

The other values for content are:

defualt, black, black-translucent

Cascading Style Sheets

In this section, I will assume you have a basic understanding of CSS and how it works. Mobile Safari takes advantage of a lot of new CSS3 properties. In my experimenting, some of the new properties must have the prefix -webkit, while others do not. In debugging, if you don't see a property, try toggling this prefix.

Linking to CSS

Should you put your CSS in your HTML? Or should you link to external files? How do you distinguish from the different files for different devices?

Usually, I use one master stylesheet. I try my best to reduce HTTP requests, because I believe the iPad (as an example) can only load 2 threads at a time. I'm not 100% on this, but I know it is limited when compared to a desktop browser. I also like to tailor what is loaded on the server side. There are techniques to choosing a stylesheet in the HTML, but I think server side is the easiest way to go (goes parallel with tailoring my HTML and Javascript, keeping structure consistent).

However, if you do not want to select a stylesheet based on the user_agent, here is a device width technique:

<link media='only screen and (max-device-width: 480px)' href='/css/iphone.css' type= 'text/css' rel='stylesheet' />

Detecting Orientation

You should also separate your stylesheets based on the device's orientation. I generally put all of the style properties in one file, and in another, correct for the opposite orientation with !important tags on each property I am changing. Usually this leaves me with two stylesheets (and that is all that will be requested on the page load!): one being very large for one orientation, and the other very small with opposite orientation corrections. To determine orientation for stylesheet selection, use this:

<link type='text/css' rel='Stylesheet' media='all and (orientation:portrait)' charset='utf-8' href='css/ipadp.css' />
    <link type='text/css' rel='Stylesheet' media='all' charset='utf-8' href='css/ipad.css' />

Animating with CSS

To start off, if you are used to jQuery, please drop everything that you know about animating DOM elements. Currently, jQuery will sometimes animate objects by simply changing the "left" CSS property instead of using a -webkit-transition or keyframe.

Please see my previous posts on CSS animation for ideas:

Here are a few other tips:

Javascript

Again, you should have a fairly good understanding of Javascript if you are making an iOS web app. The only way to really make your app interactive is to use Javascript. I will just list some tips here.

How to Load

The only Javascript that I like to load outside of the HTML is the jQuery framework. Other than that, I like to tailor the scripts for the device being used and load it directly with the HTML at the end of the document. It is good practice to put all of your Javascript after the DOM elements (ie. right before you close the body). If you put Javascript before everything else, the browser will stop loading the page until all of the scripts have loaded/executed.

Tips

Summary

This entire post is just a round up of what I have learned and gathered about making iOS web applications. It took me a long time to get to this point, and if I had things laid out this plainly when I had gotten started, things would have gone a lot smoother. I thought I'd just share the love and save some people some time.

I started making web apps to avoid using OSX and the Apple Developer's SDK, and it has really paid off. There is a lot to learn about tailoring to a specific product. Please keep in mind though, Apple devices are not the only means of being on the web and using applications. I think they are revolutionary devices, but if you are creating content for public use (or even commercial), you will have to meet the needs of Firefox, Safari, Chrome, IE, Opera... the list goes on and on (keep in mind other mobile browsers too like Blackberry and Android!).

But, I have fun using my Apple products with my web apps. The touch interface is amazing, even when using a web app. By optimizing and minimizing, you can easily create a native feeling web application for your iOS device.