<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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/"
	>

<channel>
	<title>Christophe Coenraets &#187; Android</title>
	<atom:link href="http://coenraets.org/blog/category/android/feed/" rel="self" type="application/rss+xml" />
	<link>http://coenraets.org/blog</link>
	<description>Web Platform, Cloud and Mobile Application Development</description>
	<lastBuildDate>Mon, 13 May 2013 16:05:20 +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>
		<item>
		<title>PhoneGap API Explorer for Android now on Google Play</title>
		<link>http://coenraets.org/blog/2012/09/phonegap-api-explorer-for-android-now-on-google-play/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=phonegap-api-explorer-for-android-now-on-google-play</link>
		<comments>http://coenraets.org/blog/2012/09/phonegap-api-explorer-for-android-now-on-google-play/#comments</comments>
		<pubDate>Wed, 12 Sep 2012 16:25:06 +0000</pubDate>
		<dc:creator>Christophe Coenraets</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[PhoneGap]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=3923</guid>
		<description><![CDATA[After I published the iOS version on the Apple App Store, a number of people asked for an Android version. I just published it on Google Play. PhoneGap API Explorer is an API reference application for PhoneGap device integration capabilities. The application clearly presents the syntax for each function, and allows you to provide values [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://coenraets.org/blog/wp-content/uploads/2012/09/Screenshot_2012-09-11-15-17-54.png"><img src="http://coenraets.org/blog/wp-content/uploads/2012/09/Screenshot_2012-09-11-15-17-54-1024x640.png" alt="" title="Screenshot_2012-09-11-15-17-54" width="660" height="412" class="aligncenter size-large wp-image-3944" /></a></p>
<p>After I published the <a href="http://itunes.apple.com/us/app/phonegap-api-explorer/id537825489?mt=8">iOS version</a> on the Apple App Store, a number of people asked for an Android version. I just published it on Google Play.<br />
<a href="http://play.google.com/store/apps/details?id=org.coenraets.phonegapexplorer"><br />
  <img alt="Get it on Google Play" src="http://www.android.com/images/brand/get_it_on_play_logo_large.png" /><br />
</a><br />
<span id="more-3923"></span><br />
PhoneGap API Explorer is an API reference application for PhoneGap device integration capabilities. The application clearly presents the syntax for each function, and allows you to provide values for the function’s arguments, invoke the function from within the application, and see immediate results. PhoneGap API Explorer provides a unique and interactive learning experience.</p>
<p>You can read more about the application and watch a video in my <a href="http://coenraets.org/blog/2012/08/new-phonegap-api-explorer-available-on-the-app-store/">initial post</a> about the iOS release.</p>
<h3>Source Code</h3>
<p>The iOS and the Android versions share the exact same code. Some platform specific CSS styles are dynamically applied through device detection to provide a natural experience on each platform. I will make the source code available on GitHub soon, ready for you to build on <a href="https://build.phonegap.com/">PhoneGap Build</a>. </p>
<p>Here are a few more screenshots:</p>
<p><a href="http://coenraets.org/blog/wp-content/uploads/2012/09/Screenshot_2012-09-11-15-15-47.png"><img src="http://coenraets.org/blog/wp-content/uploads/2012/09/Screenshot_2012-09-11-15-15-47-1024x640.png" alt="" title="Screenshot_2012-09-11-15-15-47" width="660" height="412" class="aligncenter size-large wp-image-3949" /></a></p>
<p><a href="http://coenraets.org/blog/wp-content/uploads/2012/09/Screenshot_2012-09-11-15-19-41.png"><img src="http://coenraets.org/blog/wp-content/uploads/2012/09/Screenshot_2012-09-11-15-19-41-1024x640.png" alt="" title="Screenshot_2012-09-11-15-19-41" width="660" height="412" class="aligncenter size-large wp-image-3954" /></a><a href="http://coenraets.org/blog/wp-content/uploads/2012/09/Screenshot_2012-09-11-15-17-09.png"><img src="http://coenraets.org/blog/wp-content/uploads/2012/09/Screenshot_2012-09-11-15-17-09-1024x640.png" alt="" title="Screenshot_2012-09-11-15-17-09" width="660" height="412" class="aligncenter size-large wp-image-3950" /></a><a href="http://coenraets.org/blog/wp-content/uploads/2012/09/Screenshot_2012-09-11-15-15-47.png"><img src="http://coenraets.org/blog/wp-content/uploads/2012/09/Screenshot_2012-09-11-15-15-47-1024x640.png" alt="" title="Screenshot_2012-09-11-15-15-47" width="660" height="412" class="aligncenter size-large wp-image-3949" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2012/09/phonegap-api-explorer-for-android-now-on-google-play/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Simple Offline Data Synchronization for Mobile Web and PhoneGap Applications</title>
		<link>http://coenraets.org/blog/2012/05/simple-offline-data-synchronization-for-mobile-web-and-phonegap-applications/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=simple-offline-data-synchronization-for-mobile-web-and-phonegap-applications</link>
		<comments>http://coenraets.org/blog/2012/05/simple-offline-data-synchronization-for-mobile-web-and-phonegap-applications/#comments</comments>
		<pubDate>Wed, 16 May 2012 19:36:45 +0000</pubDate>
		<dc:creator>Christophe Coenraets</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Backbone.js]]></category>
		<category><![CDATA[HTML 5]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[PhoneGap]]></category>
		<category><![CDATA[Twitter Bootstrap]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=3652</guid>
		<description><![CDATA[Being able to work offline is an expected feature of mobile applications. For data-driven applications, it means that you &#8212; the developer &#8212; will have to store (a subset of) your application data locally, and implement a data synchronization mechanism that keeps your local and server data in sync. In this article, I describe a [...]]]></description>
				<content:encoded><![CDATA[<p>Being able to work offline is an expected feature of mobile applications. For data-driven applications, it means that you &#8212; the developer &#8212; will have to store (a subset of) your application data locally, and implement a data synchronization mechanism that keeps your local and server data in sync.</p>
<p>In this article, I describe a simple data synchronization strategy that uses the device&#8217;s (or browser&#8217;s) SQLite database. The implementation currently leverages the Web SQL API (even though the W3C is no longer actively maintaining the spec) because both iOS and Android support it, but they don&#8217;t support IndexedDB, the official alternative. However, the API described below &#8212; getLastSync(), getChanges(), applyChanges() &#8212; defines a generic synchronization contract, and the solution can be expanded and made &#8220;pluggable&#8221;: You could create different synchronization objects, each providing a different implementation of these methods. You could then choose which object to plug in based on the context and the platform your application is running on.</p>
<h3>Try it in the Playground</h3>
<p><a href="http://coenraets.org/offline-sync/client-app"><img src="http://coenraets.org/blog/wp-content/uploads/2012/05/Screen-Shot-2012-05-16-at-21.jpg" alt="" title="Screen Shot 2012-05-16 at 2" width="640" height="760" class="aligncenter size-full wp-image-3734" /></a><br />
<span id="more-3652"></span><br />
Before looking at the code, you can try some offline syncing in this a hosted playground:</p>
<ol>
<li>Open the <a href="http://coenraets.org/offline-sync/client-app">Offline Client Playground</a> in Chrome or Safari (they both support Web SQL).</li>
<li>Click the Synchronize button.</li>
<li>Look at the log (the textarea in the middle of the screen): Because it&#8217;s the first time you use the application, all the employees have been downloaded from the server and inserted in your local SQLite database.</li>
<li>Clear the log, click the Synchronize button, and look at the log again: because you now have an up-to-date local version of the data, the server didn&#8217;t return any change and your local database remains unchanged.</li>
<li>In another tab, open the <a href="http://coenraets.org/offline-sync/server-app">Server Admin PlayGround</a>.</li>
<li>Modify an existing employee and click Save. (Don&#8217;t worry, it&#8217;s using your own session-based data set).</li>
<li>Go back to the Offline Client tab, click Synchronize, and notice that the server returned one change,  and that it was applied to your local database.</li>
<li>Go back to the Server Admin tab and modify (create, update, delete) other employees. Switch back to the Offline Client tab, click Synchronize, and see how these changes are applied to your local database.</li>
<li>You can also use the Resources Tab in the Chrome Developer Tools to inspect your local database.</li>
</ol>
<h3>Server API</h3>
<p>The only piece of infrastructure you need at the server side is an API that returns the items that have changed (created, updated, or deleted) since a specific moment in time expressed as a timestamp. </p>
<p>Here is the RESTful API call used in my application:</p>
<p><a href="http://coenraets.org/offline-sync/api/employees?modifiedSince=2012-03-01 10:20:56">http://coenraets.org/offline-sync/api/employees?modifiedSince=2012-03-01 10:20:56</a></p>
<p>The format of the data returned by the server is up to you and is part of the contract between the client and the server. In this application, the server returns the changes as an array of JSON objects. The server-side technology (RoR, PHP, Java, .NET, &#8230;) and database system (SQL, NoSQL, &#8230;) you use to generate the list of changes is also totally up to you. I provide a simple PHP implementation as part of the source code. That implementation manages a session-based data set that provides an isolated and transient playground. In a real-life application, you&#8217;d obviously get the data from some sort of database.</p>
<h3>Client API</h3>
<p>At the client side, our synchronization API consists of three methods.</p>
<h4>getLastSync()</h4>
<p>A method that returns a timestamp to be used as the query parameter for the next synchronization request. A common practice is to persist a timestamp after each synchronization request. But things can go wrong and the timestamp itself can get out-of-sync. I prefer to &#8220;recalculate&#8221; the lastSync timestamp before each synchronization request.   </p>
<pre class="brush: jscript; title: ; notranslate">
getLastSync: function(callback) {
    this.db.transaction(
        function(tx) {
            var sql = &quot;SELECT MAX(lastModified) as lastSync FROM employee&quot;;
            tx.executeSql(sql, this.txErrorHandler,
                function(tx, results) {
                    var lastSync = results.rows.item(0).lastSync;
                    callback(lastSync);
                }
            );
        }
    );
}
</pre>
<h4>getChanges()</h4>
<p>This is a wrapper around an Ajax call to the server-side API that returns the items that have changed (created, updated, or deleted) since a specific moment in time defined in the modifiedSince parameter. </p>
<pre class="brush: jscript; title: ; notranslate">
getChanges: function(syncURL, modifiedSince, callback) {

    $.ajax({
        url: syncURL,
        data: {modifiedSince: modifiedSince},
        dataType:&quot;json&quot;,
        success:function (changes) {
            callback(changes);
        },
        error: function(model, response) {
            alert(response.responseText);
        }
    });

}
</pre>
<h4>applyChanges()</h4>
<p>A method that persists the changes in your local data store. Notice that SQLite supports a convenient &#8220;INSERT OR REPLACE&#8221; statement so that you don&#8217;t have to determine if you are dealing with a new or existing employee before persisting it.</p>
<pre class="brush: jscript; title: ; notranslate">
applyChanges: function(employees, callback) {
    this.db.transaction(
        function(tx) {
            var l = employees.length;
            var sql =
                &quot;INSERT OR REPLACE INTO employee (id, firstName, lastName, title, officePhone, deleted, lastModified) &quot; +
                &quot;VALUES (?, ?, ?, ?, ?, ?, ?)&quot;;
            var e;
            for (var i = 0; i &lt; l; i++) {
                e = employees[i];
                var params = [e.id, e.firstName, e.lastName, e.title, e.officePhone, e.deleted, e.lastModified];
                tx.executeSql(sql, params);
            }
        },
        this.txErrorHandler,
        function(tx) {
            callback();
        }
    );
}
</pre>
<h3>Synchronization Logic</h3>
<p>With these server and client APIs in place, you can choreograph a data synchronization process as follows: </p>
<pre class="brush: jscript; title: ; notranslate">
sync: function(syncURL, callback) {

    var self = this;
    this.getLastSync(function(lastSync){
        self.getChanges(syncURL, lastSync,
            function (changes) {
                self.applyChanges(changes, callback);
            }
        );
    });

}
</pre>
<h3>Final Notes</h3>
<ul>
<li>This solution currently supports unidirectional (server to client) data synchronization. It could easily be expanded to support bidirectional synchronization.</li>
<li>This solution currently implements &#8220;logical deletes&#8221;: items are not physically deleted from the table, but the value of their &#8220;deleted&#8221; column is set to true.</li>
<li>As mentioned above, you could replace the Web SQL implementation with another data access strategy. For example, take a look at <a href="http://brian.io/lawnchair/">Brian Leroux&#8217; Lawnchair</a> for another local persistence solution.</li>
</ul>
<h3>Source Code</h3>
<p>The source code is available in <a href="https://github.com/ccoenraets/offline-sync">this GitHub repository</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2012/05/simple-offline-data-synchronization-for-mobile-web-and-phonegap-applications/feed/</wfw:commentRss>
		<slash:comments>37</slash:comments>
		</item>
		<item>
		<title>Sample Mobile App with Backbone.js, PhoneGap, and a Local Database</title>
		<link>http://coenraets.org/blog/2012/02/sample-mobile-app-with-backbone-js-phonegap-and-a-local-database/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sample-mobile-app-with-backbone-js-phonegap-and-a-local-database</link>
		<comments>http://coenraets.org/blog/2012/02/sample-mobile-app-with-backbone-js-phonegap-and-a-local-database/#comments</comments>
		<pubDate>Tue, 07 Feb 2012 16:29:39 +0000</pubDate>
		<dc:creator>Christophe Coenraets</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Backbone.js]]></category>
		<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[HTML 5]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PhoneGap]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=3044</guid>
		<description><![CDATA[In my previous post, I shared a simple Wine Cellar application built with Backbone.js and packaged as a mobile app with PhoneGap. That version of the application gets its data from a set of RESTful services, which means that you can only use it while online. In this post, we explore an offline version of [...]]]></description>
				<content:encoded><![CDATA[<p>In my <a href="http://coenraets.org/blog/2012/02/sample-mobile-app-with-backbone-js-and-phonegap/">previous post</a>, I shared a simple Wine Cellar application built with <a href="http://documentcloud.github.com/backbone/">Backbone.js</a> and packaged as a mobile app with <a href="http://phonegap.com/">PhoneGap</a>. That version of the application gets its data from a set of RESTful services, which means that you can only use it while online.</p>
<p>In this post, we explore an offline version of the same application: this new version gets its data from your device&#8217;s local database using the PhoneGap SQL database API. </p>
<p>By default, Backbone.js Models access their data using RESTful services defined by the Models &#8220;url&#8221; and &#8220;urlRoot&#8221; attributes. But Backbone.js also makes it easy and elegant to change your Models data access mechanism: All you have to do is override the Backbone.sync method. From the Backbone.js <a href="http://documentcloud.github.com/backbone/#Sync">documentation</a>:</p>
<blockquote><p>Backbone.sync is the function that Backbone calls every time it attempts to read or save a model to the server. By default, it uses (jQuery/Zepto).ajax to make a RESTful JSON request. You can override it in order to use a different persistence strategy, such as WebSockets, XML transport, or Local Storage.</p></blockquote>
<p>The documentation includes a <a href="http://documentcloud.github.com/backbone/docs/backbone-localstorage.html">useful example</a> that shows how to replace the default Backbone.sync implementation with localStorage-based persistence where models are saved into JSON objects.  </p>
<p>In our application, we will replace the default Backbone.sync implementation with SQL-based persistence using the device&#8217;s local database.<br />
<span id="more-3044"></span><br />
First, we create a data access object that encapsulates the logic to read (find), create, update, and delete wines. This simple application is read-only and only needs to retrieve collections. So, I only implemented the findAll() method and stubbed the other methods (find, create, update, destroy). WineDAO also has a &#8220;populate&#8221; function to populate the wine table with sample data. </p>
<pre class="brush: jscript; title: ; notranslate">
window.WineDAO = function (db) {
    this.db = db;
};

_.extend(window.WineDAO.prototype, {

    findAll:function (callback) {
        this.db.transaction(
            function (tx) {
                var sql = &quot;SELECT * FROM wine ORDER BY name&quot;;
                tx.executeSql(sql, [], function (tx, results) {
                    var len = results.rows.length;
                    var wines = [];
                    for (var i = 0; i &lt; len; i++) {
                        wines[i] = results.rows.item(i);
                    }
                    callback(wines);
                });
            },
            function (tx, error) {
                alert(&quot;Transaction Error: &quot; + error);
            }
        );
    },

    create:function (model, callback) {
//        TODO: Implement
    },

    update:function (model, callback) {
//        TODO: Implement
    },

    destroy:function (model, callback) {
//        TODO: Implement
    },

    find:function (model, callback) {
//        TODO: Implement
    },

//  Populate Wine table with sample data
    populate:function (callback) {
        this.db.transaction(
            function (tx) {
                console.log('Dropping WINE table');
                tx.executeSql('DROP TABLE IF EXISTS wine');
                var sql =
                    &quot;CREATE TABLE IF NOT EXISTS wine ( &quot; +
                        &quot;id INTEGER PRIMARY KEY AUTOINCREMENT, &quot; +
                        &quot;name VARCHAR(50), &quot; +
                        &quot;year VARCHAR(50), &quot; +
                        &quot;grapes VARCHAR(50), &quot; +
                        &quot;country VARCHAR(50), &quot; +
                        &quot;region VARCHAR(50), &quot; +
                        &quot;description TEXT, &quot; +
                        &quot;picture VARCHAR(200))&quot;;
                console.log('Creating WINE table');
                tx.executeSql(sql);
                console.log('Inserting wines');
                tx.executeSql(&quot;INSERT INTO wine VALUES (1,'CHATEAU DE SAINT COSME','2009','Grenache / Syrah','France','Southern Rhone / Gigondas','The aromas of fruit and spice give one a hint of the light drinkability of this lovely wine, which makes an excellent complement to fish dishes.','saint_cosme.jpg')&quot;);
                tx.executeSql(&quot;INSERT INTO wine VALUES (2,'LAN RIOJA CRIANZA','2006','Tempranillo','Spain','Rioja','A resurgence of interest in boutique vineyards has opened the door for this excellent foray into the dessert wine market. Light and bouncy, with a hint of black truffle, this wine will not fail to tickle the taste buds.','lan_rioja.jpg')&quot;);
                tx.executeSql(&quot;INSERT INTO wine VALUES (3,'MARGERUM SYBARITE','2010','Sauvignon Blanc','USA','California Central Cosat','The cache of a fine Cabernet in ones wine cellar can now be replaced with a childishly playful wine bubbling over with tempting tastes of black cherry and licorice. This is a taste sure to transport you back in time.','margerum.jpg')&quot;);
                tx.executeSql(&quot;INSERT INTO wine VALUES (4,'OWEN ROE \&quot;EX UMBRIS\&quot;','2009','Syrah','USA','Washington','A one-two punch of black pepper and jalapeno will send your senses reeling, as the orange essence snaps you back to reality. Do not miss this award-winning taste sensation.','ex_umbris.jpg')&quot;);
                tx.executeSql(&quot;INSERT INTO wine VALUES (5,'REX HILL','2009','Pinot Noir','USA','Oregon','One cannot doubt that this will be the wine served at the Hollywood award shows, because it has undeniable star power. Be the first to catch the debut that everyone will be talking about tomorrow.','rex_hill.jpg')&quot;);
                tx.executeSql(&quot;INSERT INTO wine VALUES (6,'VITICCIO CLASSICO RISERVA','2007','Sangiovese Merlot','Italy','Tuscany','Though soft and rounded in texture, the body of this wine is full and rich and oh-so-appealing. This delivery is even more impressive when one takes note of the tender tannins that leave the taste buds wholly satisfied.','viticcio.jpg')&quot;);
                tx.executeSql(&quot;INSERT INTO wine VALUES (7,'CHATEAU LE DOYENNE','2005','Merlot','France','Bordeaux','Though dense and chewy, this wine does not overpower with its finely balanced depth and structure. It is a truly luxurious experience for the senses.','le_doyenne.jpg')&quot;);
                tx.executeSql(&quot;INSERT INTO wine VALUES (8,'DOMAINE DU BOUSCAT','2009','Merlot','France','Bordeaux','The light golden color of this wine belies the bright flavor it holds. A true summer wine, it begs for a picnic lunch in a sun-soaked vineyard.','bouscat.jpg')&quot;);
                tx.executeSql(&quot;INSERT INTO wine VALUES (9,'BLOCK NINE','2009','Pinot Noir','USA','California','With hints of ginger and spice, this wine makes an excellent complement to light appetizer and dessert fare for a holiday gathering.','block_nine.jpg')&quot;);
                tx.executeSql(&quot;INSERT INTO wine VALUES (10,'DOMAINE SERENE','2007','Pinot Noir','USA','Oregon','Though subtle in its complexities, this wine is sure to please a wide range of enthusiasts. Notes of pomegranate will delight as the nutty finish completes the picture of a fine sipping experience.','domaine_serene.jpg')&quot;);
                tx.executeSql(&quot;INSERT INTO wine VALUES (11,'BODEGA LURTON','2011','Pinot Gris','Argentina','Mendoza','Solid notes of black currant blended with a light citrus make this wine an easy pour for varied palates.','bodega_lurton.jpg')&quot;);
                tx.executeSql(&quot;INSERT INTO wine VALUES (12,'LES MORIZOTTES','2009','Chardonnay','France','Burgundy','Breaking the mold of the classics, this offering will surprise and undoubtedly get tongues wagging with the hints of coffee and tobacco in perfect alignment with more traditional notes. Breaking the mold of the classics, this offering will surprise and undoubtedly get tongues wagging with the hints of coffee and tobacco in perfect alignment with more traditional notes. Sure to please the late-night crowd with the slight jolt of adrenaline it brings.','morizottes.jpg')&quot;);
            },
            function (tx, error) {
                alert('Transaction error ' + error);
            },
            function (tx) {
                callback();
            }
        );
    }
});
</pre>
<p>I then added a &#8220;dao&#8221; attribute to the Models to specify which data object should be used to access their underlying data.</p>
<pre class="brush: jscript; title: ; notranslate">
window.Wine = Backbone.Model.extend({
	urlRoot: &quot;http://coenraets.org/backbone-cellar/part1/api/wines&quot;,
    dao: WineDAO
});

window.WineCollection = Backbone.Collection.extend({
	model: Wine,
	url: &quot;http://coenraets.org/backbone-cellar/part1/api/wines&quot;,
    dao: WineDAO
});
</pre>
<p>NOTE: The application doesn&#8217;t need the url and urlRoot attributes anymore, but you can imagine a more sophisticated version of the app that would work with the RESTful services while online and fall back to the local database while offline. </p>
<p>With that infrastructure in place, we can now override Backbone.sync as follows:</p>
<pre class="brush: jscript; title: ; notranslate">
Backbone.sync = function (method, model, options) {

    var dao = new model.dao(window.db);

    switch (method) {
        case &quot;read&quot;:
            if (model.id)
                dao.find(model, function (data) {
                    options.success(data);
                });
            else
                dao.findAll(function (data) {
                    options.success(data);
                });
            break;
        case &quot;create&quot;:
            dao.create(model, function (data) {
                options.success(data);
            });
            break;
        case &quot;update&quot;:
            dao.update(model, function (data) {
                options.success(data);
            });
            break;
        case &quot;delete&quot;:
            dao.destroy(model, function (data) {
                options.success(data);
            });
            break;
    }

};
</pre>
<p>And finally, we need to open the database (and populate it with sample data) at startup:</p>
<pre class="brush: jscript; title: ; notranslate">
window.startApp = function () {
    var self = this;
    window.db = window.openDatabase(&quot;WineCellar&quot;, &quot;1.0&quot;, &quot;WineCellar Demo DB&quot;, 200000);
    var wineDAO = new WineDAO(self.db);
    wineDAO.populate(function () {
        this.templateLoader.load(['wine-list', 'wine-details', 'wine-list-item'], function () {
            self.app = new AppRouter();
            Backbone.history.start();
        });
    })
}
</pre>
<h3>Download</h3>
<p>I added this version of the application to the backbone-cellar GitHub repository <a href="https://github.com/ccoenraets/backbone-cellar/tree/master/mobile/offline">here</a>. </p>
<p>NOTE: You will have to create a PhoneGap project (see <a href="http://phonegap.com/start">documentation</a> here) or use the <a href="https://build.phonegap.com/">hosted build service</a> to package the code as a native app for different mobile platforms.</p>
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2012/02/sample-mobile-app-with-backbone-js-phonegap-and-a-local-database/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Sample Mobile App with Backbone.js and PhoneGap</title>
		<link>http://coenraets.org/blog/2012/02/sample-mobile-app-with-backbone-js-and-phonegap/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sample-mobile-app-with-backbone-js-and-phonegap</link>
		<comments>http://coenraets.org/blog/2012/02/sample-mobile-app-with-backbone-js-and-phonegap/#comments</comments>
		<pubDate>Mon, 06 Feb 2012 17:27:53 +0000</pubDate>
		<dc:creator>Christophe Coenraets</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Backbone.js]]></category>
		<category><![CDATA[HTML 5]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[PhoneGap]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=2987</guid>
		<description><![CDATA[I recently blogged a tutorial (part 1, part 2, part 3, and postface) that takes you through the process of building a CRUD application using HTML and the Backbone.js framework. The application used in this tutorial is a Wine Cellar management app, and I thought it would be fun to create a Mobile version using [...]]]></description>
				<content:encoded><![CDATA[<p>I recently blogged a tutorial (<a href="http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-1-getting-started/">part 1</a>, <a href="http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-2-crud/">part 2</a>, <a href="http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-3-deep-linking-and-application-states/">part 3</a>, and <a href="http://coenraets.org/blog/2012/01/backbone-js-lessons-learned-and-improved-sample-app/">postface</a>) that takes you through the process of building a CRUD application using HTML and the <a href="http://documentcloud.github.com/backbone/">Backbone.js</a> framework. The application used in this tutorial is a Wine Cellar management app, and I thought it would be fun to create a Mobile version using <a href="http://phonegap.com/">PhoneGap</a>.</p>
<p>PhoneGap &#8212; if you are not familiar with it &#8212; is an open source platform that allows you develop cross-platform Mobile applications using HTML and JavaScript. Specifically, it allows you to:</p>
<ol>
<li>Package an HTML application as a native app on all the key mobile platforms (iOS, Android, BlackBerry, Windows Phone, WebOS, Symbian, Bada).</li>
<li>Access your device capabilities (Camera, GPS, database, accelerometer, etc) using a cross-platform JavaScript API.</li>
</ol>
<p>Backbone.js is a great framework to give structure to your web application regardless of where it is running: in a traditional Web Browser, or as an app packaged with PhoneGap. </p>
<p>So, here is the app&#8230;<br />
<span id="more-2987"></span></p>
<p>
<img src="http://coenraets.org/blog/wp-content/uploads/2012/02/wine4.jpg" alt="" title="wine4" width="300" height="450" style="float: left;" /></p>
<p><img src="http://coenraets.org/blog/wp-content/uploads/2012/02/wine3.jpg" alt="" title="wine3" width="300" height="450" style="float: right;"/>
</p>
<p style="clear: both;">&nbsp;</p>
<p>The UI is intentionally plain to keep the focus on the architectural framework. This is a simple &#8216;consumer&#8217; version of the application: It allows you to look for wines in your Wine Cellar. The tutorial application mentioned above is an &#8216;admin&#8217; version: You can create, update, delete wines in your Wine Cellar. Most of the code is shared between the Mobile &#8216;consumer&#8217; version and the browser-based &#8216;admin&#8217; version.</p>
<p>In this version, the application gets the data from RESTful services hosted on my server. In my next post, I will provide another version of the application that gets the data using a local database on your device.</p>
<h3>Download</h3>
<p>I added the source code for the mobile application to the <a href="https://github.com/ccoenraets/backbone-cellar">backbone-cellar GitHub repository</a>. You can download the zip file <a href="https://github.com/ccoenraets/backbone-cellar/zipball/master">here</a>. For your convenience, I created an <a href="https://github.com/ccoenraets/backbone-cellar/tree/master/mobile/ios">iOS directory</a> with the Xcode project and an <a href="https://github.com/ccoenraets/backbone-cellar/tree/master/mobile/android">Android directory</a> with the Eclipse project. The core application is in the www directory (<a href="https://github.com/ccoenraets/backbone-cellar/tree/master/mobile/ios/WineCellar/www">iOS</a> and <a href="https://github.com/ccoenraets/backbone-cellar/tree/master/mobile/android/BackboneCellarAndroid/assets/www">android</a>) and it is the same code for both iOS and Android.</p>
<p>If you want to run the application on your Android device without installing the project, you can also download the apk file available in the <a href="https://github.com/ccoenraets/backbone-cellar/tree/master/mobile/android/BackboneCellarAndroid/bin">bin directory</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2012/02/sample-mobile-app-with-backbone-js-and-phonegap/feed/</wfw:commentRss>
		<slash:comments>32</slash:comments>
		</item>
		<item>
		<title>jQuery Mobile &quot;Getting Started&quot; Application</title>
		<link>http://coenraets.org/blog/2011/11/jquery-mobile-getting-started-application/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=jquery-mobile-getting-started-application</link>
		<comments>http://coenraets.org/blog/2011/11/jquery-mobile-getting-started-application/#comments</comments>
		<pubDate>Wed, 02 Nov 2011 18:58:30 +0000</pubDate>
		<dc:creator>Christophe Coenraets</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[JQuery Mobile]]></category>
		<category><![CDATA[PhoneGap]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=1972</guid>
		<description><![CDATA[A couple of weeks ago, I shared an Employee Directory sample application built with jQuery Mobile and PhoneGap. That application was implemented &#8220;Ajax-style&#8221;, keeping the UI and the data access code cleanly separated. In other words: no server code intermingled in the HTML markup. A number of people have asked for a similar example using [...]]]></description>
				<content:encoded><![CDATA[<p>A couple of weeks ago, I shared an Employee Directory <a href="http://coenraets.org/blog/2011/10/sample-application-with-jquery-mobile-and-phonegap/">sample application</a> built with jQuery Mobile and PhoneGap. That application was implemented &#8220;Ajax-style&#8221;, keeping the UI and the data access code cleanly separated. In other words: no server code intermingled in the HTML markup.</p>
<p>A number of people have asked for a similar example using a &#8220;classic&#8221; (non-Ajax) implementation where pages (markup + data) are entirely built at the server-side before being delivered to the client.</p>
<p>So, here is simpler version of the same application built &#8220;sans Ajax&#8221;. I used PHP in this version, but you can of course use your favorite server-side technology (Java, .NET, CF, RoR, etc).</p>
<p><span id="more-1972"></span></p>
<h4>Run the application</h4>
<p>Click <a href="http://www.coenraets.org/apps/directory/jqmphp/">here</a> to run the application.</p>
<p><a href="http://coenraets.org/apps/directory/jqmphp"><img src="http://coenraets.org/blog/wp-content/uploads/2011/10/directory11.png" alt="" title="directory1" width="300" height="500" class="alignnone size-full wp-image-1823" style="border: 1px solid #555555;float:left;" /></a></p>
<p><a href="http://coenraets.org/apps/directory/jqmphp"><img src="http://coenraets.org/blog/wp-content/uploads/2011/10/directory21.png" alt="" title="directory2" width="300" height="500" class="aligntop size-full wp-image-1824" style="border: 1px solid #555555;margin-left:20px;margin-top:-20px;padding-top:0px;" /></a></p>
<h4>Download the source code</h4>
<p>Click <a href="http://www.coenraets.org/apps/directory/jqmphp/EmployeeDirectoryJQMPHP.zip">here</a> to download the source code. Edit config.php to make sure it matches your database configuration.</p>
<h4>Running the Application with PhoneGap</h4>
<p>With this implementation, the application files can&#8217;t be installed locally on the device since pages are created dynamically on the server side. So, in the PhoneGap application, instead of loading a local HTML file, you point to a file hosted on your web server. Here is the code for my main Android activity. Greg has a <a href="http://gregsramblings.com/2011/10/12/stupid-phonegap-tricks-loading-external-content/">great post</a> on this topic (I haven&#8217;t tried it on iOS myself yet).</p>
<pre class="brush: java; title: ; notranslate">
package org.coenraets.directory;

import com.phonegap.DroidGap;

import android.os.Bundle;

public class EmployeeDirectoryJQMPHPActivity extends DroidGap {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        super.setBooleanProperty(&quot;loadInWebView&quot;, true);
        super.loadUrl(
            &quot;http://coenraets.org/apps/directory/jqmphp/index.php&quot;);
    }
}
</pre>
<p>&nbsp;</p>
<h4>Summary</h4>
<p>To recap the difference between the two versions: In the original (Ajax) version, the server side code exposes a set of services consumed by an HTML/JS client. In this new (non-Ajax) version, the server-side code returns fully assembled HTML pages (markup + data).</p>
<p>The original (Ajax) version has many benefits:</p>
<ol>
<li>Your UI code doesn&#8217;t have a dependency on a specific server-side technology.</li>
<li>Your data access logic doesn&#8217;t have a dependency on a specific UI technology.</li>
<li>You can manipulate the data on the client side (i.e. sort using different criteria) without requiring a server roundtrip.</li>
<li>That decoupled architecture also works offline when working with a local database.</li>
</ol>
<p>When none of the items above is a requirement of your application, the &#8220;non-Ajax&#8221; approach may work too and may even have some benefits. In particular, it makes the jQuery Mobile page navigation model easier to handle.</p>
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2011/11/jquery-mobile-getting-started-application/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Flex / Spring Mobile Test Drive: Learn the Best Way to Build Java-Backed iOS, Android and PlayBook Apps</title>
		<link>http://coenraets.org/blog/2011/08/flex-spring-mobile-test-drive-learn-the-best-way-to-build-java-backed-ios-android-and-playbook-apps/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=flex-spring-mobile-test-drive-learn-the-best-way-to-build-java-backed-ios-android-and-playbook-apps</link>
		<comments>http://coenraets.org/blog/2011/08/flex-spring-mobile-test-drive-learn-the-best-way-to-build-java-backed-ios-android-and-playbook-apps/#comments</comments>
		<pubDate>Thu, 25 Aug 2011 13:50:13 +0000</pubDate>
		<dc:creator>Christophe Coenraets</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[PlayBook]]></category>
		<category><![CDATA[Spring]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=1700</guid>
		<description><![CDATA[Flex is a powerful application framework for building first-class mobile applications for iOS, Android, and the BlackBerry PlayBook using a single programming model, a single tool, and a single code base. If you are a Java developer, the Flex programming model is also easy to master because it is syntactically very close to Java. The [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://coenraets.org/blog/wp-content/uploads/2011/08/flex-spring-mobile1.jpg"><img src="http://coenraets.org/blog/wp-content/uploads/2011/08/flex-spring-mobile1.jpg" alt="" title="flex-spring-mobile" width="650" height="250" class="alignnone size-full wp-image-1724" /></a></p>
<p>Flex is a powerful application framework for building first-class mobile applications for iOS, Android, and the BlackBerry PlayBook using a single programming model, a single tool, and a single code base.</p>
<p>If you are a Java developer, the Flex programming model is also easy to master because it is syntactically very close to Java. The Flex IDE (Flash Builder) is a plugin on top of Eclipse, which means that you can write, debug, and profile your client and server code in the same development environment.</p>
<p>You can also easily integrate Flex applications with a Java back end using the Remoting and Messaging services provided by <a href="http://opensource.adobe.com/wiki/display/blazeds/BlazeDS">BlazeDS</a> (open source) or <a href="http://www.adobe.com/products/livecycle/dataservices/">LCDS</a> (commercial license). For Spring developers, the integration is even easier and more powerful using the <a href="http://www.springsource.org/spring-flex">Spring/BlazeDS integration project</a>, which makes the Flex and Spring combination the best way to build cross-platform iOS, Android, and PlayBook applications with a Java back end.<br />
<span id="more-1700"></span><br />
I put together a new &#8220;Flex / Spring Mobile Test Drive” to help developers get started building these applications. The Test Drive consists of a web application with BlazeDS and the “Spring/BlazeDS integration” preconfigured and ready to use. It also includes two sample mobile applications running “out-of-the-box”: An Employee Directory and a Trader Desktop. The Employee directory demonstrates how to use Remoting to access Spring services. The Mobile Trader focuses on the Messaging integration: It shows a Spring component pushing real-time market data updates to a Flex applications.</p>
<p><img src="http://coenraets.org/blog/wp-content/uploads/2011/08/github1.gif" alt="" title="github" width="56" height="49" /></a>The project is hosted on GitHub: <a href="https://github.com/ccoenraets/flex-spring-mobile-testdrive">https://github.com/ccoenraets/flex-spring-mobile-testdrive</a></p>
<h3>Installation</h3>
<ol>
<li>Deploy flex-spring-mobile.war to your app server.</li>
<li>Import the projects into Flash Builder: (If you don&#8217;t have Flash Builder, you can download it <a href="http://www.adobe.com/cfusion/tdrc/index.cfm?product=flash_builder">here</a>)
<ul>
<li>File > Import > General > Existing Projects into Workspace</li>
<li>Select ccoenraets-flex-spring-mobile-testdrive as the Root directory</li>
<li>Select all the projects (EmployeeDirectoryJ, flex-spring-mobile, and MobileTraderJ)</li>
<li>Click Finish</li>
</ul>
</li>
<li>Running the EmployeeDirectory
<ul>
<li>Open config.xml in the src folder and modify the endpoint to match the hostname and port number of your app server</li>
<li>Right-click EmployeeDirectoryJ and select Run As > Mobile Application</li>
<li>Select a target platform (iOS, Android, or BlackBerry Tablet OS), select On desktop as the launch method and select a device to simulate</li>
<li>Click Run</li>
</ul>
</li>
<li>Running the MobileTrader Application
<ul>
<li>Right-click MobileTraderJ and select Run As > Mobile Application
<li>Select a target platform (iOS, Android, or BlackBerry Tablet OS), select On desktop as the launch method and select a device to simulate
<li>Click Run
<li>The Settings view is automatically activated the first time you run the application. Enter the MessageBroker base URL, for example: http://localhost:8080/flex-spring-mobile/messagebroker (modify the endpoint to match the hostname and port number of your app server), select a Channel type, click Save Settings, and click Start Server Feed.
<li>Access the Watch tab: The list should be automatically updated with the (simulated) real time updates pushed from the Spring web app.
</ul>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2011/08/flex-spring-mobile-test-drive-learn-the-best-way-to-build-java-backed-ios-android-and-playbook-apps/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>MobileTrader for iOS, Android, and PlayBook: Source code now available on GitHub</title>
		<link>http://coenraets.org/blog/2011/07/mobiletrader-for-ios-android-and-playbook-source-code-now-available-on-github/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mobiletrader-for-ios-android-and-playbook-source-code-now-available-on-github</link>
		<comments>http://coenraets.org/blog/2011/07/mobiletrader-for-ios-android-and-playbook-source-code-now-available-on-github/#comments</comments>
		<pubDate>Wed, 20 Jul 2011 18:13:51 +0000</pubDate>
		<dc:creator>Christophe Coenraets</dc:creator>
				<category><![CDATA[Air]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Collaboration]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=1551</guid>
		<description><![CDATA[I made some changes to the MobileTrader application and took the opportunity to push the source code to GitHub. You can get it here: https://github.com/ccoenraets/MobileTrader This version was built with the shipping version of Flex and Flash Builder 4.5.1 which has built-in support for iOS, Android and the BlackBerry PlayBook. The most notable change in [...]]]></description>
				<content:encoded><![CDATA[<p>I made some changes to the MobileTrader application and took the opportunity to push the source code to GitHub. You can get it here: <a href="https://github.com/ccoenraets/MobileTrader">https://github.com/ccoenraets/MobileTrader</a></p>
<p>This version was built with the shipping version of Flex and Flash Builder 4.5.1 which has built-in support for iOS, Android and the BlackBerry PlayBook.</p>
<p>The most notable change in this version is that I enabled the real time collaboration feature (with your financial advisor). This includes video conference, user interface synchronization, etc. You will need a <a href="http://www.adobe.com/products/livecycle/collaborationservice/">LiveCycle Collaboration Service</a> room URL to enable this feature. You can sign up for a developer version here: https://afcs.acrobat.com. You can still use the application without enabling the real time collaboration feature.</p>
<p>Usual disclaimer about the source code: This is a sample application, I intentionally cut some corners, etc.</p>
<p><span id="more-1551"></span></p>
<p>If you haven&#8217;t seen the application before, watch it here:</p>
<p><iframe title="YouTube video player" width="640" height="390" src="http://www.youtube.com/embed/ZfKNOt3xdgs?rel=0" frameborder="0" allowfullscreen></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2011/07/mobiletrader-for-ios-android-and-playbook-source-code-now-available-on-github/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Three Platforms, One application: MobileTrader for iOS, Android, and PlayBook Source Code Available</title>
		<link>http://coenraets.org/blog/2011/05/three-platforms-one-application-mobiletrader-for-ios-android-and-playbook-source-code-available/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=three-platforms-one-application-mobiletrader-for-ios-android-and-playbook-source-code-available</link>
		<comments>http://coenraets.org/blog/2011/05/three-platforms-one-application-mobiletrader-for-ios-android-and-playbook-source-code-available/#comments</comments>
		<pubDate>Tue, 17 May 2011 18:12:24 +0000</pubDate>
		<dc:creator>Christophe Coenraets</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[PlayBook]]></category>
		<category><![CDATA[flexorg]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=1512</guid>
		<description><![CDATA[My recent video, Flex on the iPad, has generated a lot of interest. The same application runs on iOS, Android, and the BlackBerry PlayBook. A number of you have asked me for the source code. Now that Flex 4.5 has been released, I&#8217;m able to share it: you can download the project file here. NOTE: [...]]]></description>
				<content:encoded><![CDATA[<p>My recent video, <a href="http://coenraets.org/blog/2011/03/flex-on-the-ipad/">Flex on the iPad</a>, has generated a lot of interest. The same application runs on iOS, Android, and the BlackBerry PlayBook. A number of you have asked me for the source code. Now that Flex 4.5 has been released, I&#8217;m able to share it: you can download the project file <a href="http://coenraets.org/mobile/MobileTrader.fxp">here</a>.</p>
<p>NOTE: The shipping version of Flash Builder 4.5 provides full support for Flex projects on Android. Support for Flex projects on iOS and the PlayBook will be available in a June update. More information <a href="http://blogs.adobe.com/flex/2011/04/compatibility-matrix-for-mobile-development-with-flash-builder-4-5.html">here</a>.</p>
<p>Usual disclaimer about the source code: This is a sample application, I intentionally cut some corners, etc.</p>
<p><span id="more-1512"></span><br />
<iframe title="YouTube video player" width="640" height="390" src="http://www.youtube.com/embed/ZfKNOt3xdgs?rel=0" frameborder="0" allowfullscreen></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2011/05/three-platforms-one-application-mobiletrader-for-ios-android-and-playbook-source-code-available/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Flex Charts on the iPad</title>
		<link>http://coenraets.org/blog/2011/04/flex-charts-on-the-ipad/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=flex-charts-on-the-ipad</link>
		<comments>http://coenraets.org/blog/2011/04/flex-charts-on-the-ipad/#comments</comments>
		<pubDate>Wed, 20 Apr 2011 14:51:13 +0000</pubDate>
		<dc:creator>Christophe Coenraets</dc:creator>
				<category><![CDATA[Air]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[PlayBook]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=1469</guid>
		<description><![CDATA[I continue to see a lot of interest for dashboards applications on mobile devices (particularly on tablets), and I think that interactive data visualization applications are really a sweet spot for Flex. As an example, I built a simple dashboard aggregator using the out-of-the box charting components available in Flex. The same application can run [...]]]></description>
				<content:encoded><![CDATA[<p>I continue to see a lot of interest for dashboards applications on mobile devices (particularly on tablets), and I think that interactive data visualization applications are really a sweet spot for Flex. As an example, I built a simple dashboard aggregator using the out-of-the box charting components available in Flex. The same application can run on iOS (iPhone/iPad/iPod Touch), Android devices, and on the BlackBerry PlayBook. If you are an existing Flex developer, this will look very familiar: these are the same charts you also run in the browser or on the desktop on traditional computers. Check out the video:</p>
<p><iframe title="YouTube video player" width="640" height="390" src="http://www.youtube.com/embed/paTRLcmErNY?rel=0" frameborder="0" allowfullscreen></iframe></p>
<p>For more data-visualization applications built with Flex, check out the <a href="http://coenraets.org/blog/2011/03/flex-on-the-ipad/">Mobile Trader</a> and the <a href="http://coenraets.org/blog/2011/04/flex-powered-multi-touch-data-visualization-on-the-ipad-android-and-the-blackberry-playbook/">Sales Pipeline</a> applications.</p>
<p>Usual disclaimer: I&#8217;m not a designer, so this is mostly developer artwork. You can of course polish, customize and style the out-of-the-box-experience.</p>
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2011/04/flex-charts-on-the-ipad/feed/</wfw:commentRss>
		<slash:comments>27</slash:comments>
		</item>
		<item>
		<title>Flex-Powered Multi-Touch Data Visualization on the iPad, Android, and the BlackBerry PlayBook</title>
		<link>http://coenraets.org/blog/2011/04/flex-powered-multi-touch-data-visualization-on-the-ipad-android-and-the-blackberry-playbook/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=flex-powered-multi-touch-data-visualization-on-the-ipad-android-and-the-blackberry-playbook</link>
		<comments>http://coenraets.org/blog/2011/04/flex-powered-multi-touch-data-visualization-on-the-ipad-android-and-the-blackberry-playbook/#comments</comments>
		<pubDate>Fri, 15 Apr 2011 14:30:43 +0000</pubDate>
		<dc:creator>Christophe Coenraets</dc:creator>
				<category><![CDATA[Air]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[PlayBook]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=1452</guid>
		<description><![CDATA[Over the past couple of weeks, I’ve visited many enterprise customers to spread the exciting news and discuss their mobile strategy. I found it interesting that most of them were focusing primarily on tablets (instead of phones), and that the application they were focusing on was almost always a dashboard or at least involved a [...]]]></description>
				<content:encoded><![CDATA[<p><iframe title="YouTube video player" width="640" height="390" src="http://www.youtube.com/embed/-zaSmo-mQkE?rel=0" frameborder="0" allowfullscreen></iframe></p>
<p>Over the past couple of weeks, I’ve visited many enterprise customers to spread <a href="http://coenraets.org/blog/2011/03/flex-on-the-ipad/">the exciting news</a> and discuss their mobile strategy. I found it interesting that most of them were focusing primarily on tablets (instead of phones), and that the application they were focusing on was almost always a dashboard or at least involved a lot of charting components. It is true that tablets such as the iPad, the Xoom, and the BlackBerry PlayBook are amazing devices for data visualization.</p>
<p><span id="more-1452"></span></p>
<p>Multi-touch is revolutionizing the way we interact with applications. The idea of <em>user interfaces behaving like real life objects</em> has been kicked around for a long time, and touch screens remove an important barrier.  In the area of data visualization, multi-touch can have a particularly transformative effect: there are definitely a lot of opportunities for more “natural” data manipulation and exploration.</p>
<p>So, as an exercise, I built an interactive sales dashboard using Flex to explore the possibilities.</p>
<p>Check out the video (running on an iPad). Of course, the same application can run on Android, on the BlackBerry PlayBook, and in the browser or as a desktop application on traditional computers.</p>
<p>This is just a small example of thinking about data visualization differently. Charts don’t have to be read-only: If the data isn’t right, change it right there (“in place editing”).</p>
<p>I’m looking forward to seeing what people will come up with in this exciting field.</p>
<p>Disclaimer: I’m not a designer. This is still mostly developer artwork. The goal of this demo is to experiment with new ways to visualize and modify data, and not to recommend this specific implementation.</p>
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2011/04/flex-powered-multi-touch-data-visualization-on-the-ipad-android-and-the-blackberry-playbook/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
	</channel>
</rss>
