<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Joe Lambert</title>
	
	<link>http://blog.joelambert.co.uk</link>
	<description />
	<lastBuildDate>Tue, 21 May 2013 13:12:00 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/joelambert" /><feedburner:info uri="joelambert" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Slips for FreeAgent, simple time tracking for Freelancers &amp; Small Businesses</title>
		<link>http://feedproxy.google.com/~r/joelambert/~3/5XTZQiPddks/</link>
		<comments>http://blog.joelambert.co.uk/2013/05/21/slips-for-freeagent-simple-time-tracking-for-freelancers-small-businesses/#comments</comments>
		<pubDate>Tue, 21 May 2013 13:12:00 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.joelambert.co.uk/?p=1177</guid>
		<description><![CDATA[Get Slips now: http://slips.rareloop.com We (Rareloop) have just released our first Mac App via the App Store, it&#8217;s an easy to use menu bar timer that keeps track on how long you&#8217;re spending on tasks. It&#8217;s integrated directly with FreeAgent so re-billing your time couldn&#8217;t be easier. We originally wrote Slips for internal use at [...]]]></description>
				<content:encoded><![CDATA[<p><img src="http://www.rareloop.com/wp-content/uploads/2013/05/slips-blog.jpg" alt="Slips for FreeAgent" /></p>

<p><a href="http://slips.rareloop.com">Get Slips now: http://slips.rareloop.com</a></p>

<p>We (<a href="http://rareloop.com">Rareloop</a>) have just released our first Mac App via the App Store, it&#8217;s an easy to use menu bar timer that keeps track on how long you&#8217;re spending on tasks. It&#8217;s integrated directly with <a href="http://fre.ag/41hrnfsd">FreeAgent</a> so re-billing your time couldn&#8217;t be easier.</p>

<p>We originally wrote Slips for internal use at Rareloop but after having used it everyday for over a year and seeing how much it&#8217;s helped our timetracking we&#8217;ve decided to make it publicly available.</p>

<p>If you use a Mac &amp; FreeAgent and need to keep track of your hours, I&#8217;d highly recommend taking a look at <a href="http://slips.rareloop.com">Slips</a>!</p>

<p><a href="http://slips.rareloop.com">Get Slips now: http://slips.rareloop.com</a></p>
<img src="http://feeds.feedburner.com/~r/joelambert/~4/5XTZQiPddks" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.joelambert.co.uk/2013/05/21/slips-for-freeagent-simple-time-tracking-for-freelancers-small-businesses/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://blog.joelambert.co.uk/2013/05/21/slips-for-freeagent-simple-time-tracking-for-freelancers-small-businesses/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=slips-for-freeagent-simple-time-tracking-for-freelancers-small-businesses</feedburner:origLink></item>
		<item>
		<title>Offline First – A better HTML5 User Experience</title>
		<link>http://feedproxy.google.com/~r/joelambert/~3/GOErxtSAJZY/</link>
		<comments>http://blog.joelambert.co.uk/2012/11/26/offline-first-a-better-html5-user-experience/#comments</comments>
		<pubDate>Mon, 26 Nov 2012 08:23:36 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.joelambert.co.uk/?p=1162</guid>
		<description><![CDATA[This year at Full Frontal, offline enabled web site/apps were a recurring theme. Paul Kinlan gave an excellent talk entitled &#8216;Building Web Apps of the future. Tomorrow, today and yesterday&#8217; (his slides are available here), in which he compared the &#8216;offline&#8217; user experience provided by the top 50 or so iOS and Android apps with [...]]]></description>
				<content:encoded><![CDATA[<p>This year at <a href="http://2012.full-frontal.org">Full Frontal</a>, offline enabled web site/apps were a recurring theme. <a href="https://twitter.com/Paul_Kinlan">Paul Kinlan</a> gave an excellent talk entitled &#8216;Building Web Apps of the future. Tomorrow, today and yesterday&#8217; (his slides are available <a href="https://speakerdeck.com/paulkinlan/building-web-apps-of-the-future-tomorrow-today-and-yesterday">here</a>), in which he compared the &#8216;offline&#8217; user experience provided by the top 50 or so iOS and Android apps with that of popular web sites/apps.</p>

<p>Needless to say, the native apps fared better and more gracefully degraded when no internet connection was available. <strong>Offline is a feature</strong> and it&#8217;s crucial we start to consider it from the start of a project as apposed to adding support later in the development lifecycle. At <a href="http://rareloop.com">Rareloop</a> we&#8217;ve been focussing on adding offline support to our apps from the start. Most notably the <a href="http://formagenthq.com">FormAgent</a> mobile clients where designed from the outset to support offline access, to allow for use when no connectivity was possible and to transparently sync up data when internet is available. The following are guidelines I&#8217;ve found helpful.<span id="more-1162"></span><br/><br/>
<em>Note, I&#8217;m not going to discuss how to cache your app assets (e.g. JavaScript &amp; CSS). Whether you&#8217;re using App Cache or a hybrid solution (like <a href="http://phonegap.com">PhoneGap</a>) it&#8217;s not really important, the guidelines below are more focussed on how to engineer your app to enable sensible offline access and assume your core assets are already readily available via some mechanism.</em></p>

<h1>Basic guidelines</h1>

<h2>1. Decouple your app from the server</h2>

<p>Historically when creating content for the web the server does the majority of the heavy lifting. Data is stored in a database and is accessed via server side code (e.g. PHP or Ruby), the data is then manipulated and rendered to HTML with a series of templates. Many modern frameworks use good Software Engineering principles and separate these tasks in an MVC architecture (Model, View, Controller) but they are still server side. This means that the storing, manipulation &amp; rendering of content all requires a connection to the server.</p>

<p>An offline first approach would be to move the entire MVC stack into client side code (aka our app) and to turn our server side component into a data only JSON API. This keeps the server component largely logic less, lightweight and makes it really easy to write unit tests for.</p>

<p><a href="https://twitter.com/jamespearce">James Pearce</a> also touched on this at Full Frontal (<a href="https://speakerdeck.com/jamesgpearce/23181">slides</a>), with a slightly tongue in cheek statement:</p>

<blockquote>
  <p>no angle brackets on the wire &#8211; only curly brackets</p>
</blockquote>

<p><strong>Summary:</strong></p>

<ol>
<li><p>Make sure client side app is not reliant on server side code to produce the minimum viable experience. It should be able to at least render something to say that no data is available.</p></li>
<li><p>Communicate using JSON</p></li>
</ol>

<h2>2. Create an API wrapper object in client side code</h2>

<p>Don&#8217;t litter your app code with Ajax calls and nested callback functions. Create an API object that mirrors the functionality of the API end point you&#8217;ve created. This creates a better separation of code within your app which is easier to debug, enables you to write unit tests and crucially allows for mock data to be used if the server side API has yet to be written. The object you create will internally use AJAX but the idea is that from the point of view of the rest of your app, its irrelevant what the implementation details are in order to provide the data requested.</p>

<p><strong>Summary:</strong></p>

<ol>
<li><p>Abstract JSON API into an object</p></li>
<li><p>Don&#8217;t litter your app code with direct AJAX calls and callbacks</p></li>
</ol>

<h2>3. Decouple data updates from data storage</h2>

<p>It might be tempting to now just request data directly from the API object straight into our view objects for rendering with client side templates. I&#8217;d suggest creating a Data object to act as a proxy between the API object and the rest of your app. This new Data object is responsible for making requests to the API for updates and processing the responses. This includes indexing any results received for quick retrieval within the app, synchronising any data stored when no connection was available or just gracefully returning sensible data structures when no data is available.</p>

<p>It&#8217;s up to you to decide what triggers the Data object to request an update from the server (maybe when the user presses a refresh button or the browser fires an <code>online</code> event) but by not calling the server directly you&#8217;re able to locally cache the data more easily.</p>

<p>The Data object must also be able to serialise itself to persistent storage, be that LocalStorage or WebSQL/IndexDB, it should also know how to re-read this serialised form back into memory.</p>

<p><strong>Summary:</strong></p>

<ol>
<li><p>Use a data controller object to store and schedule updates</p></li>
<li><p>Make all requests for data via this proxy object</p></li>
</ol>

<h1>An example</h1>

<p>As way of a trivial example, lets consider a contact card viewing application. The first step would be to create a server based API that lets us retrieve the raw contact data. Lets assume we&#8217;ve created a RESTful API with a URI <code>/contacts</code> that returns the complete list of contact records. Each record has an <code>id</code>, <code>firstName</code>, <code>lastName</code> &amp; <code>email</code> field.</p>

<p>Next, we write the API object to wrap our actual end point which might look something like:</p>

<pre><code>var API = function() { };

API.prototype.getContacts = function(success, failure) {
    var win = function(data) {
        if(success)
            success(data);
    };

    var fail = function() {
        if(failure)
            failure()
    };

    $.ajax('http://myserver.com/contacts', {
        success: win,
        failure: fail
    });
};
</code></pre>

<p>Then we need to write our Data object, which is the interface between our app and the data store. This might look a little like this:</p>

<pre><code>var Data = function() {
    this.api = new API();
    this.contacts = this.readFromStorage();
    this.indexData();
};

Data.prototype.indexData = function() {
    // Do indexing task (e.g. store contact via email)
};

/* -- API Updating -- */

Data.prototype.updateFromServer = function(callback) {
    var _this = this;

    var win = function(data) {
        _this.contacts = data;
        _this.indexData();

        if(callback)
            callback();
    };

    var fail = function() {
        if(callback)
            callback();
    };

    this.api.getContacts(win, fail);
};

/* -- Data serialisation -- */

Data.prototype.readFromStorage = function() {
    var c = JSON.parse(window.localStorage.getItem('appData'));

    // Ensure a sensible default
    return c || [];
};

Data.prototype.writeToStorage = function() {
    window.localStorage.setItem('appData', JSON.stringify(this.contacts));
};

/* -- Standard getters/setters -- */

Data.prototype.getContacts = function() {
    return this.contacts;
};

// App specific data request
Data.prototype.getContactWithEmail = function(email) {
    // Retrieve the contact from our index datastructure
    return contact;
};
</code></pre>

<p>We now have a Data object that can be told to update from the API but that by default serves up data that it has stored locally. We then might have the following code elsewhere in our app:</p>

<pre><code>var App = function() {
    this.data = new Data();
    this.template = '...';

    this.render();
    this.setupListeners();
};

App.prototype.render = function() {
    // Use this.template &amp;&amp; this.data.getContacts() to render HTML
    return html;
}

App.prototype.setupListeners = function() {
    var _this = this;

    // Reload the data from the server
    $('button.refresh').on('click', function(event) {
        _this.refresh();
    });
};

App.prototype.refresh = function () {
    _this.showLoadingSpinner();

    _this.data.updateFromServer(function() {
        // We've now got new data to show
        _this.render();
        _this.hideLoadingSpinner();
    });
};

App.prototype.showLoadingSpinner = function() {
    // show spinner
};

App.prototype.hideLoadingSpinner = function() {
    // hide spinner
};
</code></pre>

<p>The above is a very simple example and in a real app you&#8217;d probably want to make sure the Data object was s singleton but it does illustrate how to structure your code to enable offline access out of the box.</p>

<hr />

<p><em><a href="http://formagenthq.com">Check our the &#8216;Offline First&#8217; approach in action in FormAgent</a></em></p>
<img src="http://feeds.feedburner.com/~r/joelambert/~4/GOErxtSAJZY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.joelambert.co.uk/2012/11/26/offline-first-a-better-html5-user-experience/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		<feedburner:origLink>http://blog.joelambert.co.uk/2012/11/26/offline-first-a-better-html5-user-experience/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=offline-first-a-better-html5-user-experience</feedburner:origLink></item>
		<item>
		<title>FormAgent: Data collection evolved</title>
		<link>http://feedproxy.google.com/~r/joelambert/~3/rXrYGCpg4pE/</link>
		<comments>http://blog.joelambert.co.uk/2012/09/28/formagent-data-collection-evolved/#comments</comments>
		<pubDate>Fri, 28 Sep 2012 07:33:44 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.joelambert.co.uk/?p=1158</guid>
		<description><![CDATA[This week my company Rareloop launched a preview of a new product FormAgent. For anyone who&#8217;s been reading the blog for a while it might seem familiar, in fact its a technology we&#8217;ve been developing for a year and powers quite a few of the projects done at Rareloop. FormAgent is the simplest way to [...]]]></description>
				<content:encoded><![CDATA[<p><img src="http://blog.joelambert.co.uk/wp-content/uploads/2012/09/formagent_http_formagenthqcom.png" alt="FormAgent - http://formagenthq.com" /></p>

<p>This week my company Rareloop launched a preview of a new product <a href="http://formagenthq.com">FormAgent</a>. For anyone who&#8217;s been reading the blog for a while it might seem familiar, in fact its a technology we&#8217;ve been developing for a year and powers quite a few of the <a href="http://rareloop.com/casestudies">projects done at Rareloop</a>.</p>

<p>FormAgent is the simplest way to create and distribute forms/surveys to a range of mobile and tablet devices anywhere in the world. It runs on iOS, Android and BlackBerry PlayBook and even works great in areas of low connectivity.</p>

<p>We&#8217;re currently in private beta, so head on over to <a href="http://formagenthq.com">http://formagenthq.com</a> &amp; sign up for an invite code.</p>

<blockquote>
  <p><strong>FormAgent: Data collection evolved</strong></p>
  
  <p>Take control of your data collection with FormAgent, an online service for creating and distributing surveys to tablets &amp; smartphones anywhere in the world.</p>
  
  <p><a href="http://formagenthq.com">Sign up now for the beta @ http://formagenthq.com</a></p>
</blockquote>
<img src="http://feeds.feedburner.com/~r/joelambert/~4/rXrYGCpg4pE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.joelambert.co.uk/2012/09/28/formagent-data-collection-evolved/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.joelambert.co.uk/2012/09/28/formagent-data-collection-evolved/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=formagent-data-collection-evolved</feedburner:origLink></item>
		<item>
		<title>Using Android tablets to reduce the cost of large scale surveying</title>
		<link>http://feedproxy.google.com/~r/joelambert/~3/OXWe_tjak90/</link>
		<comments>http://blog.joelambert.co.uk/2012/07/05/using-android-tablets-to-reduce-the-cost-of-large-scale-surveying/#comments</comments>
		<pubDate>Thu, 05 Jul 2012 10:36:45 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.joelambert.co.uk/?p=1153</guid>
		<description><![CDATA[Rareloop teamed up with Gamos to deliver a powerful Android based digital survey for the highly respected UK NGO, Tearfund. Gamos have over 20 years experience providing research and detailed evaluation/analysis to the development sector. Given the enormous amounts of data collected and the complex statistical analysis required, partnering with Gamos ensured that both the [...]]]></description>
				<content:encoded><![CDATA[<p><img src="http://www.rareloop.com/css/img/casestudies/gamos/promo-image.png" alt="Gamos App" /></p>

<blockquote>
  <p>Rareloop teamed up with Gamos to deliver a powerful Android based digital survey for the highly respected UK NGO, Tearfund. Gamos have over 20 years experience providing research and detailed evaluation/analysis to the development sector. Given the enormous amounts of data collected and the complex statistical analysis required, partnering with Gamos ensured that both the right technical &amp; research expertise were available to deliver on the project&#8217;s needs.</p>
</blockquote>

<p>We&#8217;ve done work using Android tablets to perform surveys before, but never to this scale. Its also great to get the opportunity to work with NGO&#8217;s &amp; know that, even in a small non-direct way, our skill sets can help make a difference.</p>

<p>Head on over to the <a href="http://www.rareloop.com/casestudies/gamos">Rareloop website</a> for more information on the project and our technology platform.</p>

<p>If you&#8217;d like a demo of our technology, please don&#8217;t hesitate to <a href="http://rareloop.com/contact">get in contact</a>.</p>
<img src="http://feeds.feedburner.com/~r/joelambert/~4/OXWe_tjak90" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.joelambert.co.uk/2012/07/05/using-android-tablets-to-reduce-the-cost-of-large-scale-surveying/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.joelambert.co.uk/2012/07/05/using-android-tablets-to-reduce-the-cost-of-large-scale-surveying/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=using-android-tablets-to-reduce-the-cost-of-large-scale-surveying</feedburner:origLink></item>
		<item>
		<title>Digital brochure app for PlayBook – Clinic Beauty</title>
		<link>http://feedproxy.google.com/~r/joelambert/~3/xB9o-secql4/</link>
		<comments>http://blog.joelambert.co.uk/2012/07/02/digital-brochure-app-for-playbook-clinic-beauty/#comments</comments>
		<pubDate>Mon, 02 Jul 2012 07:57:46 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.joelambert.co.uk/?p=1150</guid>
		<description><![CDATA[Our latest app project at Rareloop has been a digital brochure for Southampton based Clinic Beauty. Written for the BlackBerry PlayBook (using HTML5/WebWorks) the app combines stunning brochure content and Rareloop&#8217;s own data collection framework to aid with the companies sales efforts. Taking cues from their work with HTML5 magazines for tablets, Rareloop created a [...]]]></description>
				<content:encoded><![CDATA[<p><img src="http://blog.joelambert.co.uk/wp-content/uploads/2012/07/clinic_beauty_app.png" alt="Clinic Beauty App" /></p>

<p>Our latest app project at Rareloop has been a digital brochure for Southampton based <a href="http://www.clinicbeauty.co.uk">Clinic Beauty</a>.</p>

<p>Written for the BlackBerry PlayBook (using HTML5/WebWorks) the app combines stunning brochure content and Rareloop&#8217;s own data collection framework to aid with the companies sales efforts.</p>

<blockquote>
  <p>Taking cues from their work with HTML5 magazines for tablets, Rareloop created a rich environment for showcasing Clinic Beauty&#8217;s work. Transitions and animations bring the content to life and a simple to use mobile optimised form enables data capture from potential clients: elegance and simplicity.</p>
</blockquote>

<p>Head on over to the <a href="http://rareloop.com/casestudies/clinicbeauty">Rareloop website</a> for more information and to see a video of the app in action.</p>
<img src="http://feeds.feedburner.com/~r/joelambert/~4/xB9o-secql4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.joelambert.co.uk/2012/07/02/digital-brochure-app-for-playbook-clinic-beauty/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.joelambert.co.uk/2012/07/02/digital-brochure-app-for-playbook-clinic-beauty/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=digital-brochure-app-for-playbook-clinic-beauty</feedburner:origLink></item>
		<item>
		<title>.net mag: Create a page turn effect with CSS3 [Read Online]</title>
		<link>http://feedproxy.google.com/~r/joelambert/~3/XzS4gRFXQnk/</link>
		<comments>http://blog.joelambert.co.uk/2012/06/11/net-mag-create-a-page-turn-effect-with-css3-read-online/#comments</comments>
		<pubDate>Mon, 11 Jun 2012 19:24:55 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.joelambert.co.uk/?p=1143</guid>
		<description><![CDATA[The tutorial I wrote for the January edition of .net mag is now available to read online. The tutorial shows how to make a page turn effect, similar to the one found in Flux, with JavaScript and CSS3. Enjoy!]]></description>
				<content:encoded><![CDATA[<p><img src="http://media.netmagazine.futurecdn.net/files/imagecache/featured_main/articles/tutorial/2012/05/halfway.jpg" alt="Page Turn Effect" /></p>

<p>The tutorial I wrote for the January edition of .net mag is now available to <a href="http://www.netmagazine.com/tutorials/create-page-turn-effect">read online</a>.</p>

<p>The tutorial shows how to make a page turn effect, similar to the one found in <a href="http://joelambert.co.uk/flux">Flux</a>, with JavaScript and CSS3.</p>

<p>Enjoy!</p>
<img src="http://feeds.feedburner.com/~r/joelambert/~4/XzS4gRFXQnk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.joelambert.co.uk/2012/06/11/net-mag-create-a-page-turn-effect-with-css3-read-online/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://blog.joelambert.co.uk/2012/06/11/net-mag-create-a-page-turn-effect-with-css3-read-online/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=net-mag-create-a-page-turn-effect-with-css3-read-online</feedburner:origLink></item>
		<item>
		<title>Installing Weinre on Mac OS X</title>
		<link>http://feedproxy.google.com/~r/joelambert/~3/evo5BrqaMOQ/</link>
		<comments>http://blog.joelambert.co.uk/2012/05/17/installing-weinre-on-mac-os-x/#comments</comments>
		<pubDate>Thu, 17 May 2012 08:45:35 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.joelambert.co.uk/?p=1136</guid>
		<description><![CDATA[If you haven&#8217;t checked out Weinre, you really ought to! Weinre is a debugger for web pages, like FireBug (for FireFox) and Web Inspector (for WebKit-based browsers), except it&#8217;s designed to work remotely, and in particular, to allow you debug web pages on a mobile device such as a phone. While not as good as [...]]]></description>
				<content:encoded><![CDATA[<p><img src="http://blog.joelambert.co.uk/wp-content/uploads/2012/05/weinre.jpg" alt="Weinre" /></p>

<p>If you haven&#8217;t checked out <a href="http://people.apache.org/~pmuellr/weinre/docs/latest/">Weinre</a>, you really ought to!</p>

<blockquote>
  <p>Weinre is a debugger for web pages, like FireBug (for FireFox) and Web Inspector (for WebKit-based browsers), except it&#8217;s designed to work remotely, and in particular, to allow you debug web pages on a mobile device such as a phone.</p>
</blockquote>

<p>While not as good as a full remote web inspector (like the one found on the PlayBook), its a great tool to help debug with mobile development. Weinre is part of the PhoneGap project and there is a publicly hosted version run as a service that can be found at <a href="http://debug.phonegap.com">debug.phonegap.com</a>. Unfortunately the hosted service appears to be having a few problems &amp; I&#8217;ve struggled to get local clients to connect, the good news is that Weinre can be installed and run locally.</p>

<p><span id="more-1136"></span></p>

<p>Weinre was originally written in Java but has recently been ported to Node.js, these instructions will be for installing the Node version.</p>

<h1>Install Homebrew</h1>

<p><a href="http://mxcl.github.com/homebrew/">Homebrew</a> is a package manager for the Mac and is what we&#8217;ll use to install Node. Full installation instructions can be found <a href="https://github.com/mxcl/homebrew/wiki/installation">here</a> (including the contents of the following script) but to jump right in run the following in Terminal:</p>

<pre><code>/usr/bin/ruby -e "$(/usr/bin/curl -fsSL https://raw.github.com/mxcl/homebrew/master/Library/Contributions/install_homebrew.rb)"
</code></pre>

<p><em>Note: You&#8217;ll need XCode installed to be able to get Homebrew working</em></p>

<h1>Install Node.js</h1>

<p>Now Homebrew is installed you should be able to get Node by running:</p>

<pre><code>brew install node
</code></pre>

<h1>Install NPM</h1>

<p>NPM is a package manager for Node.js and makes it easier to install/update/remove discrete Node modules. To install run:</p>

<pre><code>git clone http://github.com/isaacs/npm.git
cd npm
sudo make install
</code></pre>

<h1>Install Weinre</h1>

<p>You should now have everything ready to be able to install Weinre, to do so run:</p>

<pre><code>sudo npm -g install weinre
</code></pre>

<h1>Running Weinre</h1>

<p>Now Weinre is installed you can make a start using it locally. First you need to run the server:</p>

<pre><code>weinre
</code></pre>

<p>You should now be able to connect to <code>http://localhost:8080</code> from your desktop web browser. The page displayed will give instructions on usage.</p>

<h1>Working with Real Devices</h1>

<p>I recently wrote about my setup for <a href="http://blog.joelambert.co.uk/2012/05/10/testing-mobile-web-apps-on-real-devices/">testing web apps/sites on real mobile devices</a>. If you&#8217;re also using this kind of a setup then you likely want to be able to run Weinre on something other than <code>localhost</code>. This is easily done by providing an additional startup flag. To use the fictional <code>mywebapp.mobiledev.com</code> domain used in aforementioned blog post, you&#8217;d simply run:</p>

<pre><code>weinre --boundHost=mywebapp.mobiledev.com
</code></pre>

<p>You would then need to point your browser to <code>http://mywebapp.mobiledev.com:8080</code>.</p>
<img src="http://feeds.feedburner.com/~r/joelambert/~4/evo5BrqaMOQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.joelambert.co.uk/2012/05/17/installing-weinre-on-mac-os-x/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		<feedburner:origLink>http://blog.joelambert.co.uk/2012/05/17/installing-weinre-on-mac-os-x/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=installing-weinre-on-mac-os-x</feedburner:origLink></item>
		<item>
		<title>Testing mobile web apps on real devices</title>
		<link>http://feedproxy.google.com/~r/joelambert/~3/n63Z1_j2mO4/</link>
		<comments>http://blog.joelambert.co.uk/2012/05/10/testing-mobile-web-apps-on-real-devices/#comments</comments>
		<pubDate>Thu, 10 May 2012 09:16:45 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.joelambert.co.uk/?p=1127</guid>
		<description><![CDATA[When developing HTML5 web apps for mobiles and tablets, simulators and emulators can only take you so far. The sooner you can test on real devices the sooner you can catch real life usability issues and vendor implementation quirks. This post outlines a technique for rapidly testing code changes with real devices. My desktop development [...]]]></description>
				<content:encoded><![CDATA[<p><img src="http://blog.joelambert.co.uk/wp-content/uploads/2012/05/mobiles_and_tablets.jpg" alt="Mobiles and Tablets" /></p>

<p>When developing HTML5 web apps for mobiles and tablets, simulators and emulators can only take you so far. The sooner you can test on real devices the sooner you can catch real life usability issues and vendor implementation quirks.</p>

<p>This post outlines a technique for rapidly testing code changes with real devices.</p>

<p><span id="more-1127"></span></p>

<h1>My desktop development setup</h1>

<p>For more traditional desktop web apps my development environment is fairly well established. I run a local web server on my laptop (in my case Apache) which mirrors the setup on my deployment server. I have virtual hosts setup and use the <code>/etc/hosts</code> file of my laptop to ensure each virtual host resolves to my local machine.</p>

<p>So to create a new web app I just have to create a new folder in my sites directory, for example <code>mywebapp.home</code> and then create a corresponding record in my <code>hosts</code> file, e.g.</p>

<pre><code>127.0.0.1   mywebapp.home
</code></pre>

<p>This works because the <code>hosts</code> file is checked prior to my laptop making a DNS request further up the chain. So anytime an application on my laptop makes a request for <code>mydomain.home</code>, it is resolved to <code>127.0.0.1</code> aka <code>localhost</code>.</p>

<h1>Making this work for mobiles/tablets</h1>

<p>The above works well for testing in multiple desktop browsers (and the iOS Simulator) but for most emulators and on all physical devices it won&#8217;t work as the <code>hosts</code> file isn&#8217;t able to intercept the DNS requests.</p>

<p>The aim however is still to enable the devices to be able to view the content served from my laptop. <em>Larger businesses may run their own DNS setup locally which would negate this problem but for more agile working environments we need a different solution.</em></p>

<p>The easiest solution that I&#8217;ve found is to setup a single record on a remote DNS server that points to my local IP address. Then instead of using the <code>mydomain.home</code> nomenclature, switch to something that matches the DNS record you created. As an example, if I owned the domain <code>mobiledev.com</code> then I could setup a wildcard DNS A record as follows:</p>

<pre><code>*.mobiledev.com =&gt; 192.168.0.4
</code></pre>

<p>And the matching folder in my sites directory might be <code>mywebapp.mobiledev.com</code>.</p>

<p>Then, whenever a lookup for a subdomain is made it maps to the IP address for my laptop on the local network. Any device on the same network as my laptop is then able to resolve to the web server on my machine. <em>The crucial caveat here is that you must be on the same network for this to work</em>. You don&#8217;t need to open any ports or setup port forwarding on your router, you&#8217;re not allowing remote access to your development server, you&#8217;re just creating a replacement for your <code>/etc/hosts</code> file that can be read by other devices.</p>

<h1>Taking this mobile</h1>

<p>You&#8217;re more than likely able to setup your home/office network to always issue you with the same IP address, so whenever you&#8217;re on your own network the IP address will resolve to the correct machine.</p>

<p>But what if you travel for work or often work in a number of locations?</p>

<p>For this, Dynamic DNS is a great option. My DNS provider (<a href="https://cp.dnsmadeeasy.com/u/65726">DNS Made Easy</a>) offers this at no extra cost and they make an API available to programatically update your DNS record. Using the API I wrote a little PHP script that I run each time I arrive at a new location/network. The script works out my new local IP address and updates the DNS record accordingly.</p>

<p>If this would also be of you use to you, then you can <a href="https://gist.github.com/2642900">download the script from GitHub</a>.</p>

<p><em>Note: Its worth having a fairly short TTL (time to live) value for the dynamic DNS record so that changes propagate quickly. I&#8217;ve got mine set to about 3 minutes.</em></p>

<h1>Extras</h1>

<p>Once your devices are able to resolve a domain to your development machine you can start to take advantage of some of the other tools that are springing up around mobile web development:</p>

<ul>
<li><p><a href="http://debug.phonegap.com">Weinre (aka PhoneGap Debug)</a></p>

<blockquote>
  <p>&#8220;Weinre is a debugger for web pages, like FireBug (for FireFox) and Web Inspector (for WebKit-based browsers), except it&#8217;s designed to work remotely, and in particular, to allow you debug web pages on a mobile device such as a phone.&#8221; &#8211; <a href="http://people.apache.org/~pmuellr/weinre/docs/latest/">via docs</a></p>
</blockquote>

<p>You can download and run it locally or make use of the PhoneGap Debug service to get up and running as quickly as possible.</p></li>
<li><p><a href="http://labs.adobe.com/technologies/shadow/">Adobe Shadow</a></p>

<p>Shadow is a Chrome extension with companion apps for iOS and Android that essentially slaves all connected devices to the current Chrome window. This enables quick page reloading across many mobile devices from your desktop device. It also has a built in version of <a href="http://people.apache.org/~pmuellr/weinre/">Weinre</a>.</p></li>
</ul>
<img src="http://feeds.feedburner.com/~r/joelambert/~4/n63Z1_j2mO4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.joelambert.co.uk/2012/05/10/testing-mobile-web-apps-on-real-devices/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://blog.joelambert.co.uk/2012/05/10/testing-mobile-web-apps-on-real-devices/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=testing-mobile-web-apps-on-real-devices</feedburner:origLink></item>
		<item>
		<title>Flux Slider wins third place in Mozilla’s March Dev Derby</title>
		<link>http://feedproxy.google.com/~r/joelambert/~3/-HeY_Se9raU/</link>
		<comments>http://blog.joelambert.co.uk/2012/04/22/flux-slider-wins-third-place-in-mozillas-march-dev-derby/#comments</comments>
		<pubDate>Sun, 22 Apr 2012 06:12:30 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.joelambert.co.uk/?p=1123</guid>
		<description><![CDATA[Flux Slider has placed third in Mozilla&#8217;s March Dev Derby, which was all about CSS 3D Transforms! The quality of the competition was incredibly high so its a real honour to place in the top three. You can see my demo here, but its also really worth checking out some of the other submissions. Flux [...]]]></description>
				<content:encoded><![CDATA[<p><img src="http://blog.joelambert.co.uk/wp-content/uploads/2012/04/dev_derby_3rd_place.jpg" alt="Dev Derby 3rd Place" /></p>

<p>Flux Slider has placed third in Mozilla&#8217;s March Dev Derby, which was all about CSS 3D Transforms! The quality of the competition was incredibly high so its a real honour to place in the top three.</p>

<p>You can see <a href="https://developer.mozilla.org/en-US/demos/detail/3d-image-transitions">my demo here</a>, but its also <em>really</em> worth checking out some of the <a href="https://developer.mozilla.org/en-US/demos/devderby/2012/march/">other submissions</a>.</p>

<p><em>Flux is also a &#8216;<a href="https://developer.mozilla.org/en-US/demos/">Featured Demo</a>&#8216; at the moment!</em></p>

<p>Thanks again to the incredible <a href="http://ndesign-studio.com/">Nick La</a> for letting me use his awesome illustrations.</p>
<img src="http://feeds.feedburner.com/~r/joelambert/~4/-HeY_Se9raU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.joelambert.co.uk/2012/04/22/flux-slider-wins-third-place-in-mozillas-march-dev-derby/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		<feedburner:origLink>http://blog.joelambert.co.uk/2012/04/22/flux-slider-wins-third-place-in-mozillas-march-dev-derby/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=flux-slider-wins-third-place-in-mozillas-march-dev-derby</feedburner:origLink></item>
		<item>
		<title>Interview for Sandbox’s ‘Rockstar Developer’ feature</title>
		<link>http://feedproxy.google.com/~r/joelambert/~3/sknXSn9oqVM/</link>
		<comments>http://blog.joelambert.co.uk/2012/04/22/interview-for-sandboxs-rockstar-developer-feature/#comments</comments>
		<pubDate>Sun, 22 Apr 2012 05:33:49 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.joelambert.co.uk/?p=1118</guid>
		<description><![CDATA[Sandbox is a subscription only music industry marketing magazine by Music Ally. They&#8217;ve just started a regular feature called &#8216;Rockstar Developers&#8217; and they kindly ask to interview me for the latest edition (issue 58). So if you have a subscription and fancy hearing my thoughts on mobile development trends for 2012 head on over to [...]]]></description>
				<content:encoded><![CDATA[<p><img src="http://blog.joelambert.co.uk/wp-content/uploads/2012/04/sandbox_music_ally.jpg" alt="Sandbox (Music Ally)" /></p>

<p>Sandbox is a subscription only music industry marketing magazine by <a href="http://musically.com/">Music Ally</a>. They&#8217;ve just started a regular feature called &#8216;Rockstar Developers&#8217; and they kindly ask to interview me for the latest edition (issue 58).</p>

<p>So if you have a subscription and fancy hearing my thoughts on mobile development trends for 2012 head on over to the <a href="http://musically.com/">Music Ally website</a>.</p>

<p>Thanks for <a href="http://www.twitter.com/bettekoady">Sarah Lewin</a> for asking me to take part.</p>
<img src="http://feeds.feedburner.com/~r/joelambert/~4/sknXSn9oqVM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.joelambert.co.uk/2012/04/22/interview-for-sandboxs-rockstar-developer-feature/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.joelambert.co.uk/2012/04/22/interview-for-sandboxs-rockstar-developer-feature/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=interview-for-sandboxs-rockstar-developer-feature</feedburner:origLink></item>
	</channel>
</rss><!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Page Caching using apc
Database Caching 12/23 queries in 0.005 seconds using apc

 Served from: blog.joelambert.co.uk @ 2013-06-19 05:33:57 by W3 Total Cache -->
