<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://devlicio.us/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Sergio Pereira : HTML5</title><link>http://devlicio.us/blogs/sergio_pereira/archive/tags/HTML5/default.aspx</link><description>Tags: HTML5</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>Chrome Extension Development</title><link>http://devlicio.us/blogs/sergio_pereira/archive/2010/06/28/chrome-extension-development.aspx</link><pubDate>Tue, 29 Jun 2010 03:20:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:60801</guid><dc:creator>sergiopereira</dc:creator><slash:comments>3</slash:comments><description>&lt;p&gt;Do you like JavaScript? Have you been looking for a reaon or an idea to learn and start using
HTML5? Google Chrome extesions are a great way to get into HTML5 and all its new APIs
with bite sized applications.&lt;/p&gt;

&lt;h3&gt;Anatomy of a Chrome Extension&lt;/h3&gt;

&lt;p&gt;A Chrome extesion is nothing more than a tiny website that runs hosted inside Chrome. Like
any website, it consists of regular web components. Grossly simplifying it is just a directory
full of files, such as JavaScript, CSS, images, HTML5, and anything else you usually add to
a web page.&lt;/p&gt;

&lt;p&gt;Because it runs inside the browser, you have access to things like browser events, browsing
history, and open tabs.&lt;/p&gt;

&lt;p&gt;Essentially, your extension gets loaded as an HTML page called &lt;b&gt;background.html&lt;/b&gt; where
you can put any common/global functions and variables. This page is never visible and
even if you don&amp;#39;t provide a background.html in your extension, Chrome will load an
empty one for you. All other pages in your extension can access the background page&amp;#39;s
functions.&lt;/p&gt;

&lt;p&gt;Here&amp;#39;s a diagram of a common scenario.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2010.06/chrome_2D00_ext_2D00_diag1.png" border="0" alt="" /&gt;&lt;/p&gt;

&lt;h3&gt;Today&amp;#39;s Brew&lt;/h3&gt;

&lt;p&gt;Our sample extension will be something simple but that at the same time
will let us explore interesting aspects of extensions development, namely
local storage and cross-domain requests.&lt;/p&gt;

&lt;p&gt;The sample is also a hat tip to the valuable work &lt;a href="http://twitter.com/calcock"&gt;Chris Alcock&lt;/a&gt; does
with his &lt;a href="http://themorningbrew.net/"&gt;The Morning Brew&lt;/a&gt;, collecting some of the best links for all of us.&lt;/p&gt;

&lt;p&gt;What we will do here is create an extension that will show us his latests links at the click of a button.&lt;/p&gt;

&lt;h3&gt;Introduce yourself&lt;/h3&gt;

&lt;p&gt;The extension needs to inform Chrome a few details about itself, such as name, default icons, along with any 
permissions it requests to access privileged browser features. This is done through the &lt;b&gt;manifest file&lt;/b&gt;, which is
just a JSON document. Here&amp;#39;s our manifest file, aptly named &lt;b&gt;manifest.json&lt;/b&gt;.&lt;/p&gt;

&lt;pre name="code" class="js"&gt;{
  &amp;quot;name&amp;quot;: &amp;quot;Today&amp;#39;s Brew&amp;quot;,
  &amp;quot;version&amp;quot;: &amp;quot;1.0&amp;quot;,
  &amp;quot;description&amp;quot;: &amp;quot;Latest links from The Morning Brew.&amp;quot;,
  &amp;quot;icons&amp;quot;: { 
    &amp;quot;48&amp;quot;: &amp;quot;icon48.png&amp;quot;,
    &amp;quot;128&amp;quot;: &amp;quot;icon128.png&amp;quot; 
  },
  &amp;quot;browser_action&amp;quot;: {
    &amp;quot;default_icon&amp;quot;: &amp;quot;icon.png&amp;quot;,
    &amp;quot;default_popup&amp;quot;: &amp;quot;popup.html&amp;quot;
  },
  &amp;quot;permissions&amp;quot;: [
    &amp;quot;http://feeds.feedburner.com/&amp;quot;,
    &amp;quot;tabs&amp;quot;
  ]
}&lt;/pre&gt;

