Mobile development with HTML5 »
Created at: 26.08.2011 01:54, source: Engine Yard Blog, tagged: Technology html5 jquery local storage mobile
HTML5: the standard, the buzzword and the legend
If you read blogs that are even slightly related to tech, you likely hear about HTML5 on a near-weekly basis. Although the new web standard does not do your laundry, it has features that enable the creation of powerful applications—using only HTML, CSS and JavaScript (a Rails back-end can bring additional firepower to the table). This post will go over some key concepts and features of HTML5, setting the stage for more advanced subjects.
Browser Compatibility
Perhaps the biggest pain in developing a web-based application is ensuring that your application is compatible with the various browsers in use today. Fortunately, this is less of a problem in the mobile world. Because people get new phones more often than new computers and because the smart phone space is relatively young, there are simply fewer old smart phones out in the wild. However, this is not a carte blanche; you should test your site with any devices you wish to support, not just simulators.
Viewport
When you visit a website not designed for mobile browsers, it first appears very zoomed out. This is done intentionally by the mobile browsers to make the website viewable. They set the default viewport width to between 800 and 980 pixels (depending on the browser). This allows the user to view the whole website and then zoom in as needed. However, if you are crafting a website specifically for mobile, it make sense to set the initial viewport for the mobile device. This is accomplished with the viewport meta tag.
<meta name="viewport" content = "width=device-width”>
This sizes the viewport to the device’s width, so the content does not initally appear zoomed out. You will likely want to disable zooming entirely, so the user doesn’t accidentally zoom out and distort the UI. Do this by setting user-scalable to no.
<meta name="viewport" content = "width=device-width , user-scalable=no">
Some sites currently hard-code the width of the viewport to 320. Why? Because this is the width of the iPhone. However, in general, it is a better practice to use “device-width” instead of 320.
Having your site correctly sized for mobile is nice but the next two features of HTML5, caching with the cache manifest and local storage, allow for fully functional offline sites.
HTML5 Caching
HTML5 caching allows users to view websites they have visited before without a connection to the web. Not only is this extremely useful for users who may not get coverage where they want to use the application, but it can also mitigate brief drops in a connection.
To setup HTML5 caching, you add a manifest file to the html tag of every page you want to cache.
<html manifest="/cache.manifest">
This file starts with “CACHE MANIFEST” and then enumerates the files that the application should cache.
CACHE MANIFEST
/mystyle.css
/scripts.js
/logo.jpg
Now those files will be available offline. Frankly, there is a long list of gotchas with the cache manifest. I review some key ones below but suggest reading Dive into HTML5 for all the details.
The first and foremost, your site will default to cached files over recently downloaded ones, meaning that even if the cache has changed since the browser has last visited the page, the browser displays the old pages until the page is refreshed (or told with JavaScript to update). This is further compounded by the fact that most web servers tell the browser cache the files they serve. When you are developing your site, be sure to tell your web server not to cache the cache manifest, so you always download the most recent copy.
The next big gotcha is how the browser manages the downloading process. If the browser detects that the manifest has changed, it re-downloads every single file. Not only does this make the process expensive, if a single file fails to download correctly, the browser abandons the update and loads the previous cache. When this happens the browser does not post any error by default. However, you can use JavaScript to detect the error thrown by the manifest.
$(function() {
$(window.applicationCache).bind("error", function() {
alert("Cache: update failed");
});
});
So now your site is cached and everything worked. You’re ready to launch? Not really. This caching technique works well with static content. However, if your application has content that is dynamically created and frequently changed (most web apps), it will not work well. This is because, unless the cache is changed, the old html page will be displayed, not the page with your new content. The simple answer is to change the cache manifest file whenever new content is added. However, this is generally not a good idea because it forces the browser to re-download every file every time any content is changed—very costly if your content is updated frequently. The solution is to use jQuery templates to build the page dynamically.
jQuery Templates
The best practice is to populate your content through JavaScript templates. In this way, the content is not part of the HTML page and thus is not cached with the cache manifest. For this, you need to download and add jQuery and the jQuery template plugin to your application.
There are three steps to using these templates:
- Define the template.
- Define the collection.
- Tell jQuery to populate to the page with the template.
Below is an example for a simple blog application.
1. Define the template:
<script id="post_template" type="text/html”>
<div>
<h2>${Name}</h2>
<p>${Body}</p>
</div>
</script>
2. Define the collection (of posts in JSON).
<script>
var posts = [
{ Name: "First!", Body: "This is pretty cool" },
{ Name: "Another post", Body: "This is pretty cool" },
{ Name: "Yet another blog post", Body: "This is pretty cool" }];
</script>
3. Tell jQueryto populate to the page with the template.
<script>
$( "#post_template" ).tmpl( posts ).appendTo( "#blog_posts" );
</script>
…
<body>
<div id="blog_posts"></div>
</body>
Although this content is loaded via JavaScript, it is not dynamic—it is just defined on the page. For dynamic content we will want to use JSON provided by the server. Let’s assume our blog application provides us with the JSON representation of our blog at this URL:
/posts.json
We will tell jQueryto make a request for the JSON and then use it to populate the page.
<script type="text/javascript">
$.getJSON('/posts.json', function(data) {
$( "#post_template" ).tmpl( data ).appendTo( "#blog_posts" );
});
</script>
We also need to change the template so that it can handle the JSON elements, substituting post.name for Name and post.body for Post:
<script id="post_template" type="text/html">
<div>
<h2>${post.name}</h2>
<p>${post.body}</p>
</div>
</script>
Now our blog is pulling content that is not cached in the cache manifest and using jQuery templates to populate the page. However, this works only if our mobile browser can connect to our server. This feels like two steps forward and three steps back, but trust me, we almost have a working mobile HTML5 app. We just need to include one last component of HTML5, Local Storage.
Local Storage
Christopher Haupt of Webvanta recently authored a guest blog post about Local Storage. See the Enhancing Client-side Storage with HTML5 post for details and general use.
On a high level, Local Storage is a client-side key-value store implemented by the browser. It stores strings of text locally and then recalls them later. Here, we use it to store JSON so we can populate the blog with posts even if there is no connection to the server.
Although we could write this by hand, there is a great plugin to manage the process for us. The jQuery Offline plugin uses content from Local Storage if the server is not available and will store fresh content in local storage when it’s received.
Download this plugin from jQuery-Offline
To use the plugin we change the getJSON call to retrieveJSON. We will also need to change our script slightly as there is one key difference between getJSON and retrieveJSON. The latter will execute twice, once to pull from the cache and again to get the new content from the server. This will cause the posts to appear twice if we simply append the new posts to the page.
<script type="text/javascript">
$.retrieveJSON('/posts.json', function(data) {
$( "#blog_posts" ).html($( "#post_template" ).tmpl( data ));
});
</script>
The blog application can now be viewed offline and is correctly sized for a mobile browser! You can download this example here offline-blog.
I hope you enjoyed this initial look at some of the technologies that are making mobile development easier. In the coming weeks I hope to be covering more advanced topics such as the popular MVC framework Backbone.js.
more »
Case for Smartphone Web Activity Feeds »
Created at: 05.10.2010 20:32, source: igvita.com, tagged: Architecture mobile pubsubhubbub
Sensor networks have historically been the domain of the military and large-scale commercial applications - powerful, but expensive to setup and operate. At the same time, Morgan Stanley is reporting that by 2012 the smartphone market will outship the global PC market (notebook, netbook, desktop, etc), which will easily create the largest, always-on, broadband-enabled sensor network to date. Only one problem, most mobile OS vendors (Apple, RIM, Google, etc) are app store obsessed at the moment, each fighting for the developer mindshare to stockpile their native app arsenals. But, for a second, imagine if instead of rushing to build mobile apps which pull data off the web to local devices, what if we also had the infrastructure that could efficiently push the data back to the web? Billions of smartphone devices pushing real-time updates to our web applications - now that would be exciting.
Motivation & Use Cases
The question is not whether pull or push is more efficient (you need both), but enabling push from the smartphone as a platform capability could enable an entirely new class of applications: instead of focusing on an experience of a singular mobile user, you could aggregate data from many agents and build "network aware" applications! For the sake of an example, imagine we had the following:
http://www.apple.com/mobile/feed/{subscriber_id}.xml
http://www.blackberry.com/mobile/feed/{subscriber_id}.rss
http://www.android.com/mobile/feed/{subscriber_id}.js
Yes, that's an RSS feed - it is as simple as that. Each vendor already offers their own platform for "push notifications" to deliver data to the phone, so why not offer the reverse? What if each phone also had a representative notification feed that any web app could access? Calendar notifications, battery notifications, geo notifications, and so on, it is all fair game! Add a subscription and an access control management layer on top, and all of the sudden, any web-developer is now but a URL away from enriching the experience of any mobile user: process a notification from the phone, push an update back. Not to mention, the capability to aggregate data from thousands of mobile devices for trends analysis, data-mining applications and so forth - a global mobile sensor network at your disposal!
Mobile Activity Feeds via PubSubHubbub
Maintaining direct tethered links to each individual mobile device is obviously an expensive and a technically challenging proposition, especially if we are after real-time updates. But the good news is, we have already solved this problem in a different context. WebHooks allow us to establish callback (push) semantics between web-services, and PubSubHubbub solves the problem of efficiently delivering real-time notifications from a single publisher (mobile device, in this case) to many subscribers: the phone pushes a single update to the platform provider and the PSHB hub does all the hard work of distributing the individual updates to each subscriber. Distributed architecture, simple protocols, efficient delivery, and it scales well.
Smarter Web via Mobile Sensor Networks
Native apps are great, but why keep the data locked to within a single device? If we could efficiently aggregate activity feeds from thousands of mobile subscribers with rich geo and contextual meta-data (user, or device generated), then imagine all the numerous mash-ups and data-mining applications that could be built on top!
In fact, if the rumours of Facebook looking at building their own mobile device/OS are true (really, not as crazy as it sounds), then I would argue, it is in part because they understand the (commercial and technical) potential of these activity feeds better than anyone else - what seems completely foreign to Apple, RIM and others is completely obvious to the web-natives such as Facebook and Twitter. Question is, who is going to get there first?
more »


