Presenting at the San Diego Flash User Group

If you’re in the San Diego area and want to hear a bit about Flex for mobile devices I’ll be presenting on that topic to the San Diego Flash User Group on December 6th at 6:00 in the North Building of the San Diego Art institute.

I’ll be talking about:

  • Introducing Flex “Hero” and the mobile-optimized components
  • UI paradigms in Flex “Hero” for mobile devices
  • Optimizing Flex “Hero” for good performance on devices
  • Using device APIs with Flex “Hero”

I’ll also be around Southern California for a bit afterwards so if you want to get together and talk Flash/Flex/AIR or anything else, drop me a line.

Getting Started With jQuery Mobile

I’ve been spending a lot of time recently getting my JavaScript and HTML chops up because I think that Adobe is going to have a lot of impact in the HTML5/JS/CSS3 world next year and as a web developer, HTML and JavaScript have become incredibly interesting (and fun) with the rise of frameworks and the mobile landscape. As part of that experiment I’ve been digging into jQuery mobile. I’m obviously not a jQuery pro but after playing with both Flex “Hero” for mobile applications and now jQuery mobile, I thought it would be helpful to do a quick getting started post on jQuery mobile and talk about some of the UI paradigms it uses while walking through a basic application. jQuery mobile is in alpha2 right now, so it’s a little rough around the edges, but still very capable of providing a basis to create mobile applications.

jQuery Mobile divides the world up into pages, which are essentially just screens. Each page has three areas for content; the header, the main content, and the footer. Those are each defined by setting the data-role attribute within the div tag to specify “header”, “content”, or “footer”. The data-role attribute is also used to set up pages by setting it to the “page” value. With jQuery mobile the pages can be set up in different HTML files or all in one file. For this example I’m going to build a two-screen application. The first screen has a button that the user clicks to enable the use of the Geolocation APIs and the second screen is going to be a list of Wikipedia entries that are close to the coordinates. So I have two pages each with the three content types set using data-role.

 
<div>
 
<div>
 
<h1>Find Location</h1>
</div>
 
 
<div>
 
This application will use the <a href="http://geonames.org">Geonames</a> API and your location to bring back a list of Wikipedia articles about features that are near you. To get started, click the button below and allow the application to read your geolocation information.
 
        <input id="getLocation" type="button" value="Get My Location" /></div>
 
 
<div>
 
<h4>By <a href="http://blog.digitalbackcountry.com">Ryan Stewart</a></h4>
</div>
</div>
 
 
<div id="dashboard">
 
<div>
 
<h1>Data List</h1>
</div>
 
 
<div>
 
<ul id="wikiList">
</ul>
</div>
 
 
<div>
 
<h4>By <a href="http://blog.digitalbackcountry.com">Ryan Stewart</a></h4>
</div>
</div>

With my structure set up I can now start adding jQuery-mobile specific interactions. As soon as I add the jQuery mobile libraries to my application it knows how to parse the data-role attributes and themes the application accordingly. What you get is something like on the right. Notice how it automatically styles the header and footer sections as well as providing a nice, big, touchable button and some styling on the footer link to indicate that it can be tapped.

With the external jQuery and jQuery mobile files included I can move on to adding interactivity. I start by adding a click handler to my button, which will go out and grab the geolocation information if it’s available. It’s just using the HTML5 geolocation API, which is supported by most modern browsers. When the user clicks the button, it will get the current position and then call onSuccess or onError depending on whether or not the API call worked.

$(document).ready(function(){
     // Add a click listener on the button to get the location data
     $('#getLocation').click(function(){
          if (navigator.geolocation) {
               navigator.geolocation.getCurrentPosition(onSuccess, onError);
          } else {
               // If location is not supported on this platform, disable it
               $('#getLocation').value = "Geolocation not supported";
               $('#getLocation').unbind('click');
          }
     });
 
});

Next I set up a namespace for the geonames information. It has variables for the baseURL and then a search function with the getJSON function that goes out and calls the Geonames API. The function loops through each one of the results and then creates an <li> tag and appends the data we want to show to it, including the title of the Wikipedia article, the distance, and a summary. This is all straight jQuery. But after that we get into a couple of jQuery mobile-specific parts.

