<?xml version="1.0" encoding="utf-8"?>
<feed version="0.3" xmlns="http://purl.org/atom/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xml:lang="en">
<title>Christian Cantrell</title>
<link rel="alternate" type="text/html" href="http://weblogs.macromedia.com/cantrell/" />
<modified>2008-05-13T19:44:10Z</modified>
<tagline>AIR Application Developer</tagline>
<id>tag:weblogs.macromedia.com,2008:/cantrell/5</id>
<generator url="http://www.movabletype.org/" version="3.16">Movable Type</generator>
<copyright>Copyright (c) 2008, cantrell</copyright>
<entry>
<title>Adobe Feeds Update II</title>
<link rel="alternate" type="text/html" href="http://weblogs.macromedia.com/cantrell/archives/2008/05/adobe_feeds_upd_1.html" />
<modified>2008-05-13T19:44:10Z</modified>
<issued>2008-05-13T19:30:52Z</issued>
<id>tag:weblogs.macromedia.com,2008:/cantrell/5.14912</id>
<created>2008-05-13T19:30:52Z</created>
<summary type="text/plain">Just a quick note to let you know that I fixed the Adobe Feeds web services.</summary>
<author>
<name>cantrell</name>

<email>ccantrel@adobe.com</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.macromedia.com/cantrell/">
<![CDATA[<p>Just a quick note to let you know that I fixed the Adobe Feeds web services. Also, just a reminder that if you're seeing &quot;header length too long&quot; error messages, clear your cookies, and the problem won't come back.</p>
<p>Oh, I also fixed the FAQ on Safari, so if you Mac users have been dying to read the FAQ all these years, now you can. Of course, you probably figured out the answer to your question by now.</p>]]>

