<!DocType HTML5.in>

Geolocation, Offline &
Mobile

Dhaval Trivedi

UX Engineer, Studio March


This Page Intentionally Left Blank

only for adults!
where am i?

Geolocation

The Geolocation API...

  • High level interface to device implementation.
  • Agnostic of the underlying information sources.
  • Location inferred from GPS, WPS, Cell Tower Triangulation, IP Address, etc.
  • Location information is represented by latitude and longitude co-ordinates.
  • No guarantee! Accuracy depending availability of geo data.
  • Sharing your location is always opt-in. If you don’t want to, you don’t have to.

    Infobar:
    geolocation prompt

...is supported by

FireFox Safari Chrome Opera iPhone Android
3.5+ 5.0+ 5.0+ 10.6+ 3.0+ 2.0+

The geolocation object

  • Geolocation API is published through geolocation child object within navigator object.
  • If the object exists, geolocation services are available. You can therefore:
                        if (navigator.geolocation) {
                            // geolocation is available. yay!
                            // do stuff.
                        } else {
                            // bugger
                            alert ('Geolocation services are not supported by your browser');
                        }
                    

Getting the location

  • navigator.geolocation.getCurrentPosition()
  • "One shot"
                        // Three parameters - Success callback, an Optional Error callback, and an Optional PositionOptions Object.
                        navigator.geolocation.getCurrentPosition(show_map, handle_error);

                        // callback is called asynchronously
                        // with a Position object
                        function show_map(position) {
                            var latitude = position.coords.latitude;
                            var longitude = position.coords.longitude;
                            var accuracy = position.coords.accuracy;
                            // what are you waiting for?
                        }

                        // things gone awry. error callback will be called with PositionError object.
                        function handle_error(err) {
                            if (err.code == 1) {
                            // user said no!
                            }
                        }                        
                    

The Position Object

  • Has two properties - coords and timestamp.

Property Type Notes
coords.latitude double decimal degrees
coords.longitude double decimal degrees
coords.accuracy double meters
coords.altitude double or null meters
coords.altitudeAccuracy double or null meters
coords.heading double or null degrees
coords.speed double or null meters/second
timestamp DOMTimeStamp Date() object

The PositionError Object

  • Has two properties - code (enumerated error code) and message (for logging).

Error Enumerated Value
PERMISSION_DENIED 1
POSITION_UNAVAILABLE 2
TIMEOUT 3
UNKNOWN_ERROR 0

The PositionOptions Object...

  • Has three properties - enableHighAccuracy, timeout and maximumAge.
  • All are optional.

Property Type Default Note
enableHighAccuracy Boolean false true might be slower, may fail.
timeout long (no default) milliseconds
maximumAge long 0 milliseconds

...examples

                        // Cache a position for 75 seconds
                        navigator.geolocation.getCurrentPosition(show_map, handle_error, {maximumAge:75000});
                        
                        // Force to use GPS if available
                        navigator.geolocation.getCurrentPosition(show_map, handle_error, {enableHighAccuracy: true});
                        
                        // Fall back to a previously cached position
                        navigator.geolocation.getCurrentPosition(show_map, handle_error, {maximumAge:Infinity, timeout:0, enableHighAccuracy: true});
                    

Watching the current location

  • navigator.geolocation.watchPosition()
  • "Requests repeated position updates"
  • Same as getCurrentPosition() - the callback is called every time the position is updated.
  • Get a handle to watchPosition, and use clearWatch(handle) to stop getting the updates. Just like setInterval() and clearInterval()

                        // Simple, eh?
                        var watchId = navigator.geolocation.watchPosition(update_map, handle_error);

                        // On clicking some button, we want all this to stop.
                        function someButtonClickHandler() {
                            navigator.geolocation.clearWatch(watchId);
                        }
                    

Unsupported platforms?

  • Google Gears - almost the same as geolocation API.
  • Many older mobile platforms have device specific geolocation APIs - e.g. BlackBerry, Nokia, Palm, etc.