&lt;h3&gt;What you can do&lt;/h3&gt;

&lt;p&gt;Extensions can perform several different jobs, like showing notifications, providing new themes, changing
some of the default Chrome pages, etc. One other thing they can do are the browser actions, which basically 
means adding a button to the toolbar that acts independent of what page is being shown, as if it were
just another browser feature.&lt;/p&gt;

&lt;p&gt;If you look at our manifest file you&amp;#39;ll notice we declared a &lt;b&gt;browser_action&lt;/b&gt;, with its icon and the page it
opens wen clicked. &lt;/p&gt;

&lt;p&gt;Our extension does not have a custom background page, we will just rely on the default one Chrome will
give us and put all of our logic in the popup page that we will open.&lt;/p&gt;

&lt;h3&gt;What you need to do that&lt;/h3&gt;


&lt;p&gt;Here&amp;#39;s how our extension will look like when we&amp;#39;re done.
&lt;/p&gt;
&lt;p&gt;&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2010.06/todaysbrew.png" border="0" alt="" /&gt;&lt;/p&gt;

&lt;p&gt;In our extension, other than manipulating our own extension&amp;#39;s HTML dynamically (which doesn&amp;#39;t require
any special permissions) we will need to fetch the RSS feed from Feedburner and eventually open
new tabs as the user clicks on the links.&lt;/p&gt;

&lt;p&gt;That&amp;#39;s what you can see in the &lt;b&gt;permissions&lt;/b&gt; section of the manifest file above.
&lt;/p&gt;
&lt;h3&gt;Getting down to business&lt;/h3&gt;

&lt;p&gt;To create our extension we start by creating an empty directory and adding our manifest.json file and all
the icon image files that we mentioned in that manifest file.&lt;/p&gt;

&lt;p&gt;Then we create our popup.html file, which will be pretty empty and will be populated with
the content we will retrieve from the RSS feed. Here&amp;#39;s that file.&lt;/p&gt;

&lt;pre name="code" class="html:nogutter"&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;jquery.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;popup.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;div id=&amp;quot;main&amp;quot;&amp;gt;
  &amp;lt;h1&amp;gt;&amp;lt;/h1&amp;gt;
  &amp;lt;div id=&amp;quot;content&amp;quot;&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;

&lt;p&gt;As you can see, we will be using jQuery so we should also add that file to our directory. We will
leave all the beautification of the popup in the popup.css file, which I won&amp;#39;t bother showing here;
you can download it along with the rest of the code at the end of this article.&lt;/p&gt;

&lt;p&gt;The other file referenced by the HTML is popup.js. That&amp;#39;s where all the action happens.
&lt;/p&gt;


&lt;pre name="code" class="js"&gt;$(document).ready(function(){
  SERGIOPEREIRA.samples.todaysBrew.init();
});