// create the geonames namespace for calling the API
var geonames = {};
     geonames.baseURL = "http://ws.geonames.org/";
     geonames.method = "findNearbyWikipediaJSON";
     geonames.search = function(lat,lng){
 
     // get the data in JSON format from Geonames
     $.getJSON(geonames.baseURL + geonames.method + '?formatted=true&amp;lat=' + lat + '&amp;lng=' + lng + '&amp;style=full&amp;radius=10&amp;maxRows=25',function(data){
          // Loop through each item in the result and add it to the DOM
          $.each(data.geonames, function() {
               $('
 
 
')
               .hide()
               .append('<a href="http://'+this.wikipediaUrl+'">
 
<h2>'+this.title+'</h2>
 
 
</a>
 
'+ this.summary + '
 
<span class="ui-li-aside">
 
<h5>'+this.distance+' (km)</h5>
 
 
</span>')
               .appendTo('#wikiList')
               .show();
          });
          // Once the data is added to the DOM, make the transition
          $.mobile.changePage('#dashboard',"slide",false,true);
 
          // refresh the list to make sure the theme applies properly
          $('#wikiList').listview('refresh');
     });
};

The page model in jQuery mobile gives you a lot of control over how those pages are displayed. By default, when you set up an anchor tag it will play a default transition and go to the page you want. If that page is an external page it will load that external page in the browser. If it’s an internal, local link (with a hash), then jQuery will perform a slide transition and then swap out the old page content with the new one. It also updates the URL by default so you can use the back button that’s included in the header or the back button on your device/browser and go back to the original page. Pretty slick that this all happens by default. However, if you want more control you can use the $.mobile.changePage method, which is what I’m using because I wanted to only change the page after I had parsed the data from Geonames. With mobile.changePage I specify the URL, which in this case is just the id of the new div tag, the transition I want, whether I want the animation to be reversed, and finally whether I want to change the URL so the user can go back to the first screen. By default when you use mobile.changePage the last attribute is set to false so it won’t update the URL in the navbar. In this case I want them to be able to update their location when they move so I set the property to true.

The last thing I have to do is refresh the list to make sure the styles are applied to the new data. Lists are incredibly sick in jQuery an jQuery mobile. By using the data-role attribute and the data-theme attribute you can create some very powerful lists. In this case, I’m just using the default list so my <ul> tag has an id of wikiList, and a data-role of “listview”. That means any <li> tags I add to it will become jQuery mobile list items. And that’s exactly what happens in my Geonames callback function when I iterate through each item. It’s creating <li> elements with my data and appending them to my wikiList <ul> tag. Then when I call .listview('refresh') on my wikiList, it styles them appropriately. One cool feature of jQuery mobile lists is that there are a few different properties I can set to add some stylistic touch. For example, to show distance I’m using a span tag with the class set to ui-li-aside. That class will right-justify the content so my distance shows up on the right side.

And that’s pretty much all there is to it. The last bit of code I have is just the onSuccess and onError functions that handle the geolocation API.

// Success function for Geolocation call
function onSuccess(position)
{
     geonames.search(position.coords.latitude,position.coords.longitude);
}
 
// Error function for Geolocation call
function onError(msg)
{
     alert(msg);
}

You can check out the full application here and see it in action. This is just scratching the surface of what you can do with jQuery mobile but hopefully you got a sense of the page model and how to move back and forth between screens. In some later posts I’ll hopefully cover the new gestures, the new components, and some of the ways to lay out content.

Untappd – Down with Mobile Apps

Update: This was recently the topic of a post by Fred Wilson, a very well known VC. I’m riffing on it now because I had an example today that drove it home for me.

I hate that mobile apps have taken the world by storm. I hate not being able to access something because I have an Android phone and all that the site has is an iPhone app. As a developer I hate having to build for a crap-ton of different platforms to make sure my users have access to my content. If only there was some global phenomenon that was accessible on a mobile device and was completely cross-platform. Oh wait, there is, it’s called THE WEB.

Why in the hell are we building native mobile applications when we can just build a web application to accomplish the same thing? Now, I understand that there are some requirements, like camera, that force us into the native realm. But if you aren’t using the camera or some other device-specific API, you should be building a web app.

This is why I love Untappd so much. Untappd is essentially Foursquare for beer. Instead of checking into a location, you can “check-in” what beer you’re drinking. Instead of doing the native app thing, they built a mobile site. I can access it from any device. It uses the browser-based GPS API to get my location so I can attach that to my beer, and there’s no stupid install needed. Just a wonderful web app with all of the functionality I need accessible from anywhere.

I realize there are some caveats beyond the device-specific APIs, but there has to be ways around them. One of the biggies is responsiveness. I think this one is kind of a cop-out because a great web app will be able to create a UI in such a way that it feels just as responsive as a native app. jQuery mobile and Sencha Touch are great at this. The biggest thing is monetization. Currently it’s really hard to monetize web apps and it’s very easy to monetize native mobile applications. This is one of the reasons I’m so jazzed on the idea of the Chrome web store. Being able to make money on web apps could (I think) help change the tide and encourage more developers to go the web app route.

It’s a shame that we’re able to do such cool stuff on the web but that developers are jumping through hoops to lock down their content to specific devices. We’ve got technologies like PhoneGap in the interim, but the sooner we get back to the web, the better.

P.S. My username on Untappd is ryanstewart.