Let there be geolocation! geo.js!

  • http://code.google.com/p/geo-location-javascript/
  • Open source, MIT-licensed library.
  • Still need to include gears_init.js
  • Normalizes API differences across different platforms.
  • Doesn't support watchPosition() yet, so getCurrentPosition() has to be polled continuously.
Offline Storage FTW!

Offline

Cookies

  • ...suck!
  • 4 KB? What?
  • Hard to code.
  • Cookies leak.
  • Cookies are immortal.

Web Storage

  • A simple key/value pair storage.
  • One API, easy to remember.
                        // To set a key-value
                        setItem(key, value);
                        // even better
                        localStorage[key] = value;
                        
                        // To get a value
                        string* getItem(key);
                        // moar better
                        var someInt = parseInt(localStorage[key]);

                        // Remove a value
                        removeItem(key);
                        
                        // Get a key
                        string key(index);
                        
                        // Clears the entire storage
                        clear();
                        
                        // Count
                        .length;
                    

Two Instances

localStorage

  • Persists until you or user explicitly clears.
  • Applied to document origin - scheme/host/port tuple.
  • No expiry.

sessionStorage

  • Lasts while on document origin.
  • There ain't no leaks.
  • Otherwise, the same as localStorage.

Two things

  • Values are strings.
  • To store complex objects, use JSONs.

Inspecting

Local Storage

Browser Support

IE FireFox Safari Chrome Opera iPhone Android
8.0+ 3.5+ 4.0+ 4.0+ 10.5+ 2.0+ 2.0+

For unsupported browsers

Detecting

                        if (Modernizr.localstorage) {
                            // window.localStorage is available!
                        } else {
                              // no native support for HTML5 storage :(
                              // maybe try dojox.storage or a third-party solution
                        }                      
                    

Not supported?

Alternatives

Web SQL Database

  • Opera, Chrome, Safari, Mobile Safari. Firefox - never!
                        // Sample code
                        openDatabase('documents', '1.0', 'Local document storage', 5*1024*1024, function (db) {
                            db.changeVersion('', '1.0', function (t) {
                                t.executeSql('CREATE TABLE docids (id, name)');
                            }, error);
                        });
                    

IndexedDB

  • Object Store - No SQL
  • FireFox4 Beta only :(

Offline Caching

  • List of URLs - HTML, CSS, JavaScript, images, etc.
  • Revolves around a manifest file.
  • Beware - if any resource fails, the app will not work offline.

Including a cache manifest

                        <!DOCTYPE HTML>
                        <html manifest="cache.manifest">
                        <body>
                        ...
                        </body>
                        </html>
                    

The Manifest

  • Serve as text/manifest by adding to mime.types:
    text/cache-manifest manifest
  • First line must be:
    CACHE MANIFEST
  • Including page is implicitly included in the cache.
  • Add some versioning.
    # version 3
  • Moar namespaces - NETWORK and OFFLINE.

Sample cache.manifest

                        CACHE MANIFEST
                        #version 3
                        #URLs to be cached
                        CACHE:
                        index.html
                        css/style.css
                        js/script.js
                        # the whitelist
                        NETWORK:
                        /live/*
                        /ajax/*
                        # fallback(s)
                        FALLBACK:
                        / offline.html
                        # or foo/bar foo.html
                    
Mobile

Mobile

Browsers

  • Mobile Safari - iPhone/iPod/iPad
  • Android Browser
  • Opera Mini & Mobile

Frameworks

  • jQtouch - favors Apple/Webkit. For iPhone/iPod.
  • Sencha - favors Apple/Webkit. For iPad.
  • A lot others. Who cares?

A lot of pain.

But don't worry!

jQuery Mobile

jQuery Mobile

  • Seriously cross platform and cross device.
  • Strategy - "Delivering top-of-the-line JavaScript and a unified User Interface across the most-used smartphone web browsers."
  • Not mimicking any particular platform design.
  • A universal design system that will feel “right” on a broad range of devices.

Performance Tips

  • Scripts at bottom.
  • Store as much UI offline.
  • Pre-load UI for responsiveness, lazy load data.
  • Use HTML5 - flatter DOM.
  • In JS, select in context (descend from IDs, etc).
  • Also, cache your selectors.

Demo

Thank You.