var SERGIOPEREIRA = {
  samples: {
    todaysBrew: {
      state: { },
      feedUrl: &amp;#39;http://feeds.feedburner.com/ReflectivePerspective?format=xml&amp;#39;,
      todaysUrl: &amp;#39;&amp;#39;,
      maxAgeHours: 12, // keep it for 12 hours
      
      init: function(){
        $(&amp;#39;#content h3&amp;#39;).live(&amp;#39;click&amp;#39;, function(){
          $(&amp;#39;#content ul:visible&amp;#39;).slideUp();
          $(this).next().slideToggle();
        });

        $(&amp;#39;#content li a&amp;#39;).live(&amp;#39;click&amp;#39;, function(){
          $(&amp;#39;#content ul:visible&amp;#39;).slideUp();
          chrome.tabs.create({url: this.href});
        });

        $(&amp;#39;h1&amp;#39;).click(function(){
          chrome.tabs.create({url: SERGIOPEREIRA.samples.todaysBrew.todaysUrl});
        });
        
        if(typeof chrome != &amp;#39;undefined&amp;#39;) {
          this.state = localStorage.getItem(&amp;#39;latestBrew&amp;#39;);

          if(this.state){
            var now = new Date();
            var minTimestamp = new Date();
            minTimestamp.setHours(minTimestamp.getHours() - this.maxAgeHours);
            minTimestamp = minTimestamp.toJSON();

            if(this.state.timestamp &amp;gt; minTimestamp) {
              this.renderLatest(this.state.latestData);
              return;
            }
          }
          this.refresh();
        }
      },
      refresh: function(){
        console.log(&amp;#39;will get feed data...&amp;#39;);
        $.get(this.feedUrl, function(xml, status, xhr){
          SERGIOPEREIRA.samples.todaysBrew.update(xml);
        });
      },
      update: function(feedXml) {
        var latest = this.getFirstItem(feedXml);
        this.state = { };
        this.state.latestData = latest;
        this.state.timestamp = new Date();
        localStorage[&amp;#39;latestBrew&amp;#39;] = JSON.stringify(this.state);
        this.renderLatest(latest);
      },
      renderLatest: function(latest){
        $(&amp;#39;#main&amp;gt;h1&amp;#39;).text(latest.title);
        $(&amp;#39;#content&amp;#39;).html(latest.content);
        this.todaysUrl = latest.url;
      },      
      getFirstItem: function(feedXml){
        var items = feedXml.evaluate(&amp;quot;//channel/item&amp;quot;, feedXml, 
                                 null, XPathResult.ANY_TYPE, null); 

        var item = items.iterateNext(); 
        if (item) {
          return this.createItem(item);
        }
      },      
      createItem: function(postXml) {
        return { 
          title: this.readElementText(postXml, &amp;#39;title&amp;#39;),
          url: this.readElementText(postXml, &amp;#39;feedburner:origLink&amp;#39;),
          content: this.readElementText(postXml, &amp;#39;content:encoded&amp;#39;)
        };
      },
      mapElements: function(contextElement, path, map){
        var result = [ ];
        var items = contextElement.ownerDocument.evaluate(path, contextElement, 
                                this.namespaceResolver, XPathResult.ANY_TYPE, null); 
        
        var item = items.iterateNext(); 
        var i = 0;
        while (item) {
          result.push( map(item, i++) );
          item = items.iterateNext();
        }

        return result;
      },      
      readElementText: function(contextElement, path){
        var results = contextElement.ownerDocument.evaluate(path, contextElement, 
                                   this.namespaceResolver, XPathResult.ANY_TYPE, null); 
        var first = results.iterateNext(); 

        if (first) {
          return first.textContent;
        }
      },      
      namespaceResolver: function(prefix) {
        if(prefix == &amp;#39;content&amp;#39;) {
          return &amp;#39;http://purl.org/rss/1.0/modules/content/&amp;#39;;
        }
        if(prefix == &amp;#39;feedburner&amp;#39;) {
          return &amp;#39;http://rssnamespace.org/feedburner/ext/1.0&amp;#39;;
        }
      }

    }
  }
};&lt;/pre&gt;

&lt;p&gt;Wow, that&amp;#39;s a lot of JavaScript at once, right? Hopefully you&amp;#39;ll notice that most of it is just
to parse the RSS xml.&lt;/p&gt;

&lt;p&gt;Only a few parts of this code deserve commentary. The &lt;code&gt;refresh&lt;/code&gt; method (line 45) is the one
that retrieves the RSS data. It uses the &lt;code&gt;jQuery.get&lt;/code&gt; method to do so. Once the data arrives, it will
invoke &lt;code&gt;update&lt;/code&gt;, which will use the parsing methods to get an object representing the latest
news item in the data. &lt;/p&gt;

&lt;pre name="code" class="js:nogutter"&gt;      update: function(feedXml) {
        var latest = this.getFirstItem(feedXml);
        this.state = { };
        this.state.latestData = latest;
        this.state.timestamp = new Date();
        localStorage[&amp;#39;latestBrew&amp;#39;] = JSON.stringify(this.state);
        this.renderLatest(latest);
      },&lt;/pre&gt;

&lt;p&gt;The above code also shows the use of two important APIs that Chrome implements. The
&lt;code&gt;localStorage&lt;/code&gt; is a way to persist information that lives in the client 
machine and lasts even after the browser closes. We use it to remeber our last
results and avoid fetching and parsing the RSS each time the popup is opened.&lt;/p&gt;

&lt;p&gt;The other API is the native &lt;code&gt;JSON&lt;/code&gt; object that can replace any dedicated
library we are used to have in cross-browser websites. We need to &lt;code&gt;stringify&lt;/code&gt;
the data because we can only save strings in the local storage.&lt;/p&gt;

&lt;p&gt;With the parsed data at hand we just need to replace the content in those empty html
tags in popup.html with the information we have.&lt;/p&gt;

&lt;h3&gt;Adding some life with events&lt;/h3&gt;

&lt;p&gt;The last piece of this puzzle are the jQuery event handlers that we created in the 
&lt;code&gt;init&lt;/code&gt; method. They make some of the elements clickable, including the
links, which open new tabs using &lt;code&gt;chrome.tabs.create()&lt;/code&gt;. Also note starting on line 
29 that if we find recent local data we use that instead of refreshing 
the content from the RSS feed.&lt;/p&gt;

&lt;h3&gt;Let&amp;#39;s load this thing up&lt;/h3&gt;

&lt;p&gt;Now we just need to run it and see how it goes. Go to the extesions page, expand
the &lt;i&gt;Developer Mode&lt;/i&gt; area and click &lt;i&gt;Load unpacked extension...&lt;/i&gt;. &lt;/p&gt;

&lt;p&gt;&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2010.06/loadext.png" border="0" alt="" /&gt;&lt;/p&gt;

&lt;p&gt;Then simply browse to your extension&amp;#39;s directory and select it. The extension should now be listed
as seen below.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2010.06/loadedext.png" border="0" alt="" /&gt;&lt;/p&gt;

&lt;p&gt;While you&amp;#39;re developing your extension you can debug it using the developer tools
included in Chrome. To do that, right click the extension button and select 
&lt;i&gt;Inspect popup&lt;/i&gt;.&lt;/p&gt;

&lt;p&gt;You can &lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2010.06/todaysbrew.zip"&gt;download&lt;/a&gt; 
the code for this extension and play with it all you want. I&amp;#39;m still early into learning this 
so feel free to give me pointers or ask questions.
&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=60801" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/sergio_pereira/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://devlicio.us/blogs/sergio_pereira/archive/tags/jQuery/default.aspx">jQuery</category><category domain="http://devlicio.us/blogs/sergio_pereira/archive/tags/HTML5/default.aspx">HTML5</category></item><item><title>The Ground is Shaking Again. Get Mobile.</title><link>http://devlicio.us/blogs/sergio_pereira/archive/2010/06/17/the-ground-is-shaking-again-get-mobile.aspx</link><pubDate>Thu, 17 Jun 2010 05:08:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:60619</guid><dc:creator>sergiopereira</dc:creator><slash:comments>5</slash:comments><description>&lt;p&gt;A little over two years ago I commented how surprising it was that
&lt;a href="http://devlicio.us/blogs/sergio_pereira/archive/2008/05/18/and-the-winner-is-vb-net.aspx"&gt;VisualBasic 
was still more popular than C#&lt;/a&gt; in the .Net world. Back 
then I checked the &lt;a href="http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html"&gt;TIOBE Index&lt;/a&gt; 
and saw that VB (in all its flavors) enjoyed almost 11% of relevance 
while C# wasn&amp;#39;t even at the 4% level.&lt;/p&gt;

&lt;p&gt;When we look at the June 2010 rank below we see that C# has finally
caught up with VB, and it&amp;#39;s safe to say C# is now the
most popular .Net language (remember, the VB index is not made up of just VB.NET.)&lt;/p&gt;

&lt;table&gt;
&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;Java&lt;/td&gt;&lt;td&gt;18.03%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:18.03%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;C&lt;/td&gt;&lt;td&gt;17.81%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:17.81%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;C++&lt;/td&gt;&lt;td&gt;10.76%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:10.76%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;PHP&lt;/td&gt;&lt;td&gt;8.93%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:8.93%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;5&lt;/td&gt;&lt;td&gt;(Visual) Basic&lt;/td&gt;&lt;td&gt;5.87%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:5.87%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;6&lt;/td&gt;&lt;td&gt;C#&lt;/td&gt;&lt;td&gt;5.20%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:5.20%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;7&lt;/td&gt;&lt;td&gt;Python&lt;/td&gt;&lt;td&gt;4.27%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:4.27%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;8&lt;/td&gt;&lt;td&gt;Perl&lt;/td&gt;&lt;td&gt;3.20%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:3.20%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;9&lt;/td&gt;&lt;td&gt;Objective-C&lt;/td&gt;&lt;td&gt;2.47%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:2.47%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;10&lt;/td&gt;&lt;td&gt;Delphi&lt;/td&gt;&lt;td&gt;2.39%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:2.39%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;11&lt;/td&gt;&lt;td&gt;JavaScript&lt;/td&gt;&lt;td&gt;2.19%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:2.19%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;12&lt;/td&gt;&lt;td&gt;Ruby&lt;/td&gt;&lt;td&gt;2.07%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:2.07%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;13&lt;/td&gt;&lt;td&gt;PL/SQL&lt;/td&gt;&lt;td&gt;0.79%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:0.79%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;14&lt;/td&gt;&lt;td&gt;SAS&lt;/td&gt;&lt;td&gt;0.70%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:0.70%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;15&lt;/td&gt;&lt;td&gt;Pascal&lt;/td&gt;&lt;td&gt;0.70%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:0.70%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;16&lt;/td&gt;&lt;td&gt;Lisp/Scheme/Clojure&lt;/td&gt;&lt;td&gt;0.65%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:0.65%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;17&lt;/td&gt;&lt;td&gt;Lua&lt;/td&gt;&lt;td&gt;0.59%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:0.59%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;18&lt;/td&gt;&lt;td&gt;MATLAB&lt;/td&gt;&lt;td&gt;0.59%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:0.59%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;19&lt;/td&gt;&lt;td&gt;ABAP&lt;/td&gt;&lt;td&gt;0.58%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:0.58%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;20&lt;/td&gt;&lt;td&gt;PowerShell&lt;/td&gt;&lt;td&gt;0.53%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:0.53%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;/table&gt;

&lt;p&gt;Again, anyone can debate the importance of this ranking system, but at least it
has been there for a while and to me it seems to represent the
pulse of software development quite well.&lt;/p&gt;

&lt;h3&gt;Movers and shakers&lt;/h3&gt;

&lt;p&gt;But this post is not about C# vs. VB.NET.&lt;/p&gt;

&lt;p&gt;This time around what caught my attention was the &lt;b&gt;impressive
rise of  Objective-C&lt;/b&gt; (up 36 positions in one year). Now,
no matter how more common Macs have become in the last few years,
no one will convince me this increase in Objective-C is due to
native OSX application development :)&lt;/p&gt;

&lt;p&gt;Of course we all know it&amp;#39;s caused by the surge in mobile and device app
development (iPhone, iPad, and anything that they decide will
run the iOS, like the AppleTV in the future, who knows?)&lt;/p&gt;

&lt;p&gt;If you look at the trending chart on the 
&lt;a href="http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html"&gt;TIOBE page&lt;/a&gt;
you&amp;#39;ll see that Objective-C started to gain significant steam around June of
last year, coincidentally (maybe not?) when the iPhone 3GS was announced.&lt;/p&gt; 

&lt;h3&gt;Keep your eyes on the ball&lt;/h3&gt; 

&lt;p&gt;Are you playing with Mobile yet? Have you:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Started reading about mobile development?&lt;/li&gt;
&lt;li&gt;Developed a Mobile web site?&lt;/li&gt;
&lt;li&gt;Written and tested a native app against a device emulator/VM (iPhone, Android, WebOS, WP7)?&lt;/li&gt;
&lt;li&gt;Written and deployed an app to your own mobile device?&lt;/li&gt;
&lt;li&gt;Published an app on the market?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It&amp;#39;s not like you will find yourself out of a job if you don&amp;#39;t get into mobile
but for many developers, from software shops to corporate environments, sooner
or later a request for a mobile product or a mobile version of an existing
one will swing by your desk.&lt;/p&gt;

&lt;p&gt;It&amp;#39;s an exciting time. Once again you have the chance of taking the lead
and play an important role in your team by staying ahead of the game. 
Remember when you started seeing request for Ajax and fancy UI&amp;#39;s in
your web applications. Remember how you were one of the few that
knew anything about it in your team? Same thing here. Only much bigger.&lt;/p&gt;

&lt;h3&gt;What I&amp;#39;m looking into&lt;/h3&gt;

&lt;p&gt;There are two different fronts that interest me in mobile development: 
Native Android apps and Mobile Sites. I&amp;#39;ll explain.&lt;/p&gt;

&lt;p&gt;The time I spent in Objective-C and XCode in the past was enough for
me to know I&amp;#39;d be grinding my teeth and blowing off steam every single
day if I wanted to develop for the iPhone (it&amp;#39;s probably just me, I can live with that admission.)
Besides, I don&amp;#39;t like the idea of an approval process before I can give away or sell my apps.&lt;/p&gt;

&lt;p&gt;Windows Phone is something that I&amp;#39;ll have to wait more and see what
kind of traction it gains. It also has the approval process issue. The
big plus will be the development tools, which I think will better than
iPhone and Android.&lt;/p&gt;

&lt;p&gt;All that, combined with the enormous momentum that Android has, made
me start coding for Android when it comes to native apps.&lt;/p&gt;

&lt;h3&gt;Don&amp;#39;t forget Mobile Web&lt;/h3&gt;

&lt;p&gt;Native mobile development is fun and rewarding but let&amp;#39;s not kid ourselves.
History shows that businesses will favor the simplicity of web development.&lt;/p&gt;

&lt;p&gt;I went through that transition period when custom desktop application
development quickly lost market to web applications. And that happened
in a world where Windows was virtually in every workstation that mattered.&lt;/p&gt;

&lt;p&gt;Now imagine the mobile scene, where there&amp;#39;s more than one big player, none
equivalent to what Windows was back in 1998. Do you really think anyone
will want incur the cost of maintaining 3 or 4 different native 
versions of each mobile application that we will start cranking out
like we do web apps today? Native apps will probably be the minority,
for environments where you have the luxury of dictating your end-user&amp;#39;s
choice of mobile device.&lt;/p&gt;

&lt;p&gt;Didn&amp;#39;t we just spend the better part of the last 10 years trying to get out of 
a certain single-browser paradigm? Do we want to repeat that mistake?&lt;/p&gt;

&lt;h3&gt;Moving to HTML5&lt;/h3&gt;

&lt;p&gt;Why is HTML5 so important in Mobile and not as much in the standard Web yet? Well,
for one there is a greater percentage of HTML5-capable browsers in Mobile
than on the desktop browsers. Android, iPhone, WebOS (and soon BlackBerries) 
have WebKit browsers. &lt;/p&gt;

&lt;p&gt;With things like richer forms, offline support, canvas, video and the
Geo-Location API (not really HTML5 but present in those WebKit browsers) we
can build really capable mobile web apps. Not just small screen
versions of the regular web apps.&lt;/p&gt;

&lt;p&gt;To be very straight forward about it, the way I personally see it is
that HTML5 is where the bulk of the mobile development will happen in the Enterprise and
consumer-facing applications.&lt;/p&gt;

&lt;p&gt;Maybe something like Flash, AIR, or Silverlight makes a run for their
mobile money too but with all the bullying from Apple and diverging
opinions everywhere, that&amp;#39;s not something I&amp;#39;m spending time on right now.&lt;/p&gt;

&lt;h3&gt;Native or Web?&lt;/h3&gt;

&lt;p&gt;Both. But definitely much more of the Web kind.
&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=60619" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/sergio_pereira/archive/tags/Development/default.aspx">Development</category><category domain="http://devlicio.us/blogs/sergio_pereira/archive/tags/Mobile/default.aspx">Mobile</category><category domain="http://devlicio.us/blogs/sergio_pereira/archive/tags/Android/default.aspx">Android</category><category domain="http://devlicio.us/blogs/sergio_pereira/archive/tags/HTML5/default.aspx">HTML5</category></item></channel></rss>