</content>
</entry>
<entry>
<title>Adobe Feeds Update</title>
<link rel="alternate" type="text/html" href="http://weblogs.macromedia.com/cantrell/archives/2008/05/adobe_feeds_upd.html" />
<modified>2008-05-08T17:36:00Z</modified>
<issued>2008-05-08T17:33:44Z</issued>
<id>tag:weblogs.macromedia.com,2008:/cantrell/5.14909</id>
<created>2008-05-08T17:33:44Z</created>
<summary type="text/plain"><![CDATA[The new launch of Adobe Feeds (MXNA) has gone well, but there are two issues I'm seeing people report: Maybe people have been getting &quot;Header Length Too Large&quot; errors. Interestingly, this comes from cookie-related code that CF7 tolerated, but CF8...]]></summary>
<author>
<name>cantrell</name>

<email>ccantrel@adobe.com</email>
</author>
<dc:subject>Adobe</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.macromedia.com/cantrell/">
<![CDATA[<p>The new launch of Adobe Feeds (MXNA) has gone well, but there are two issues I'm seeing people report:</p>
<ol>
  <li>Maybe people have been getting &quot;Header Length Too Large&quot; errors. Interestingly, this comes from cookie-related code that CF7 tolerated, but CF8 doesn't. Anyway, the problem has been fixed. If you're still seeing the error message, clear your feeds.adobe.com cookies, and it will never come back.</li>
  <li>It seems the web services are broken. This is probably the result of the query optimizations I made. I didn't test all the web services, so they're probably incompatible with the changes I made. Oops. Sorry about that. I'll get this fixed in the next couple of days, and report back when they're working again.</li>
</ol>
<p>We'll get Feeds back to 100% in the next week or so. Please be patient with us!</p>]]>

</content>
</entry>
<entry>
<title>The new MXNA (AXNA?)</title>
<link rel="alternate" type="text/html" href="http://weblogs.macromedia.com/cantrell/archives/2008/05/the_new_mxna_ax.html" />
<modified>2008-05-06T05:10:14Z</modified>
<issued>2008-05-06T05:08:10Z</issued>
<id>tag:weblogs.macromedia.com,2008:/cantrell/5.14904</id>
<created>2008-05-06T05:08:10Z</created>
<summary type="text/plain">First, I personally apologize for the downtime. We&apos;ve been meaning to find MXNA a new home for quite a while now, and we finally decided to make the time to do it.  If you&apos;re interested in the story behind what happened, here it is.</summary>
<author>
<name>cantrell</name>

<email>ccantrel@adobe.com</email>
</author>
<dc:subject>Adobe</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.macromedia.com/cantrell/">
<![CDATA[<p>First, I personally apologize for the downtime. We've been meaning to find MXNA a new home for quite a while now, and we finally decided to make the time to do it. Ironically, as we were working on moving the code over to the Adobe cluster, the old weblogs server went down in a big way. We're still not sure what happened, but for some reason, Java was core dumping a few minutes after starting JRun. Rather than spending too much time fixing the old server, we decided to look ahead, put up an &quot;under construction&quot; page, and focus on the new platform.</p>
<p><a href="http://www.mikechambers.com/blog/">Mike Chambers</a> and I wrote <a href="http://feeds.adobe.com">MXNA</a> five years ago, thinking we would aggregate a few dozen popular blogs. 100 at the most. We initially put it on our own server which we expensed every month. When we outgrew that, we moved it to a single Macromedia server which Mike and I managed entirely ourselves. That worked out well for a couple of years until we outgrew it, as well. By that time, we were Adobe &mdash; a much larger company with more infrastructure &mdash; so moving it over to the cluster was a fairly involved task.</p>
<p>But we didn't just spread <a href="http://feeds.adobe.com">MXNA</a> across a few more servers. As we began approaching 2,000 feeds, it became clear that the same code that managed 100 feeds wasn't doing such a good job managing 1,800. So I finally set aside a day, installed CF8, imported the production database, and with some pointers from <a href="http://forta.com/">Ben Forta</a> (I'd never even used CF8 before &mdash; I've been focusing on AIR for the last two years), started optimizing.</p>
<p>I spent most of my time rewriting queries, and working on reducing the number of queries per request. The most dramatic change I made was optimizing the search query which went from about 30 seconds to one or two. Be sure to <a href="http://feeds.adobe.com">give it a try</a>.</p>
<p>Again, sorry not just for the recent downtime, but for all the intermittent downtime over the last year or so. Hopefully we're past all that, and <a href="http://feeds.adobe.com">MXNA</a> (AXNA?) will become a valuable community resource again.</p>]]>

</content>
</entry>
<entry>
<title>Weekend update to Newsbrew</title>
<link rel="alternate" type="text/html" href="http://weblogs.macromedia.com/cantrell/archives/2008/04/weekend_update.html" />
<modified>2008-04-28T19:34:22Z</modified>
<issued>2008-04-28T19:32:44Z</issued>
<id>tag:weblogs.macromedia.com,2008:/cantrell/5.14900</id>
<created>2008-04-28T19:32:44Z</created>
<summary type="text/plain">With just a few hours of work, I was able to make Newsbrew much more robust by using Google&apos;s new RESTful feed APIs.</summary>
<author>
<name>cantrell</name>

<email>ccantrel@adobe.com</email>
</author>
<dc:subject>Web Development</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.macromedia.com/cantrell/">
<![CDATA[<p>A couple weeks ago, I blogged about a <a href="http://code.google.com/appengine/">Google App Engine</a> news aggregator I wrote called <a href="http://news-brew.appspot.com/">Newsbrew</a> (<a href="http://weblogs.macromedia.com/cantrell/archives/2008/04/newsbrew_is_now.html">original post</a>). A few days later, Google announced the availability their <a href="http://code.google.com/apis/ajaxfeeds/documentation/">RESTful feed API</a>. Since the trickiest part of Newsbrew was the aggregation code, I decided to refactor the application to use Google's new service.</p>
<p>Newsbrew still stores feed and post data, but rather than retrieving and parsing the feeds myself (a surprisingly complex and error-prone process), Newsbrew now uses Google's REST feed API. All data, regardless of the underlying syndication format, is returned in a nice normalized JSON format.</p>
<p>With just a few hours of work, I was able to make Newsbrew much more robust, and because I no longer have code for parsing nine different formats of RSS and Atom, Newsbrew is much less error prone, and the code base is simpler.</p>
<p>I also added <a href="http://ajaxian.com/">Ajaxian</a> to the blogroll at the request of <a href="http://almaer.com/blog/">Dion Almaer</a>. If you know of any other sites I should add, let me know.</p>]]>

</content>
</entry>
<entry>
<title>The latest version of PixelPerfect (with screencast)</title>
<link rel="alternate" type="text/html" href="http://weblogs.macromedia.com/cantrell/archives/2008/04/the_latest_vers.html" />
<modified>2008-04-23T17:24:13Z</modified>
<issued>2008-04-23T17:12:49Z</issued>
<id>tag:weblogs.macromedia.com,2008:/cantrell/5.14898</id>
<created>2008-04-23T17:12:49Z</created>
<summary type="text/plain">PixelPerfect is a simple AIR application for measuring things on your desktop. If you want to see how it works, check out this screencast. If you want to see the code, check out the PixelPerfect Google Code project. And finally, if you just want to install it, click on the badge below.</summary>
<author>
<name>cantrell</name>

<email>ccantrel@adobe.com</email>
</author>
<dc:subject>Apollo</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.macromedia.com/cantrell/">
<![CDATA[<p>PixelPerfect is a simple AIR application for measuring things on your desktop. If you want to see how it works, <a href="javascript:openVideoWindow('/cantrell/videos/PixelPerfect.mov', 800, 600);">check out this screencast</a>. If you want to see the code, check out the <a href="http://code.google.com/p/pixelperfect/">PixelPerfect Google Code project</a>. And finally, if you just want to install it, click on the badge below.</p>

<div align="center" id="pixelperfect_div">AIR Badge</div>

<script type="text/javascript" src="/cantrell/swfobject/swfobject.js"></script>
<script type="text/javascript">
var pixelPerfectBadge = new SWFObject("/cantrell/air_apps/badge.swf", "badge", 217, 180, "9", "#ffffff");
pixelPerfectBadge.addVariable('appname', 'PixelPerfect');
pixelPerfectBadge.addVariable('appurl', 'http://weblogs.macromedia.com/cantrell/air_apps/PixelPerfect.air');
pixelPerfectBadge.addVariable('airversion', '1.0');
pixelPerfectBadge.addVariable('imageurl', '/cantrell/air_apps/pixelperfect.png');
pixelPerfectBadge.write('pixelperfect_div');
</script>]]>

</content>
</entry>
<entry>
<title>Newsbrew is now a Google Application</title>
<link rel="alternate" type="text/html" href="http://weblogs.macromedia.com/cantrell/archives/2008/04/newsbrew_is_now.html" />
<modified>2008-04-18T19:19:25Z</modified>
<issued>2008-04-18T19:16:31Z</issued>
<id>tag:weblogs.macromedia.com,2008:/cantrell/5.14891</id>
<created>2008-04-18T19:16:31Z</created>
<summary type="text/plain">I wrote a news aggregator a couple of years ago called Newsbrew which I primarily used for my own news-reading needs. After Google launched the Google App Engine, I decided to take a little break from Flex and AIR and rewrite Newsbrew in Python to get a good feel for the GAE experience.</summary>
<author>
<name>cantrell</name>

<email>ccantrel@adobe.com</email>
</author>
<dc:subject>Web Development</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.macromedia.com/cantrell/">
<![CDATA[<p>I wrote a news aggregator a couple of years ago called Newsbrew which I primarily used for my own news-reading needs. I think I took it down when I got tired of paying for the server, and worrying about keeping it up.</p>
<p>After Google launched the <a href="http://code.google.com/appengine/">Google App Engine</a>, I decided to take a little break from Flex and AIR and rewrite Newsbrew in Python to get a good feel for the GAE experience. You can see the current beta version <a href="http://news-brew.appspot.com/">here</a>.</p>
<p>Overall, I was very pleased GAE. It took me about five days to write <a href="http://news-brew.appspot.com/">this version of Newsbrew</a>, but that included learning Python, <a href="http://www.djangoproject.com/">Django</a>, and everything about GAE. The application is fairly comprehensive, consisting of a user interface, aggregation service, and a secure administrator section. Unfortunately, I didn't get to all the features and bug fixes that I wanted, but the app still seems to work reasonably well.</p>
<p>It's still going to be a little while before we're writing real-world production apps on GAE as it still has several rough patches, bugs, and missing functionality. But it's very clear where Google is going with this, and there's no doubt that GAE is a very powerful concept and platform. I'm certainly going to keep my eye on GAE, and use it as much as I can.</p>]]>

</content>
</entry>
<entry>
<title>Maptacular 2.0: a desktop mapping application for AIR</title>
<link rel="alternate" type="text/html" href="http://weblogs.macromedia.com/cantrell/archives/2008/04/maptacular_20_a.html" />
<modified>2008-04-23T17:10:28Z</modified>
<issued>2008-04-09T17:43:59Z</issued>
<id>tag:weblogs.macromedia.com,2008:/cantrell/5.14867</id>
<created>2008-04-09T17:43:59Z</created>
<summary type="text/plain">Maptacular was one of the first applications I wrote for AIR. That was back when AIR was in still in alpha, so I didn&apos;t have APIs for things like drag and drop or copy and paste. Now that AIR 1.0 has shipped, I decided to rewrite Maptacular to to have the functionality that I originally envisioned.</summary>
<author>
<name>cantrell</name>

<email>ccantrel@adobe.com</email>
</author>
<dc:subject>Apollo</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.macromedia.com/cantrell/">
<![CDATA[<p>Maptacular was one of the first applications I wrote for AIR. <a href="http://video.google.com/videoplay?docid=2840522561992638726&hl=en">The first version</a> parsed vCards from your local file system, and let you map the addresses it found inside. That was back when AIR was in still in alpha, so I didn't have APIs for things like drag and drop or copy and paste. Now that AIR 1.0 has shipped, I decided to rewrite Maptacular to to have the functionality that I originally envisioned.</p>
<p>I created a screencast of Maptacular 2.0 which <a href="javascript:openVideoWindow('/cantrell/videos/maptacular.mov', 800, 600);">you can watch here</a>. If you want to install the app, just click on the badge below. If you want to see the source, it's <a href="http://code.google.com/p/maptacular/">all available on Google Code</a>.</p>
<p>Maptacular is a good example of the following:</p>
<ul>
  <li>Custom chrome with transparency.</li>
  <li>Custom application menus (implemented for the Mac only -- when Maptacular runs on Windows, there are no application menus).</li>
  <li>Context menus.</li>
  <li>Drag and drop.</li>
  <li>Copy and paste (system clipboard access).</li>
  <li><a href="http://developer.yahoo.com/flash/maps/">Yahoo! Maps for ActionScript 3</a> (with custom markers).</li>
</ul>
<div align="center" id="maptacular_div">AIR Badge</div>

<script type="text/javascript" src="/cantrell/swfobject/swfobject.js"></script>
<script type="text/javascript">
var maptacularBadge = new SWFObject("/cantrell/air_apps/badge.swf", "badge", 217, 180, "9", "#ffffff");
maptacularBadge.addVariable('appname', 'Maptacular');
maptacularBadge.addVariable('appurl', 'http://weblogs.macromedia.com/cantrell/air_apps/Maptacular.air');
maptacularBadge.addVariable('airversion', '1.0');
maptacularBadge.addVariable('imageurl', '/cantrell/air_apps/maptacular.png');
maptacularBadge.write('maptacular_div');
</script>]]>

</content>
</entry>
<entry>
<title>Lineup: an Exchange calendar  viewer for AIR</title>
<link rel="alternate" type="text/html" href="http://weblogs.macromedia.com/cantrell/archives/2008/04/lineup_an_excha.html" />
<modified>2008-04-23T17:11:06Z</modified>
<issued>2008-04-02T17:39:14Z</issued>
<id>tag:weblogs.macromedia.com,2008:/cantrell/5.14845</id>
<created>2008-04-02T17:39:14Z</created>
<summary type="text/plain">I did a screencast of an Exchange calendaring application I wrote for AIR. It&apos;s one of the most useful applications I&apos;ve written so far, and probably the most popular within Adobe.</summary>
<author>
<name>cantrell</name>

<email>ccantrel@adobe.com</email>
</author>
<dc:subject>Apollo</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.macromedia.com/cantrell/">
<![CDATA[<p>I did a screencast of an Exchange calendaring application I wrote for AIR. <a href="javascript:openVideoWindow('/cantrell/videos/lineup.mov', 800, 600);">Click here to watch it</a>.</p>
<p>It's one of the most useful applications I've written so far, and probably the most popular within Adobe. It lets you view your Exchange calendar, and it notifies you of upcoming meetings. It also works offline, so you can view your calendar and get meeting details while you're between internet connections.</p>
<p>Lineup uses all the following open source ActionScript 3 libraries:</p>
<ul>
  <li><a href="http://code.google.com/p/as3corelib/">as3corelib</a>: various utilities like advanced date parsing.</li>
  <li><a href="http://code.google.com/p/as3exchangelib/">as3exchangelib</a>: talks to Exchange servers.</li>
  <li><a href="http://code.google.com/p/as3nativealertlib/">as3nativealertlib</a>: a modal alert that appears in its own native window.</li>
  <li><a href="http://code.google.com/p/as3notificationlib/">as3notificationlib</a>: creates notification windows, and provides a layer of abstraction on top of OS-specific notifications.</li>
  <li><a href="http://code.google.com/p/as3preferenceslib/">as3preferenceslib</a>: manages application preference persistence, including encryption when necessary.</li>
</ul>
<p>The complete source code for Lineup itself is also <a href="http://code.google.com/p/lineup/">available on Google Code</a>, or you can simply click on the badge below to install it.</p>

<div align="center" id="lineup_div">AIR Badge</div>

<script type="text/javascript" src="/cantrell/swfobject/swfobject.js"></script>
<script type="text/javascript">
var lineupBadge = new SWFObject("/cantrell/air_apps/badge.swf", "badge", 217, 180, "9", "#ffffff");
lineupBadge.addVariable('appname', 'Lineup');
lineupBadge.addVariable('appurl', 'http://weblogs.macromedia.com/cantrell/air_apps/Lineup.air');
lineupBadge.addVariable('airversion', '1.0');
lineupBadge.addVariable('imageurl', '/cantrell/air_apps/lineup.png');
lineupBadge.write('lineup_div');
</script>]]>

</content>
</entry>
<entry>
<title>Tips on getting a code signing certificate</title>
<link rel="alternate" type="text/html" href="http://weblogs.macromedia.com/cantrell/archives/2008/03/tips_on_getting.html" />
<modified>2008-03-26T18:50:48Z</modified>
<issued>2008-03-26T18:48:45Z</issued>
<id>tag:weblogs.macromedia.com,2008:/cantrell/5.14826</id>
<created>2008-03-26T18:48:45Z</created>
<summary type="text/plain">I got my own certificate for signing AIR applications a couple of weeks ago, so I thought I&apos;d share my experience in order to help others more easily navigate the process.</summary>
<author>
<name>cantrell</name>

<email>ccantrel@adobe.com</email>
</author>
<dc:subject>Apollo</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.macromedia.com/cantrell/">
<![CDATA[<p>I got my own certificate for signing AIR applications a couple of weeks ago, so I thought I'd share my experience in order to help others more easily navigate the process. My intention is not to provide an exhaustive tutorial on code signing or the process of obtaining a certificate (if that's what you're looking for, see Todd Prekaski's article entitled <a href="http://www.adobe.com/devnet/air/articles/signing_air_applications_print.html">Digitally Signing Adobe AIR Applications</a>). Rather, I just want to list a few things you should know about before starting the process in order to ensure that it goes smoothly.</p>
<p>I decided to get my certificate from <a href="http://www.thawte.com/">Thawte</a>, but you can also use <a href="http://www.verisign.com/">VeriSign</a> (and soon other Certificate Authorities who Adobe is working with). Both Thawte and VeriSign issue code-signing certificates to organizations as opposed to individuals, so the tips below assume that you already have a corporate entity established. We are currently working with CAs who can issue personal certificates, so if you don't have a business,  you will soon be able to get a certificate issued in your own name.</p>
<p>If you decide to get your certificate through Thawte, here are some important things to know:</p>
<ul>
  <li>Use Firefox. Firefox has a certificate manager that allows you to easily export your certificate as a P12 file which is what you need in order to sign your applications. Yes, it's sort of a strange requirement, but it makes the process much easier.</li>
  <li>Use an email address other than Gmail, Hotmail, or Yahoo. Thawte will not issue a certificate to anyone using an address from a free email service. I tried to talk them into it (I love Gmail), but they wouldn't budge. I ended up having to use my <a href="http://www.watchreport.com">Watch Report</a> email address which they eventually accepted, however they would have rather I used an email address associated with the company's domain.</li>
  <li>Set up a corporate web page. My main business is Watch Report, but my company is called Cantrell Media Company. Since Watch Report is well established, I never bothered setting up a separate corporate web site. Thawte wanted one, so I threw together <a href="http://www.christiancantrell.com">christiancantrell.com</a> in about five minutes. It's not pretty, but it met the requirement.</li>
  <li>Get a business phone number, and list it publicly. I work out of my home, so I have a business line (I almost always use my mobile phone, but it's nice to have a landline to fall back on). However, when I got the second line, I didn't bother to create a corporate account with Verizon. Rather, I have both my home and business lines listed under my personal name. Thawte doesn't like this. They either want to see a phone bill with your business number and business name on it (which I couldn't produce), or they want to see your business and your business number listed in a public directory. I listed Cantrell Media Company on yellowpages.com which took a few days, but is completely free. Thawte was happy with that. (<a href="http://www.yellowpages.com/info-LMS85129159/Cantrell-Media-Company">Here's the listing.</a>)</li>
</ul>
<p>Those are all the specific issues that caused me problems. If you own a business, and take all four points above into account when applying for your code-signing certificate, you should be able to obtain one within a couple of days with no problem at all.</p>]]>

</content>
</entry>
<entry>
<title>Apprise: an RSS aggregator written for AIR</title>
<link rel="alternate" type="text/html" href="http://weblogs.macromedia.com/cantrell/archives/2008/03/screencast_of_t.html" />
<modified>2008-03-13T15:54:28Z</modified>
<issued>2008-03-13T15:06:57Z</issued>
<id>tag:weblogs.macromedia.com,2008:/cantrell/5.14788</id>
<created>2008-03-13T15:06:57Z</created>
<summary type="text/plain">Apprise is an RSS aggregator written for AIR. Watch the screencast, check out the source code, or install Apprise right from here.</summary>
<author>
<name>cantrell</name>

<email>ccantrel@adobe.com</email>
</author>
<dc:subject>Apollo</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.macromedia.com/cantrell/">
<![CDATA[<p>I did a screencast of the RSS aggregator called Apprise that I wrote for AIR. <a href="javascript:openVideoWindow('/cantrell/videos/apprise.mov', 800, 600);">Click here to watch it</a>. I didn't put any effort into designing the app, so it looks pretty plain, but it's very functional.</p>

<p>All the source code for apprise is available <a href="http://code.google.com/p/apprise/">here on Google Code</a>. You can install Apprise by clicking on the badge below.</p>

<div align="center" id="apprise_div">AIR Badge</div>

<script type="text/javascript" src="/cantrell/swfobject/swfobject.js"></script>
<script type="text/javascript">
var appriseBadge = new SWFObject("/cantrell/air_apps/badge.swf", "badge", 217, 180, "9", "#ffffff");
appriseBadge.addVariable('appname', 'Apprise');
appriseBadge.addVariable('appurl', 'http://weblogs.macromedia.com/cantrell/air_apps/Apprise.air');
appriseBadge.addVariable('airversion', '1.0');
appriseBadge.addVariable('imageurl', '/cantrell/air_apps/apprise.jpg');
appriseBadge.write('apprise_div');
</script>

]]>

</content>
</entry>
<entry>
<title>Detecting network connections in AIR</title>
<link rel="alternate" type="text/html" href="http://weblogs.macromedia.com/cantrell/archives/2008/03/detecting_netwo.html" />
<modified>2008-03-11T18:15:50Z</modified>
<issued>2008-03-11T18:12:19Z</issued>
<id>tag:weblogs.macromedia.com,2008:/cantrell/5.14778</id>
<created>2008-03-11T18:12:19Z</created>
<summary type="text/plain">One of the biggest benefits of AIR is that applications can be written to easily function whether online or off. This article will tell you everything you need to know to reliably determine not only if your application is connected or not, but also whether it can reach the services it requires.</summary>
<author>
<name>cantrell</name>

<email>ccantrel@adobe.com</email>
</author>
<dc:subject>Apollo</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.macromedia.com/cantrell/">
<![CDATA[<p>One of the biggest benefits of AIR is that applications can be written to easily function whether online or off. Features like file access and a local SQL database give developers the functionality they need to write applications that can pull data from remote data sources while connected, but can also rely on cached data while disconnected. Of course, writing an application that functions seamlessly both online and offline requires that you be able to reliably detect whether you have a connection or not. This article will tell you everything you need to know to reliably determine not only if your application is connected or not, but also whether it can reach the services it requires.</p>]]>
<![CDATA[<p>Let me start by saying that this isn't as simple and straightforward as it might sound. In fact, in today's world of VPNs and 3G wireless networks and virtual network interfaces, it's actually pretty complicated. We didn't realize how complicated it was until early on in AIR 1.0 development when the engineer who was responsible for the online/offline functionality in the runtime gave me a build to test. I started writing an application that needed to know whether it was connected or not, and the first time I yanked my network cable out, we were surprised to find that it didn't work as expected. The cable was disconnected, my AirPort card was turned off, but for some reason, my computer (and the AIR runtime) thought it was still connected. After some investigation, we realized that the problem was a couple of virtual network interfaces that Parallels set up in order to be able to manage networking between OS X and Windows.</p>
<p>What ensued was an almost philosophical discussion about what it meant to be online and offline. Theoretically, my application might have been trying to talk to a service on my Windows virtual machine which would have meant that my computer actually was connected even though I pulled my cord out. Or I might have had an internet connection, but the server my application needed to talk to might only be accessible while connected to a VPN. Or I might be on a public network that blocks certain services, packets, or ports that my application relies on in order to access data. Or you might be sitting in an underground concrete bunker with no connection to the outside world whatsoever, but you're developing an application the retrieves data from a server running on your local computer which means, from the application's point of view, it's online.</p>
<p>We eventually arrived at the conclusion that there really is no such thing as online or offline, or at least no simple and practical definition that worked for AIR developers, and that meant there was no way we were going to get away with a simple online/offline API (the first version of this API allowed for the simple registration of online and offline events on the static NativeApplication instance). In fact, we realized that it doesn't even matter if you're online or not which meant we were trying to answer the wrong question. All that matters is whether you can successfully access a particular service. And to figure that out, we were going to have to deliver a couple different APIs, and probably some best practices around using them.</p>
<p>The two APIs we decided to deliver with the runtime are the <a href="http://livedocs.adobe.com/flex/3/langref/flash/desktop/NativeApplication.html#event:networkChange"><code>networkChangeEvent</code></a>, and the <a href="http://livedocs.adobe.com/flex/3/langref/air/net/ServiceMonitor.html"><code>ServiceMonitor</code> class</a>. You register for <code>networkChangeEvents</code> on the <code>NativeApplication</code> static instance. Each time a <code>networkChangeEvent</code> is thrown, you know that network connectivity has somehow changed, but you don't know <em>how</em> it's changed. For instance, the user might have connected, disconnected, logged into a VPN, joined a wireless network, etc. That's where the <code>ServiceMonitor</code> class comes in. Since we determined that there really is no absolute concept of online or offline, you can use the <code>ServiceMonitor</code> class to tell you something which is much more interesting: whether or not you can actually <em>reach</em> a specific service.</p>
<p>The <code>ServiceMonitor</code> class has two subclasses: <a href="http://livedocs.adobe.com/flex/3/langref/air/net/SocketMonitor.html"><code>SocketMonitor</code></a> and <a href="http://livedocs.adobe.com/flex/3/langref/air/net/URLMonitor.html"><code>URLMonitor</code></a>. The <code>SocketMonitor</code> is for monitoring services that you connect to directly with a TCP socket like a mail or an XMPP server. The <code>URLMonitor</code> class is for monitoring HTTP services like REST based services. Both can be configured to listen for <code>networkChangeEvents</code> for you, or they can can be activated manually by calling the <code>checkService</code> method. Both also have various ways to configure them to work with your specific service. The <code>service</code> event thrown by the <code>ServiceMonitor</code> has a <code>code</code> property which indicates whether or not communication with the service was successful.</p>
<p>This is a pretty complete solution, but there's still one more scenario that we haven't accounted for. Let's say the end user plugs in a network cable which causes the <code>networkChangeEvent</code> to fire which, in turn, causes the <code>ServiceMonitor</code> to check the state of the service. And let's say the service responds favorably which causes the <code>ServiceMonitor</code> to throw its status event with a <code>code</code> property of &quot;service.available&quot;. Your application responds by showing a big green light indicating to the end user that all is well, and that it's safe to submit data to or pull live data from your remote service.</p>
<p>The problem is that the service might go down between the time you last checked it and the time your application needs to interact with it. Or your ISP might have suddenly gone out of business. Or an underwater transatlantic cable could have been cut. Any number of things could prevent your application from successfully talking to its services. The <code>ServiceMonitor</code> can't help you now, so it's up to you to catch the <code>IOErrorEvents</code> and handle them gracefully. Since I typically use the <a href="http://labs.adobe.com/wiki/index.php/Cairngorm">Cairngorm Flex framework</a>, I have a single boolean property in my ModelLocator called <code>online</code> which any part of my code can access. I set the <code>online</code> property inside of my <code>ServiceMonitor</code> event handlers and also within my <code>IOErrorEvent</code> handlers, as well (and I also set it to true every time I successfully interact with a service). That way, whether the end user has no connectivity or the service the application is trying to access is down, the application behaves consistently and appropriately.</p>
<p>Of course, having a robust solution to reliably determining whether you're online or not is only half the challenge since your application also has to know how to behave in both circumstances. Writing a complete online/offline application is beyond the scope of this article, but I will say that hinging application logic on the ModelLocator's <code>online</code> property is the key. If you want a detailed real-world example, I recommend taking a look at <a href="http://code.google.com/p/lineup/">Lineup</a>, my Exchange calendaring application. It works both online and off, and demonstrates all the principles described in this article.</p>]]>
</content>
</entry>
<entry>
<title>What you might not know about AIR (yet)</title>
<link rel="alternate" type="text/html" href="http://weblogs.macromedia.com/cantrell/archives/2008/02/what_you_might.html" />
<modified>2008-02-25T17:40:01Z</modified>
<issued>2008-02-25T17:38:40Z</issued>
<id>tag:weblogs.macromedia.com,2008:/cantrell/5.14730</id>
<created>2008-02-25T17:38:40Z</created>
<summary type="text/plain">If you&apos;re reading my blog, I&apos;m going to assume that you already know what AIR is. Rather than tell you what you probably already know about AIR, I&apos;d like to mention a few things that people might not have realized yet.</summary>
<author>
<name>cantrell</name>

<email>ccantrel@adobe.com</email>
</author>
<dc:subject>Apollo</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.macromedia.com/cantrell/">
<![CDATA[<p>If you're reading my blog, I'm going to assume that you already know what AIR is. If you don't, have a look at the <a href="http://www.adobe.com/products/air/">official AIR product page</a> before reading any further. Rather than tell you what you probably already know about AIR, I'd like to mention a few things that people might not have realized yet.</p>
<p>AIR isn't just another Adobe product. It isn't just a new tool or utility. It's an entirely new way to develop, deploy, install, and use desktop applications. Entirely new. I really can't stress this point enough. In the world of software, new products are launched all the time (if you don't believe me, just follow <a href="http://www.techcrunch.com/">TechCrunch</a> for a few days &mdash; it's staggering), each with a marketing team that wants you to believe that their technology is nothing less than revolutionary. So when something completely different does come along, it's sometimes hard to distinguish. How successful AIR will be and how quickly the technology is adopted is an entirely different topic, but there is absolutely no doubt that it's new and disruptive. I could easily write an entire white paper on the importance of AIR, but for the sake of brevity, I'll focus on three main points:</p>
<ul>
  <li><strong>Web technology on the desktop really makes sense.</strong> When I first heard the concept of running web technology on the desktop, I was admittedly skeptical. This was several years ago when my perspective on web applications was that we were all willing to sacrifice things like usability, richness, offline support, and features for the convenience of not having to host and update the apps ourselves, and the power of having your data accessible from any computer. That isn't even close to a valid assessment anymore. Thanks to Flash, Flex, and some truly amazing work done around JavaScript and Ajax, there are many applications on the web today that completely blow away most desktop experiences. The old adage of necessity being the mother of invention helped the web transition from a handful of HTML form controls and slow page refreshes to a rich, interactive, intuitive experience. The idea of unleashing those technologies and the developers working with this technologies on the desktop started making more and more sense, especially since it finally gives the final advantages that desktop applications had over web applications to web developers: local APIs, and offline support. The one thing web apps couldn't do were things like local file access, system notifications, native drag and drop, etc., and of course, no matter how great the web application was, if you didn't have an internet connection, you couldn't access it. This is what we mean by bridging the gap between the desktop and the web. AIR lets you have the richness of the web and the power of the desktop, and you can still do things like easily update your applications and store your data remotely. And you can do it all whether you're online or off.</li>
  <li><strong>Cross-platform is real.</strong> For a long time, the idea of running the same applications and getting the same experiences on Mac, Windows, and Linux was a little bit like the idea of world peace. Everyone seemed to agree that it would be great, but it never seemed all that realistic. I think it's safe to say that AIR is the first technology to really get the idea of cross-platform right. I shouldn't over-idealize this aspect of AIR, however. To be perfectly frank, there are still challenges with building 100% cross-platform applications. Menuing systems work differently on Mac and Windows, and all platforms have concepts and conventions that other platforms don't have (system tray, dock, etc.). But I have written at least a dozen fairly full-featured AIR applications since we started working on the runtime, and I have never come across a cross-platform problem that I couldn't solve. In some cases, I've had to write layers of abstractions, and in some cases I've opted to completely avoid things like menus and focus instead on making functionality better integrated in the UI (which I believe is the trend in software development anyway &mdash; look at Microsoft Office 2007, the iPhone, and many of the best Mac applications). But the extra work I've had to put into making sure my apps ran seamless across platforms was often nothing more than an afterthought, and certainly negligible compared to the advantages of anyone on almost any desktop system being able to run my app. This point was really driven home when I first started using <a href="http://weblogs.macromedia.com/cantrell/archives/2008/02/air_development.cfm">AIR on Linux</a>. I'm a big Linux fan, and the idea of not just being able to run the same apps on Linux that I run on Windows and Mac, but actually <em>develop</em> those apps on Linux as well, is incredible satisfying and liberating.</li>
  <li><strong>Today there are millions of new desktop developers.</strong> The last thing I want to mention is that I feel like we just opened the floodgates on the desktop. I feel like we just did to the desktop what the printing press did to education, or what flexible emulsion film did to photography. I don't know how many web developers there are out there, but I'm guessing there has to be millions. However many there are, there are now that many more desktop developers. Take a second to think about what that means. Someone with knowledge of HTML, JavaScript, Flash, or Flex can now build applications for the web, for Mac, for Linux, and for Windows, and all they have to do is learn a few new simple APIs. (I don't want to speculate too much in this post, but there are plans to bring AIR to even more places in the future.) Not only can they developer <em>for</em> all those different platforms, but they can develop <em>on</em> all those different platforms using all the same IDEs and tools they used before, and they can get everything they need (SDKs, etc.) entirely for free. Web developers have just been given an entirely new world, and everything they want is there for the taking.</li>
</ul>
<p>I've been in the software business for 10 years, and I've worked on all kinds of projects. I've been fortunate that I've never had to work on a project that I didn't like or believe in. But I believe AIR is the most important project I've ever had the good fortunate to be involved with. I can't wait to see what the world does with it.</p>]]>

</content>
</entry>
<entry>
<title>AIR Development on Linux</title>
<link rel="alternate" type="text/html" href="http://weblogs.macromedia.com/cantrell/archives/2008/02/air_development.html" />
<modified>2008-02-21T20:17:05Z</modified>
<issued>2008-02-21T20:14:50Z</issued>
<id>tag:weblogs.macromedia.com,2008:/cantrell/5.14714</id>
<created>2008-02-21T20:14:50Z</created>
<summary type="text/plain">It&apos;s amazing enough that I&apos;m writing desktop applications using web technologies like Flex, ActionScript, JavaScript, and HTML, but to be able to deploy them with no changes across Mac, Linux, and Windows is seriously revolutionary. The idea that I can actually go back to using Linux day to day, and still be able to do AIR and Flex development is very liberating.</summary>
<author>
<name>cantrell</name>

<email>ccantrel@adobe.com</email>
</author>
<dc:subject>Apollo</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.macromedia.com/cantrell/">
<![CDATA[<p>I used to use Linux every day for about four years before coming to work for Macromedia/Adobe (over five years ago). My favorite tools were <a href="http://mkaz.com/ref/unix_screen.html">Screen</a>, <a href="http://www.washington.edu/pine/">Pine</a>, <a href="http://thekonst.net/centericq/">Centericq</a>, <a href="http://www.xmms.org/about.php">XMMS</a>, and <a href="http://www.vim.org/">Vim</a>. My window manager of choice was <a href="http://www.fvwm.org/">FVWM</a> which was doing fast and stable virtual desktops before anyone even knew what virtual desktops were. But I had to leave all that behind when I moved over to the world of Flash and Flex development. Fortunately I had OS X to help me make the transition, but as much as I've come to love Macs, I still sometimes miss the good old days of Linux.</p>
<p>So a couple of weeks ago when I heard that the Linux version of AIR was ready for testing, I dropped everything I was working on and set up <a href="http://www.ubuntu.com/">Ubuntu</a>, <a href="http://labs.adobe.com/technologies/flex/flexbuilder_linux/">Flex Builder on Linux</a>, and installed <a href="http://labs.adobe.com/technologies/air/">AIR</a>. I keep all of my AIR application code on <a href="http://code.google.com/u/christian.cantrell/">Google Code</a>, so I installed SVN, checked out the latest versions of all my projects, and started running my AIR applications completely unchanged on Linux.</p>
<p>I use a MacBook Pro for development now, and I have Windows XP and Ubuntu virtual machines set up. I now have complete development environments including Flex Builder, AIR, and SVN on all three virtual machines, and all of my apps run across all three different operating systems (with the exception of some apps which use features we haven't implemented yet on Linux &mdash; it's still in pre-beta).</p>
<p>It's amazing enough that I'm writing desktop applications using web technologies like Flex, ActionScript, JavaScript, and HTML, but to be able to deploy them with no changes across Mac, Linux, and Windows is seriously revolutionary. The idea that I can actually go back to using Linux day to day, and still be able to do AIR and Flex development is very liberating. And now wherever there are gaps in Linux applications, I can just build them myself in AIR (like <a href="http://code.google.com/p/lineup/">Lineup</a>, an Exchange calendaring client that will enable me to view my meeting schedule on Mac and Linux as easily as on Windows).</p>
<p>As I said, the Linux version of AIR still needs more work, and is currently in pre-beta. If you're a Linux user, and you're interested in getting your hands on early builds and helping us do some testing, check out <a href="http://www.jamesward.org/wordpress/2008/02/20/adobe-air-on-linux-pre-beta-testers-needed/">this post by James Ward</a> to find out how to get involved.</p>]]>

</content>
</entry>
<entry>
<title>Transparent HTML in AIR</title>
<link rel="alternate" type="text/html" href="http://weblogs.macromedia.com/cantrell/archives/2008/02/transparent_htm.html" />
<modified>2008-02-20T17:32:43Z</modified>
<issued>2008-02-20T17:31:18Z</issued>
<id>tag:weblogs.macromedia.com,2008:/cantrell/5.14707</id>
<created>2008-02-20T17:31:18Z</created>
<summary type="text/plain">I keep forgetting how to do this, so I&apos;m going to blog it once and for all.</summary>
<author>
<name>cantrell</name>

<email>ccantrel@adobe.com</email>
</author>
<dc:subject>Apollo</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.macromedia.com/cantrell/">
<![CDATA[<p>I keep forgetting how to do this, so I'm going to blog it once and for all.</p>
<p>First of all, it's possible to have transparent HTML in AIR. I don't just mean changing the alpha of the HTML Flex component. That's one way to do it, but that's not terribly useful. I'm talking about entirely knocking out the background of an HTMLLoader (formerly know as the HTMLControl) so that you can do very cool things like custom HTML chrome. I like it because I often use the HTMLLoader to render large amounts of text in AIR, like &quot;help&quot; or &quot;about&quot; pages, so making the background transparent can let me do some cool effects and presentations.</p>
<p>There are three things you need to know about making HTML transparent in AIR:</p>
<ol>
  <li>Set the <code>paintsDefaultBackground</code> property of the HTMLLoader to false. This specifies whether the background of the HTML document is opaque or not. If you're using the Flex HTML component, you can do this using the <code>paintsDefaultBackground</code> attribute on the HTML MXML tag.</li>
  <li>Make sure that your HTML document does not have a background color explicitly specified. For instance, setting <code>background-color</code> to anything will prevent this from working.</li>
  <li>If you're using the Flex HTML component, make sure the <code>backgroundAlpha</code> property is set to 0 (this is the one I always forget). Also, don't mess with the <code>opaqueBackground</code> property.</li>
</ol>
<p>Ok, now that I have saved cumulative years of searching and trial and error, I expect that time to be reinvested into building even more cool AIR apps!</p>]]>

</content>
</entry>
<entry>
<title>How to Make Application Icons Appear During AIR Development</title>
<link rel="alternate" type="text/html" href="http://weblogs.macromedia.com/cantrell/archives/2008/02/how_to_make_app.html" />
<modified>2008-02-15T18:54:20Z</modified>
<issued>2008-02-14T17:50:12Z</issued>
<id>tag:weblogs.macromedia.com,2008:/cantrell/5.14693</id>
<created>2008-02-14T17:50:12Z</created>
<summary type="text/plain">If you&apos;ve started building an AIR application, you probably noticed that your application icons don&apos;t appear when launching your app via ADL. Fortunately, I&apos;ve found an easy way to work around this issue.</summary>
<author>
<name>cantrell</name>

<email>ccantrel@adobe.com</email>
</author>
<dc:subject>Apollo</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.macromedia.com/cantrell/">
<![CDATA[<p>If you've started building an AIR application, you probably noticed that your application icons don't appear when launching your app via ADL (ADL is the AIR Debug Launcher, and is what Flex Builder uses to launch and debug your apps). Platform specific icons are created from the PNG files referenced in your application descriptor file at install time which means they aren't available during development. It would obviously be too costly to generate those icons every time you wanted to launch or debug your code.</p>
<p>This typically isn't an issue because you usually don't need to see your application icons during development. However, there are times when you do. For instance, if your application uses a dynamic dock icon, it's nice to be able to see the &quot;before&quot; icon before seeing the &quot;after&quot; version. I've also found that it's nice to be able to try an icon out for a while during the development process to see how you like it over time which means it should appear every time you debug or launch your app.</p>
<p>Fortunately, I've found an easy way to make this work. Here's what you do:</p>
<ol>
  <li>Make a copy of your application icon and name it something different. One version should be referenced by your application descriptor file, and the other will be compiled into your application. (You don't technically have to make a copy of the icon, but when generating a release build of your application, Flex Builder doesn't copy over embedded resources which means your application icon will be missing. Trust me when I tell you that it's easier to create a copy and avoid this whole issue.)</li>
  <li>Compile the copy of your application icon into your application using code like this: <code>[Embed(source=&quot;assets/application.png&quot;)] public var appIconClass:Class;</code></li>
  <li>In your application's initialization code, create a Bitmap instance of your icon like this: <code>var appIcon:Bitmap = new appIconClass();</code></li>
  <li>Set your icon like this: <code>InteractiveIcon(NativeApplication.nativeApplication.icon).bitmaps = [appIcon];</code></li>
</ol>
<p>This code is a little oversimplified because it doesn't take platform differences into account. A more complete implementation might do something like this:</p>
<ol>
  <li>Check to see what kinds of icons the client supports. You can do this with the <code>NativeApplication.supportsDockIcon</code> and <code>NativeApplication.supportsSystemTrayIcon</code> APIs.</li>
  <li>Scale the Bitmap to the appropriate dimensions for the platform.</li>
  <li>Set the icon(s) using the NativeApplication's icon property.</li>
</ol>
<p>Since I usually use the Cairngorm framework, I like to create an UpdateIconsCommand which takes care of creating and setting dynamic icons for me. I also like using the <a href="http://code.google.com/p/as3notificationlib/">as3notificationlib</a> project to help encapsulate some of the platform differences in setting icons.</p>
<p>For a real world example of setting dynamic icons, see my Exchange calendaring application called <a href="http://code.google.com/p/lineup/">Lineup</a> (currently being updated to work with Exchange 2007). It sets icons at runtime and even dynamically generates custom icons, all in a way that works well across platforms.</p>]]>

</content>
</entry>

</feed>