Tcoz Tech Wire

Discoursing on trends and technologies interesting to Tim Consolazio, sole proprietor of Tcoz Tech Services, specializing in Flash/Flex/Air, iPhone, Facebook, Twitter, and related technologies.

"Technology from an indie software developer's perspective".

Monday, June 22, 2009

TcozTwitter: A Twitter Client using Adobe Air and the Flex Mate Framework - Day 7: Running on the iPhone...really?

This post covers my progress developing a Twitter client using the technologies mentioned in the article title, but also takes another interesting turn. I've been working on the side with Citrix to understand their latest XenApp Server product, and how a Flash/Flex/Air developer might be able to leverage it. To this end, I decided to branch my Air code base, and use what I've already done to drive forward a version of TcozTwitter that could be delivered on the iPhone...or any mobile device for that matter.

Notice I said “branch”, not “start all over again with a different technology”, and “any mobile device”, not just “iPhone”. Those are the important things to get here. More on that in a minute.

If you're interested in the history, links to all the previous blog articles are at the end of the article.

To summarize, here's the “thin line” of technologies you'll need to be familiar with, if you want more detailed summaries, look at the links at the bottom of this article:

Amazon EC2 Cloud and S3. EC2 is essentially a vast pool of processing power that you can isolate a piece of to run whatever you need. I frequently liken it to a ball of clay; you grab a chunk and shape it the way you want; when you're done, you take a snapshot of the configuration (so that you can “restart” it from where you left off), and put the chunk back on the bigger ball. S3 is “Simple Storage Service”. It's basically a huge pool of storage space that you can access via an API or one of many downloadable clients. When you take your “snapshot” of your “chunk” (or in EC2 parlance, when you “bundle” your “instance” into an “AMI”), the AMI is saved to a “bucket” (essentially a directory) that you've previously created in S3. When you “restart” your instance, you point to the configuration file that gets stored with your AMI data, fire it up, and there ya go.
XenApp Server and Desktop. There's a lot to this technology, but I'm focusing on the iPhone-tweaked version of the product, which you can read about here. Briefly, XenApp and Desktop are server-side software that “virtualizes” applications and allows you to view them over a variety of different clients. You install whatever app on a server—any technology that the server supports is fine—then “publish” it via the XenApp software so that it can be accessed remotely by Citrix Viewer and Receiver clients. Citrix has published an AMI in the EC2 cloud that you can use to experiment with. Remember, an AMI is a saved configuration, ready to go. All you need to do is go the cloud, fire it up, install your app, publish it, and remote clients can access and run it. The Citrix XenApp AMI is a demo that times out in three months; plenty of time to learn your way around.
Flex/Air, and Mate. Flex is an ActionScript 3 component framework used to build applications that run in the Flash player, Mate is a Flex-specific framework, heavily leveraging MXML, to simplify and organize building applications with Flex and ActionScript 3. I'm using Mate purely to familiarize myself with it. I'll say this; compared to other frameworks, it's pretty easy to get your head around, and it does simplify a lot of tasks. I have some concerns, but that's true of any prescribed development approach.
The iPhone. Enough said about that I think, and then some.

You'd be surprised, once you know exactly how it all works, how easy it is to set this all up and get basic applications working. I can publish an app, or an app update in a matter of minutes.

Here's some screenshots of my Twitter client, running on the iPhone, using all the above mentioned technologies:

It really works, even over EDGE on an OG iPhone (as I write this article, I'm actually expecting the delivery guy with my new 3GS 32mb Black. UPDATE, I have the new iPhone, and the Citrix stuff runs great over the 3G network). I leave it up and running on my iPhone while it's docked to see my tweets come in without any page refreshes and whatnot.

I also have to say, Citrix' luminaries Chris Fleck and Ray Yang have been great. When I started my experiments, I pinged them with a few questions, and they've been supporting my efforts with tech info and advice ever since, because they're interested in my perspective on these technologies.

It's that perspective that, perhaps, makes this all interesting, so much so that TechCrunch published a story on my findings that stayed on the front page of their site for weeks and sparked a lot of debate, mostly revolving around “There's no need for Flash on the iPhone,” and “why don't you just build a native app”. Flash is a great candidate for building mobile apps. The industry just seems to have a variety of issues that prevent it from getting out there on mobile devices, and I have good reason to believe they're not primarily technical ones.

Anyways, I'm an independent developer; in a nutshell, that means I go from contract to contract, building various kinds of applications for various kinds of clients of all sizes. I've worked for Microsoft, Viacom, Thomson Reuters, IAG Research, American Express, CitiGroup, IEEE/Spectrum, and a slew of smaller shops and startups. I'm pretty proud of my portfolio, and I work hard to stay cutting edge; I run servers to host all kinds of development environments and server software, like Flash Media Server, TomCat, BEA WebLogic, MAMP, Red5, Blaze, Ruby/Rails, .Net, Air, SVN, FTP, mySQL, SQL Server, Oracle Comm. Edition, etc. etc.

It's a lot of work, and isn't cheap; sure I write it off, but I have to do the cash layout, and admin/maintain them. IMHO, it's necessary; a good independent developer should know how to put together a good development and staging environment in just about any technology.

So, enter the Amazon EC2 cloud. Now, I can spin up instances of virtually any kind of development environment...install this and that software/app/ the configs and shut them down...for about 10 cents an hour. After doing the math, that works out to about half what I pay now for a fully dedicated hosted box at a solid host company, and that's only if I leave it up and running 24/7. It's WAY flexible. For staging and development testing, it's fantastic.

However, most of what I do for a living involves Flash development. I love the iPhone and have learned Objective C, got my business accepted into the dev program—it turned out to be more than a matter of just paying for it to my surprise—and so on. But I've been working with Flash for a decade, and it's a big disappointment that Flash doesn't run on it.

Enter XenApps, which Citrix makes available as a demo AMI config in the EC2 cloud. All I have to do is select the AMI, launch it, and I'm looking at a clean build of Windows Server 2k3 with XenApps, Desktop, and all that; everything I need to work with to see if I can deliver a Flash/Flex/Air application to an iPhone.

I settled on Air, mostly due to the fact that Air doesn't deal with browser security and sandboxes the way that Flash/Flex do; Air is a native runtime, with it's own encrypted data store and access to NativeWindow and other elements that make it a fairly powerful RIA desktop development environment. Crossdomain and such isn't a hassle as well. You can also publish an Air app (which, on Windows, is an .exe) in a very straightforward way from the XenApp environment, as opposed to using AppViewer, which is a .Net app Citrix distributes that you run in lieu of your actual SWF by pointing it at the web page that embeds it. It works and works well, but I figured why bother with web pages and such if I can just run my Flash app in a native runtime environment without the involvement of the browser footprint.

The connection should be evident; there I was developing a Twitter client in Flex Builder, and publishing it to Air, using the Mate framework. So I decided to marry the two efforts, and see if I could branch my slowly developing Twitter app—it's hard to find spare time, but I fit it in now and then—and see if I could tweak it for delivery to the iPhone via XenApps.

Yay verily, it worked; I installed the Air runtime on the Windows instance, installed my Air TcozTwitter client, published it through the XenApps server, and pointed the iPhone Citrix Receiver at it, and there it was, touch enabled and all. True, I had to rethink the UI in terms of the iPhone. I've had people say that Flash apps won't port directly to the iPhone because they use mouseovers and such—think about it, the iPhone doesn't have “fingerovers”, which is interesting—but that's true of any technology no matter what. As a UI developer, you have to look at the device, consider the interactivity, and develop your app, using your given technology, in that context. If you factor your code well and the UI is truly abstracted, this isn't that big a deal though at all, certainly a heck of a lot less work than writing the whole thing all over again in Objective C...and then Symbian...and then Android...and then Windows Mobile...and then Blackberry...and whatever else winds up getting cranked out of BigTech Labs XYZ.

Here's points I found to be VERY interesting about this manner of development:

I'm not an “enterprise”, I'm an independent developer. But, I don't just write code for clients, I build things off to the side to keeps my chops fresh and who knows, maybe make some money. I find that this technology, although created by Citrix which is typically associated with “enterprise”, works for me. The Citrix guys seemed to find that interesting too. A library of demo apps that I can bang off a single EC2 instance is also a powerful demo tool for landing contracts. As I mentioned once before, I could probably get work just by having put all this together.
With just UI refactors, I can roll out the same codebase to any mobile device that Citrix has written a Receiver for. They've covered a number of them, see their website for more info.
The XenApps “tweaked” version I'm working with, via the Receiver, presents your apps as a selectable library; so, the user downloads ONE app (the phone-specific Receiver), and they can access ALL the apps that I publish though XenApps.
Consider the above...all I have to do, to deploy a new app to my entire userbase, or update one, is install it on my EC2 instances, which you access via RDP or the Citrix Receiver desktop app (I use the Mac version). No app store approval iterations. It'll be interesting to see how this shakes out.
Because the app runs on a regular server, I don't have the development restrictions inherent on the iPhone. I can make any number of network connections of any kind, store data in a variety of ways locally, and whatever else I need to do. The available technology I can use to drive my apps is essentially unlimited.
For proving out concepts and getting user reactions, this can't be beat. I can build apps rapidly in one codebase, get them deployed to all kinds of devices, and see what users think. What hits on a Symbian may not hit on an iPhone. Depending on the reaction, I can decide to build a native app, or abandon the effort for a given platform.

There are some things I have yet to figure out, the Citrix guys say they are interested in helping me find solutions:

Encrypted data store in the Air runtime is having some issues; I believe these are probably related to the permissions that XenApp is using to run apps under; some server config will probably solve this, if not, I can always just dump everything to a SQL DB or some such.
iPhone mechanisms, like the auto-complete for text, the new cut 'n paste, and such, don't work, because the app isn't actually running on the phone. Fixable, because I can just build the capability into the application, and just make sure I emulate the iPhone look 'n feel. The investment of time can in fact give me the same look and feel consistently across any device...nice for my end users on different platforms, and of course very useful looking forward to things like NetBooks and touchscreen e-readers.

Will I abandon building native apps for the iPhone, and whatever else I find the time to learn how to build apps for? Of course not. There's money to made out there, and different development technologies is something I'm interested in. So, the Objective C book and Xcode will still take up space on my hard drive, and be frequently used.

But, if I work with a client that needs apps rapidly deployed to a variety of devices, without going through the rigor of building multiple versions and maintaing multiple code trees, will I be glad that I learned how to do this...and, will I continue to ensure that apps I build are constructed in such a way where I can branch and get a version running on the iPhone this way in relatively little-to-no time?

You bet. Citrix has most definitely found a place in this independent developer's toolbox.

I wonder how many other contract Flash developers have said that.

As always, thanks for visiting.

Article Links:

TcozTwitter: A Twitter Client using Adobe Air and the Flex Mate Framework: Day 1, Day 2, Day 3, Day 4, Day 5, and Day 6.

Flash/Flex...on the iPhone? Initial Exploration, Follow up with Citrix.

Why the Amazon EC2 Could and S3 is a great thing for the independent developer, Article Link

Labels: , , , , , , , , , , , ,

Wednesday, June 17, 2009

TcozTwitter: A Twitter Client using Adobe Air and the Flex Mate Framework - Day 6: Running on the iPhone

It's been a few days since my last post, but I've been VERY busy. Swift3d V6 is out (it's great 3d modeling and animation software, very Flash and Papervision friendly), I'm still skilling up my iPhone dev chops, I'm digging in to Flash Media Server 3.5.2, my current contract is coming to release (V1.0 of Thomson Reuters Insider), and...well, you get the idea.

If you've been following my blog, you know I've been working with Citrix to use their XenApps image in the Amazon EC2 cloud to deliver Flash/Flex/Air apps to the iPhone using the Citrix Receiver. You can view the previous post links on the right of the blog page, or search for "iPhone" and "Citrix" tags to review previous posts on how I'm going about this.

I've got the issues sorted for the most part: design parameters for an iPhone app delivered this way, how to get rid of the Adobe Air EULA so that users don't have to click through it, and so forth. I've even got ads integrated (I'm running an OpenAds server that I've set up a couple of campaigns on for friends that own ads for them, proof of concept for me).

I'm going to put up a full blog post on the issue, but for now, here's a picture of what I'm looking at on my iPhone. I just leave it up in my iPhone doc, and see my tweets come in without any refreshes; it's a fairly real-time twitter client. I've even tried it over the EDGE network, it works fine (remember, that client is actually not running on the iPhone). No awkward refreshes like standard VNC or RDP, etc.

With this as a base, adding features to complete the functionality is pretty straightforward. I'll be adding a login screen (right now it just uses my creds), a post-tweet screen, a fancy loader, and all that. But it's all just Flash development at this point, the mechanism to deliver it to the iPhone running as a native app, all I need to do is update the Air app on the EC2 cloud instance to deploy a new version; users of the Citrix Receiver won't have to update the app, they'll just have to restart the Citrix client.

Pic below, detailed blog post in next couple of days. Interestingly enough, there's not that much to tell. If you know how to put it all together, it's actually pretty easy to set it all up.

Labels: , , , , , , , ,

Friday, June 12, 2009

TcozTwitter: A Twitter Client using Adobe Air and the Flex Mate Framework - Day 5 : Multiple views, control bar, and Mate wishlist item

This is a continuation of a series of articles on my experiments with writing a Twitter desktop client using the Twitter API, the Mate Framework for Flex, and Adobe Air. Previous blog posts are here at Day 1, Day 2, Day 3, and Day 4.

This time around, I decided to get two views working: the public timeline, and my own @tcoz_tweet timeline, the latter of which is made up of my own tweets, and tweets by the members I follow.

To accomplish this, clearly I needed a way to organize different list views, and a way to switch between them. From a UI perspective, naturally a control bar seemed to be the way to go. Anticipating this, I'd already left some space at the top of the application above where tweets appear, and it turned out to be just enough; 35 pixels to be precise.

A quick look at the current state:

Starting to finally look like something isn't it? This might not be my final design, but it serves the current purpose, and doesn't look all that bad. Notice the "next" button, which currently doesn't do anything--there's nothing to go "Next" to yet--but from a forward-looking perspective, I plan on integrating search, profile views, that sort of thing. It seemed like a good idea to assume I'll need more room than what's in that one strip.

If you're curious how I'm doing the skinning, note that there are no embedded or static images of any kind being used as backgrounds for the tweets, the buttons, or any other such thing; everything is done with the AS3 drawing API. The matrix object makes gradient fills very easy--well, compared to how they used to be--with the createGradientBox utility method. Here's a sample of how I put together gradient fills:

var matrix : Matrix = new Matrix ( );
matrix.createGradientBox ( width, height, Math.PI / 2 );
graphics.beginGradientFill ( GradientType.LINEAR, Model_Config.getInstance ( )._tweetColors, [ 1, 1 ], [ 128, 255 ], matrix );
graphics.drawRect ( 0, 0, width, height );
graphics.endFill ( );

Note that I'm pulling the colors for the gradient off of my Model_Config object and applying it to the graphics object of my view. In my coding style, Models are frequently singletons, and if you recall from a previous article, I populate this model with data from an XML file, which the user can edit to alter the appearance of certain UI elements, like the background colors of tweets (again, thanks for the inadvertent feature request iJustine). Some may say that I should be accessing the data through a proxy, and that accessing Models directly is evil, and in a larger effort, I'd tend to agree. But the deeper I get into this app, the simpler I think it is. Writing a twitter client with even some semi-advanced features isn't all that difficult.

Now, you notice that I have two buttons that matter at this point: My Timeline, and Public Timeline. Click one, see one, click the other, see the other. Again, from a previous article, you know that I'm pulling collections of objects from the Twitter API, and binding them into lists. To toggle these list views, I decided to use a flex ViewStack, and it works like a charm.

If you're not familiar with ViewStack, it's a component that makes it easy to swap the currently visible view. All you do is set the selectedItem property on it to bring the desired view to the top: 0 is the first item in the stack, and so on. Here's the code:

<mx:ViewStack id="timelineViewStack" width="100%" height="100%" creationPolicy="all">

<mx:Canvas label="My Timeline" width="100%" height="100%" backgroundAlpha="0">
<mx:TileList id="userAndFriendsList" backgroundAlpha="0" borderStyle="none"
height="100%" width="100%"
paddingBottom="0" paddingTop="0" paddingLeft="0" paddingRight="0" />

<mx:Canvas label="Public Timeline" width="100%" height="100%" backgroundAlpha="0">
<mx:TileList id="publicList" backgroundAlpha="0" borderStyle="none"
height="100%" width="100%"
paddingBottom="0" paddingTop="0" paddingLeft="0" paddingRight="0" />


Pretty simple; the ViewStack is a top-level MXML wrapper. In it, I've got a stack of canvases which act as the swappable views. Inside those canvases, I have my TileList components, which is what I bind my data object arrays to. The TileList takes that array of objects, creates a specified ItemRenderer for each one, and passes it one of the data objects, which has properties that map to a tweet, like name, thumbnail url, etc. The specified item renderer receives that object, which is automatically available as instance name "data", and binds the properties to the UI elements where I specify. Here's the internal of my ItemRenderer, which will power all of the TileLists that display tweets (properties like x/y and such omitted for clarity):

<mx:Image source="{ data.user.profileImageUrl }" />
<mx:Text text="{ }" />
<mx:TextArea text="{ data.text }" />

That's it! The Flex framework makes this pretty easy. It's completely extensible: I make a new API call, like search for tweets, I get back an array of objects from the Tweetr, or my own (I'm currently using both) library. I drop another TileList into the ViewStack, and bind the data to it. I put up a button, which when clicked, sets the selectedItem property of the viewstack, which makes the desired view appear.

Now, onto something I discovered about Mate. First of all, I have found myself really liking that when I need to dispatch an event from anywhere at all, all I need to do is either do it from a view or from a Mate GlobalEventDispatcher, set it to bubble, and add the handler to my EventMap, which directs it as needed.

But...there's something missing. Take a look at this code from my evolving EventMap:

<mate:EventHandlers type="{ Event_ControlBar.SELECTED_MY_TIMELINE }" debug="true">
<mate:MethodInvoker generator="{ Manager_States }" method="changeTimelineState" arguments="{ someComputedArg }" />

<mate:EventHandlers type="{ Event_ControlBar.SELECTED_PUBLIC_TIMELINE }" debug="true">
<mate:MethodInvoker generator="{ Manager_States }" method="changeTimelineState" arguments="{ someComputedArg }" />

Note that both of these event handlers call the same method on the same Manager object.

I would very much like to have been able to do something like this:

<mate:EventHandlers type="{ Event_ControlBar.SELECTED_PUBLIC_TIMELINE | Event.ControlBar.SELECTED_PUBLIC_TIMELINE }" debug="true">
<mate:MethodInvoker generator="{ Manager_States }" method="changeTimelineState" arguments="{ ( someComputedArg ) }" />

The difference here is, I've set the event handler to accept two events as the trigger with a bitwise OR. So, if either of those events are received, the argument can be determined and passed along to the Manager. This would also be useful for bitwise exclusions, and so forth.

As far as I can tell, there is no way to do this directly in the EventMap in Mate. Every time you need to receive a different kind of event, even if it's the same arguments, same Manager, same method, etc., you have to create an entirely new MXML fragment and place it in the EventMap.

In AS3, I'd typically do something like this:

myObj.addEventListener ( MyEventClass.EVENTONE, onMyEventClassEvent );
myObj.addEventListener ( MyEventClass.EVENTTWO, onMyEventClassEvent );

private function onMyEventClassEvent ( event : MyEventClass ) : void
if ( event.type == MyEventClass.EVENTONE )
// do something
else if ( event.type == MyEventClass.EVENTTWO )
// do something else

I'm looking further into this, but so far, after searching through the docs and such, I've found no indication that you can use a common handler for multiple event types. It might be possible with a standard if statement or some such, but I was really hoping for the elegance of bitwise operators.

This is one of my misgivings about Mate, and MXML in general; it's VERBOSE. WAY more verbose than straight code. I suppose that might just be a point of view; some people may prefer the hierarchy of nested markup. At this point in time though, I don't.

Anyway, that's it this time around. As always, thanks for visiting.

Next up: refreshing Tweet lists, ensuring I only add the most recent tweets, which means, either issuing a request based on the time of the last received tweet, or just receiving the bulk and trimming off the ones that I've already got in my list.

Labels: , , , , , , ,

Thursday, June 11, 2009

Flash Catalyst: Why I'm not so sure this is a good idea.

If you read this blog, you know I'm a Flash/Flex/Air type developer. I've been working with these technologies in one form or another since ActionScript was called Lingo, and I know where the FS in FSCommand comes from.

To make my point early on, I am having serious reservations about Catalyst. I saw a live presentation from Adobe yesterday introducing the Catalyst beta, in which I feel the presenter sidestepped my questions regarding how Catalyst was actually a step back, not forward. I've downloaded and played around with the tool, and while I think it's a remarkable GUI authoring environment, I believe that it is going to reintroduce a variety of workflow and stability problems that were finally getting solved with Flex.

Catalyst, which is marketed as, "Adobe® Flash® Catalyst™ is a new professional interaction design tool for rapidly creating user interfaces without coding.", is detailed at the Adobe Catalyst Beta web site.

Now the discourse:

As an independent, I've worked on teams of all kinds, every shape and size, in a variety of different business verticals: entertainment, media, financial, you name it. After a while, you get a notion of what works, and what doesn't. When I get pinged about a project, I've gotten pretty good at anticipating what I'm getting into based on the project description, who was involved before, and what the current state is.

One of my biggest nightmares in the ActionScript world is getting involved in a project where, "the code is already written, we just need some changes and fixes to be made." Naturally, I always respond with, "why can't the original developer do it?" The usual reply, "oh he's not available." This may be the whole project, or just a piece of it, but the result is the same.

I've come to know, that almost without variation, this actually means:

"We had some great visual concepts for this application we wanted. We interviewed a number of developers that talked about things like wireframes, functionality, and specs. It seemed complicated and time consuming, we wanted immediate gratification. We found a guy who had this great looking website, really good design, who said he knew Flash. So we hired him. It was going along great, really fast, but when we requested some new features, and changes to old ones, and integration of some new data, the developer turned out to be unavailable."

I have visions of this designer, who at best may have understood a handful of canned script procedures, furiously googling ActionScript samples, hunting down code scattered all over named timeline frames, looking at a library of unnamed assets that was allowed to get out of control, posting "can anybody help me" on the boards...

...and now the client wants an "expert" (vis a vis, "somebody else to share the blame") to come in and clean it all up. No documentation, no access to the developer, or at best a hasty email saying "it's all on frame 2 just look at the code", missing external assets, often not even a project that will compile.

This isn't a once-in-a-while scenario. I see it ALL the time. When I was making my bones as a contractor, I'd take these jobs. Now I avoid them like the plague, because they're losers. Why? Because the client will feel that because it used to work, or currently does but just not the way they want it to, it should be cheap and easy for an "expert" to get it running as required.

What they don't know is, the project is a disaster, there's virtually no unravelling it, and even if you can, huge portions of it will need to be rewritten anyway in order to get the extended features working properly...

...but, they cry, "Flash is a visual development environment. It's supposed to be easy to create interactive widgets. I don't understand why OOP, or documentation, needs to be involved with this at all. We're not looking for an application per se, we just want this little bit of video/playlist/data functionality, but instead of doing it this way, we need some changes. We need you to be flexible."

This is what happens when designers are put either in charge, or at the top of the process, of actually building software.

If you're a designer, you're probably insulted now. Stay with me, I think you'll see what I mean. If it helps to keep you reading, I have IMMENSE respect for a designer that understands how to work with a software developer. It's just that the overwhelming majority of "Flash" designer/developers don't, because they assume that coding is secondary to design. I know it for a fact.

If a coder makes comments about design, the designer will certainly not take it as authoritative. Why? Because a coder != designer. If you've taken it upon yourself to study both design and coding properly, more power to you. But in general, a coder may have some design ability, or a designer may have some coding ability, but the "some" is secondary, it's not a studied, practiced, primary skill.

Flash is not a design tool. I don't care what Adobe tells you, or what you've seen people do with the vector drawing tools. Flash is a tool used to build interactive, web-based software. Call them widgets, call them stand-alone components, call them "players", call it "a design-time scripting environment that builds interactive media", whatever. Those are euphemisms.


No, Flash isn't for building operating systems. It doesn't have to be. An extension on the house for grandma, or a new hi-rise on the waterfront, are both "buildings" created through the process of "construction". You have to get permits, zoning, you need blueprints, good material, and a knowledgeable contractor with specific skills.

If you've ever watched BBC, there's a show called "How Not To Decorate". These two Brit designers ("the Lads") go into these nice homes that are atrociously decorated, and have them restructured to accommodate their design vision...THEN they add the design. I love this show because I see it as being directly analogous to software development. Do you see these guys selecting foundation materials, or trying to put cushions in the room before the builders say "ready"? Do you see them working without blueprints, only using their comps? Do you see them trying to find tools that build foundations without doing any digging?

No. You don't. They recognize their expertise, and work within the boundaries of their roles. They hire top-notch builders to explain to them what can and can't be done in terms of the design concept. They push the builders, but in the end, when the construction lead says say "not with this budget, not in this time, not in this space, not in this ground", they accept the limitation and rethink. They are integrated in the process, they attend the meetings when it makes sense, in fact, they are in charge. But they don't actually do the construction work. And in the end, they never get "pixel perfect" according to their original design vision; they work with the finished structure, rethink some of the concepts, and succeed. They don't say, "my comp shows this 10 inches this way. Tell the builders to tear down the wall and rebuild the room."

WHY does this basic, obvious, logical and sensible thinking, fall apart when it comes to Flash? There are so many bad examples to prove it, so many that Flash is easily maligned by all the "Web 2.0"--whatever that is--fanbois (apologies to Mr. O'Reilly) as being unstable and bulky garbage.

A few years ago, enter Flex. Adobe takes a stand: Flash development is about CODE, and that means, CODERS. I saw an Adobe presenter proclaim this vehemently in both the presentations I saw him give. The designers were up in arms; how dare you! I'm a designer, I don't want to have to learn about code. I want the tool to do it for me. You are ruining my livelihood!

No, we're not. We're simply giving you the opportunity to do what you do properly. Flex has a great workflow for this; finally, architects and coders were back to doing the construction. Designers were integrated where it made sense; they created assets based on areas of the project that are completed and stamped "ready" by the builders. They worked on the CSS and images in Photoshop and Illustrator, burned them up into vector images and/or swfs, or whatever, and placed them as static assets or libraries, ready to be applied to the finished components. It's a solid workflow.

The job boards are the evidence: enterprises are starving for Flex developers, because at last, it seems like we're getting some stable software out there. Flash isn't a toy after all, you just have to apply professional workflow, to any size project, to get it running. Architects and coders lead construction. Designers create vision and assets, which are integrated when the time is right. That's how you build things. Event "the Lads" know that.

Yesterday, the Adobe presenter said that Flex put code and development first, design second, and that they saw this is being "backwards"; the fix is Catalyst. Designers would once again be given a tool which, with very little or no code, they can use to take their designs FIRST, and THEN apply code, which is auto written.

He even went so far to say that the Flex developer can view the code, and edit it as necessary. Oh-my-gawd...say it isn't so. You are actually saying it's a good idea that I work with code whacked together by somebody that knows nothing other than how they want it to look, and maybe has a rough notion of how it should work? And that they should be doing this on their own in a completely different development tool?

Think of it this way: why doesn't Adobe create a tool that let's programmers auto-generate designs based on wireframe structures? Let us give designers .psd or .ai files with auto-generated and named layers, pre-sized assets, all the rest of it, and let them just clean it up as needed.

Why? Because it wouldn't work. Designers would shit all over it. And they'd be right to. But this is exactly what they did to developers with Flash, fixed with Flex, and are doing all over again with Catalyst. Designers are getting involved in more than design, they are now generating MXML...lots of it. And the Flex developer is going to have to deal with it.

I talked to two other experienced ActionScript coders, that work heavily with Flex, about this. They felt the same way; here we go again. Designers are going to throw stuff over the wall to us and we're just going to have to deal with it. If an event doesn't fire correctly, or a state change doesn't work, we're not going to be able to go back to the designer and say "rework the component". They'll say no, it's not their job. And the client, as usual, will side with the designer, because...designers aren't coders. That's your job, Mr. Flex OOP guy.

Adobe has caved; this is 180 degrees from what they were saying maybe three years or so ago. Once again, they're marketing immediate gratification via Catalyst. Designers will latch onto it because they can make text fields change color when a button is clicked, and the assets will look exactly how they want, but they won't really understand what the tool is generating, because Adobe is telling them not to worry about it, let the Flex guy sort that out.

With all that said, my predictions:

- Catalyst will flood the field, once again, with designers fronting themselves as developers, and when a serious ActionScript guy on the project says, "this stuff is useless, the designer needs to rework the component", everybody will man, that's your job.
- I will end up using Catalyst, because I'll frequently tell a designer, "just send me the assets, I'll rebuild the component". So, Adobe's notion that designers will use Catalyst, developers Flex, is misguided. Exactly as I am frequently forced to crack open Flash to fix these things, so I will be forced to crack open Catalyst.

Can Catalyst be used productively? Sure, if a team discusses the tool with the designers and specifies how exactly it's to be used. Unfortunately, in the world of independent development, that rarely happens. Marketed and prescribed workflows are rarely adhered to in all but the most well-funded, tightly controlled, corporate projects. I've seen startups collapse and corporations throw away piles of money because of this, and I don't think it's entirely their fault. They're being misled into thinking that software development is a commodity skill that should be cheap and on-demand. Design, on the other that takes something special, that's an art.

Ugh. Once again I'm going to hear...

...we had this designer come in, he used Catalyst, so all the code is written. There's a few fixes though, and we need some changes made to extend the functionality...

...and once again, now that I don't need to deal with that BS anymore, I'll hang up.

Labels: , , , , ,

Tuesday, June 9, 2009

Buying the iPhone 3GS: Existing customers, buying from either Apple or AT&T doesn't matter, and woe to the non-upgrade eligible!

Figured I would blog this to put an actual experience buying an iPhone 3GS, with details on upgrades and non-upgrade purchases. Not to mention that...I mean, c'mon. I gotta have a blog post about the new iPhone, and at this point, aside from what everybody already knows from the WWDC, this is all I've got to add.

I'll start with the bad news: if you're not eligible, this article from Boing Boing is the reality:


The article states:

For non-qualified customers, including existing AT&T customers who want to upgrade from another phone or replace an iPhone 3G, the price with a new two-year agreement is $499 (8GB), $599 (16GB), or $699 (32GB). Visit for eligibility information.

Lucky for me, this doesn't apply. I didn't see the upgrade to 3G to be worth it. True I was a little jealous of the network speed now and then and the maps feature on 3g worked better, but the overall ROI just didn't seem to be there. Funny the things people said; the CEO of a startup I did some work for said, "you must not be a power user". I'm just an adult that made a decision based on value.

Anyway, let's talk about upgrade purchase. I have an OG iPhone, have had it since day one. Yesterday I bought a 32gb 3GS iPhone from the Apple Store, right after I got the email following the WWDC, so it was about 6:30 p.m. EST. It cost $299, and the ordering process appeared aware of my current AT&T plan and upgrade eligibility, actually asking me if I wanted to upgrade any portion of it. I also paid for one-day shipping, which was $16 dollars. The total was $337.05 with tax, and the shipping date is June 19th. All this was sent to me in an order confirmation as well, so as far as I can tell, I'm good.

So, to clarify, because people have told me otherwise...THERE IS NO DIFFERENCE BUYING FROM THE APPLE STORE OR AT&T. NONE. The Apple store is aware of your upgrade options and so on, and AT&T customer service told me point blank that it doesn't matter.

Why didn't I buy from AT&T directly? Only because I got the offer email from the Apple Store first, and wanted to place me order ASAP.

Anyway, to nail in the facts, I went to the AT&T site, and checked out both "Add an new Line", and "Upgrade".

This picture was identical for both "add a new line" and "upgrade". Note it's $299.

A visit to the website, a call to customer service, and my email confirmations, confirmed it all. If you're reading this, you have the facts: eligible for an upgrade, the phone will cost you $299, not eligible, it'll cost you $699 for the high end. And there is no difference if you buy it from the Apple store or from AT&T.

I'll tell you this, for that money, I would just upgrade the 3G to the 3.0 OS and forget the new phone; wait for the next one. I just don't see it being worth the money, exactly as I didn't see the 3g being worth the money compared to the original, and, if you're already a 3g owner, you're on the faster network. I have a feeling that, aside from the better camera (which really still isn't all that great) and the bigger capacity for the high end one, there isn't much of a difference to the typical user.

What would NOT surprise me though, is if all of us upgraders get ROOKED six months from now, exactly as we did when the iPhone first released, the price plummeted later on, and they gave us a $100 rebate usable for in-Apple-store purchases (thanks Steve J. for the $87 power cord for my $3,200 first-day Macbook 17). Six months later they'll put out a faster network and another phone on it or some BS like that. Apple has a history of this and it sucks.

But then I'll just resign myself to another two years, and enjoy my new iPhone, exactly as I do my current one. I never lost a contract because I broke out a pre-3G.

There you have it. As always, thanks for visiting.

Labels: , , , ,

Friday, June 5, 2009

Why Amazon EC2 is a great thing for the Indie developer. At least, that's what I'm finding.

I've been working with Amazon EC2 a lot lately. I'll tell ya, this is a great thing for independent developers.

For those of you that don't know, EC2 is Amazon's computing cloud, in which you can run instances of virtually any kind of computing environment for pennies an hour. It's all managed right through a web interface. Go to the Amazon Elastic Compute Cloud website and check it out.

As an independent, I work with different clients all the time. Some use Linux, some Unix, some Windows. That doesn't matter to me per se, because I generally work with technologies that have runtimes for most commercially viable platforms. But, in order to look more professional, I've taken it upon myself to provide clients with a staging server, as well as SVN and FTP repositories. You would be amazed at how many times a client has said to me, "you can do all the staging, AND will set us up with SVN accounts?". Yep, I'm serious about this business, and want to make it as easy as possible to integrate me into your workflow without the hassle of setting me up internal accounts and access for the piece I'm building.

The staging server is a Windows box. The reason for this choice: I can run .Net on it. People frequently ask me, "why do you bother with that," to which I offer canned response, "I'm not going to lose work because I have a religious belief about a given technology". If the client wants .Net web services to power the Flex UI, that's fine with me. If they want Java, or PHP, or Ruby, same thing. All of these technologies are fully available on Windows. The same is not the case with Unix or Linux. People guffaw at this, pointing to .Net implementations on the Unix base, but that's not what clients use. So, to run as many technologies as I can, Windows was the logical choice. I can drop a MAMP server on it for PHP/MySql, run Tomcat and Oracle Comm. Edition for Java, and power IIS with .Net and SQL Server, or any combination of the above, all at the same time.

It costs me money though, even when I'm not using it. About $150 a month to be precise. I host with Liquid Web, which I must say does a GREAT job. GREAT. Their support is on point, and I've never had an outage in more than two years. But fact is, I do most of my development locally, and just do a daily dump it on staging so the client can eyeball it, but otherwise, I store my SVN repos on their, do some experimentation with server products and whatnot, and that's about it. If I want to test on anything other than Windows though, I do it on local virtual machines, like a Parallels Centos VM or some such. Its been a great model for working with all kinds of clients, managing the environments is great experience of course, but...

...enter Elastic Compute Cloud. The concept is this: it's a big ball of clay. When I want a piece, I pull it off; this is my "instance". I can shape it any way I want, and only get billed for when it's active. When I'm done with it, I "bundle" it (essentially a saved configuration) and put the raw material back onto the big ball, which stops billing.

Billing, btw, for a "small instance", which is roughly equivalent to my $150/month hosted box, is 0.125 dollars/hour...that's twelve and a half cents and hour.

Amazon provides you with all kinds of pre-configured instances: Fedora running Ruby on Rails, LAMP, 64 bit versions, Windows Server 2003 and 2008, etc. Additionally, the "community", which is made up of all kinds of platform developers like Citrix and what not, provides Windows, Debian, Fedora, SUSE, Ubuntu, Solaris, Gentoo, etc. images of all kinds, running their databases, VM servers, and what have you. They also put out a lot of demo instances so you can check out new technologies and services...for FREE, all pre-config'd. No downloading, installation issues, and all that. True, it's important to know how something installs, but first, let me see if I'm interested in the technology before I fight with a download and install.

So, here's the scenario. I have a client that works entirely in Linux using MySQL, and they want to see the deployment of my product in that environment. Currently, I can't do it, because my box is Windows; I can certainly demo the product working and use MySQL, but it's not Linux. So, I send it to them and have them deploy it, but that detaches me from the process, which causes iterations. I need to see it running--or breaking--to fix it fast.

With EC2, I can just develop locally, test on a Linux VM, and when I'm ready, fire up a Linux instance in EC2 and deploy it. I make any necessary changes and fixes, and when I'm done, can show it to the client running in an environment similar to theirs, and be reasonably certain that if they deploy it correctly--and there's nothing exotic going on, and of course there's nothing I can do about their internal security boundaries--it'll work.

I start the instance when I need it, stop it when I don't. Even if I leave it running 24/7, it's ~90 a month, still sixty bucks cheaper than my current environment. I write it all off true, but it's not just about the money, it's about being able to come as close as possible to the deployment environment. It looks really pro and builds client confidence. " have this running as an instance in a cloud? How did you set that up?" is a question I've already been asked.

And because it's cheap and timed, it's very easy to bill back to a client. I usually don't do this, preferring to just build it into my rate, but in this day and age of economizing, being able to draw out line items on an invoice is important. If a client declines, that's fine, but I make the point that for essentially pennies they are compromising my ability to ensure they are getting a working product in as few iterations as possible. I expect that my clients will say, "spend the fifty bucks".

Lastly...I'm an independent developer, and am getting a firm, hands-on grasp with cloud computing and how to use it effectively. That's the sort of experience that sets you apart from the typical "I do flash sites" kind of hacker.

There you have it. If you have the chops, being an indie dev isn't as hard as you'd think. I find it far more rewarding than a straight corporate job, and if you read my blog, you know I've had 'em. But to stay on top of it, when new tools or services come along that let you economize and work smarter, you gotta get involved. For me, EC2 is definitely in my toolbox.

As always, thanks for visiting.

Labels: , , , , ,

Wednesday, June 3, 2009

iPhone app development...using JS and HTML instead of Objective C? Freakin' amazing!

I had to try this; check out NimbleKit. I dabble in iPhone development, and have already gone through the rigor of Objective C, but I mean...JS and HTML?

NimbleKit touts, "NimbleKit is the fastest way to create applications for iPhone and iPod touch.You don't need to know Objective-C or iPhone SDK. All you need is to know how to write an HTML page with Javascript code."

I'm dubious to say the least; write in one language, compile to another completely different environment, is something I've seen blow up more than once. But then again, I was dubious of the Google Web Toolkit, and that worked really well when I needed it. With that said, let's give it a try. I downloaded the installer, which adds a new project type to your XCode iPhone Applications project templates:

Firing it up brings you to the dev interface for the project. It looks more or less like a regular app, with the addition of a the NimbleKit supporting binaries, like libNimbleKit.a, the NKit.js library, and an HTML folder in the project explorer. The page of interest to me is located in that HTML folder, called main.html, and we see it includes the NKit.js file.

So, let's compile and run the project on the iPhone (I'm a registered developer) using just the default HTML text in the emulator...BONK! NimbleKit wants you to register NimbleKit, and initialize it with the serial number they send you in order to test on the iPhone. I'm not inclined to do that at this point but, it did show that NimbleKit will deploy the app to the iPhone without issue; I actually see the icon on the iPhone and everything exactly as you'd expect. The pic below is a screenshot from the iPhone:

So, for now we're using the emulator. My confidence is building though, if this thing really pans out I might just register and get a serial number. Right now though, there's very little documentation and only one tutorial. I think I'll wait for another rev to commit.

There's a tutorial showing how to build a simple "Radio" application, but what I think I'm going to do is just try to knockout a hello world that loads an image. Right off the bat, you can see that, while you use JS and HTML as your "MainView", which is what you put UI items on. Let's try to add a button, and an image control, so that when we click the button, the image loads. Nothing fancy, but this gets us through creating and positioning UI elements, hooking up events, and UI elements that react based on the result of that event (in this case, a button click). This is a basic exercise I try in any UI development environment I come across.

In Objective C, the code might look like this; this is the implementation class, I'll leave out the interfaces and whatnot. Note that in the NimbleKit project, I don't have to worry about the separate interface and implementation objects, I just work right on that HTML page directly.

- (void)loadView
[ super loadView ];

mainView = self;

btn = [ UIButton buttonWithType: UIButtonTypeRoundedRect ];
btn.frame = CGRectMake ( 110, 10, 100.0, 20.0 );
[ btn setTitle: @"Load Pic"
forState: UIControlStateNormal ];
[ btn addTarget: self action: @selector(btnClicked:) forControlEvents: ( UIControlEventTouchDown ) ];

[ self.view addSubview: btn ];

- (IBAction) btnClicked:(id)sender
UIAlertView *alert = [ [UIAlertView alloc]
initWithTitle:@"Hello DevX" message:
@"iPhone, here I come!"
delegate:self cancelButtonTitle:@"OK"
otherButtonTitles:nil, nil];
[alert show];
[alert release];
img = [ UIImage imageNamed: @"cat.jpg" ];
CGSize imageSize = img.size;
myImageView = [ [ UIImageView alloc ] initWithImage: img ];
myImageView.frame = CGRectMake ( 0, 100, imageSize.width, imageSize.height );

[ mainView.view addSubview: myImageView ];
[ myImageView release ];


So, let's try and port that same idea into NimbleKit. Although there's no documentation, I saw in the video and in the screenshot on the home page that the UI elements are preceded with "NK". Those aren't native iPhone framework names...hmm, where do I get the object names? My guess would be, since you do this all in a JS script tag, I'd need to look in the nkit.js file, and sure enough, that's where I found what I was looking for; NKButton, and supporting methods.

function NKButton()
this.init = NKPlaceNativeButton; = NKShowNativeButton;
this.hide = NKHideNativeButton;
this.setTitle = NKSetNativeButtonTitle;
this.setImage = NKSetNativeButtonImage; = CallNKitAction("NKCreateButton?sync=yes");
function NKSetNativeButtonImage(imageName)

function NKSetNativeButtonTitle(title)

function NKPlaceNativeButton(x, y, width, height, callback)

function NKShowNativeButton()
function NKHideNativeButton()

So, with this info in hand, I tried to write out the JavaScript. Doing "var btn = new NKButton ( ), and setting the properties every which way, didn't make a native button appear. Ok, I'll go with a NKNavigationController instead; this worked as expected, a nav controller appeared on the top of the emulator screen with a button, and a test event handler that shows an NKAlert worked. So far so good.

It then dawned on me that I wasn't thinking about this right; I'm supposed to be using HTML and JS, not trying to figure out how the standard iPhone SDK applies. So, let's shift thinking: I'll still use the NKNavigationController (though based on what I can see, the button should have worked...DOCS PLEASE!), but I'll also add a button under it that does the same thing; clicks and makes the image appear. For the image, I'll just put in an HTML "img" tag, with no "src" attribute specified. When I click either the button in the nav bar, or the standard HTML button, I'll call a JS function to load the image. Here's my code:

<script type="text/javascript" src="NKit.js"></script>

<script type="text/javascript">
var navController = new NKNavigationController ( );
navController.setTitle ( "Testing NimbleKit" );
navController.setStyle ( "black" );
navController.addNavigationItem ( "Image", "showImage" );

function showImage ( )
img.src = "cat.jpg";


<input type="button" value="Load Image", onClick="showImage ( )" />
<img id="img" src="" />


And I will be freakin' damned...they both worked perfectly. Screenshots below. I gotta say, I'm stunned. The potential for this development kit is pretty staggering when you think about it. The developer of NimbleKit has essentially put basic iPhone development into the hands of every basic web page developer.

You think there's a lot of apps in the iPhone store NOW...just wait 'til this gets out!

As always, thanks for visiting.

Labels: , , , , , ,

TcozTwitter: A Twitter Client using Adobe Air and the Flex Mate Framework - Day 4 : Getting into Authentication

This is a continuation of a series of articles on my experiments with writing a Twitter desktop client using the Twitter API, the Mate Framework for Flex, and Adobe Air. Previous blog posts are here at Day 1, Day 2, and Day 3.

This time around, I started researching the dreaded topic, "Authentication". That is, in order to do anything really meaningful on behalf of a user, an application has to ask for your username and password, and one way or another, send it to Twitter for processing so that they can tell you "this is a known user, here's access to their stuff".

This is an interesting conundrum, since once you've installed a custom application and started using it, there's very little to prevent the application from taking your account information and sending it to a non-Twitter service. After all, you're just filling out a username and password form that isn't on the Twitter site, and clicking a button saying "sign in". The application could be sending that data anywhere. More tech-savvy users will know to use bad credentials first and monitor http calls carefully; if you see something not going to Twitter, something could be fishy.

There are social network apps and widgets out there that do this: IMHO YOU SHOULD NOT USE THEM. You are essentially giving your username and password to an unknown entity. Assurances aside, why take the risk? There is a better way...keep reading.

Let's assume that I'm not going to do anything nefarious with my own credentials. Unless I develop full-blown paranoia of some kind, I'm relatively certain that me-the-developer isn't going to compromise my Twitter account.

A visit to the Twitter API Wiki to review Twitter authentication reveals that there are two ways for an application to go about authenticating a user for access to their account-specific info: OAuth, and Basic Authentication. In brief layman's terms:

- Basic Authentication is a widely supported authentication mechanism involving sending the user's username and password encoded as Base64 via an HTTP POST. I won't get into what that means exactly here, suffice to say that it is a standard way of sending values to a web server, with those values represented in such a way that certain kinds of characters will not confuse or compromise the authentication mechanism. Such a transmitted string might look like "QWxhZGRpbjpvcGVuIHNlc2FtZQ==". While this may appear to be "secure" to the eye, since it's not the original string value (like your password), it isn't at all, because Base64 is easily decoded into it's original value. In other words, your credentials can be intercepted, decoded, and revealed.

Twitter allows the use of Basic Authentication, but they clearly don't like it. They're considering removing it in favor of OAuth. On their site, they say "We would like to deprecate Basic Auth at some point to prevent security issues but no date has been set for that."

So me, I'll use Basic Authentication will I'm dinking around with nailing in the UI for my Twitter client. But when I get ready to go live, I'll definitely want to switch to OAuth. It might very well for this reason that Twitter leaves Basic Authentication lying around; it's just easier to develop an app if you don't have to deal with OAuth.

- OAuth (useful beginners guide here) is an authentication protocol that allows users to approve applications to act on their behalf without sharing their password. The basics of it are this; the developer has to inform Twitter directly that they have created an application that will be making calls into their API that require authentication. You fill out the form and register your app at Applications that User Twitter page. Twitter returns to you tokens to be used when requests are being sent back and forth. A Token is generally a random string of letters and numbers that is unique, hard to guess, and paired with a secret key to protect the token from being abused.

The flow then goes something like this: you, the user fire up your Twitter client. If you have not already done so, the Twitter client should direct you to a web page where you can say, "Yes, allow this application to access my information based on my id" (not your username and password). From that point forward, the application sends its key, along with your unique Twitter-system user id, to the API. The Twitter system looks at the key, and the ID, and asks, "has this user authenticated this application". If the answer is yes, the interaction proceeds, if not, it's declined. Remember, this key is coupled with another secret token, so just intercepting the in-transit data won't work (unless the hacker has obtained your secret key somehow).

OAuth is considered sufficiently secure for this sort of interaction, and prevents the problem I described before about being able to capture user credentials, since the user never directly provides credentials to the application. Yes, once you approve the app at the Twitter site, the application can do wonky things, like making bad tweets on your behalf, but as soon as you see that you can either de-authorize the app, or Twitter will ban the application entirely by revoking the tokens. OAuth is most definitely what you should be looking at if you intend to release any kind of Twitter client. It is a VERY common security paradigm, e.g. Facebook uses it, so any developer getting into building apps for social networks should definitely get their head around it.

So, that I said, I want, for now, to be able to make calls as simply as humanly possible into the Twitter API, I don't care if they're secure or not at this point.

To that end, I found the tweetr ActionScript 3 library. By just copying the code in their example "Retrieving One Tweet from authenticated User Timeline", I was able to call into the API with my username and password, and as the name implies, retrieve one tweet from my account (it turned out to be my last one).

I haven't looked at the source code, but, since the library takes a username and password to make the request, and I haven't registered my application, I'm assuming with good reason that this library uses basic authentication, at least for this example. As I said, during this dev phase, that's fine, but I'm going to have to revisit this eventually.

The code looks like this; yes, I took out my username and password. Notice I put this in a Command-based class (it implements the ICommand interface, typically "execute ( )"). So I'm using Commands in the Mate framework. Nice.

private var tweetr:Tweetr;
public function execute ( ) : void
tweetr = new Tweetr();

// set the browserAuth to false so we actually use
// the AIR authentication scheme
tweetr.browserAuth = false;

tweetr.username = "xxx";
tweetr.password = "yyy";

tweetr.addEventListener(TweetEvent.COMPLETE, handleTweetsLoaded);
tweetr.addEventListener(TweetEvent.FAILED, handleTweetsFail);

// tweetr.getUserTimeLine();
tweetr.getFollowers ( );

private function handleTweetsLoaded(event:TweetEvent):void
// assign the latest response to a data object
var tweet : StatusData = event.responseArray [ 0 ] as StatusData;

// trace some data
trace ( tweet.user.profileImageUrl );
trace ( tweet.user.screenName, tweet.text, TweetUtil.returnTweetAge ( tweet.createdAt ) );

private function handleTweetsFail(event:TweetEvent):void
trace ( "TWITTER ERROR ARGH ", );

So far so good; I've found a library that lets me proceed with my development, like creating user interfaces for posting tweets, managing friends and favorites, and so on. I'm using Basic Authentication for now, but I know I need to change it, and since I've done Facebook application development already, I shouldn't have any problem tracking down resources and libraries to get me through this on the Twitter side.

Next, retrieving my own timeline, and creating a view for it, such that I can toggle back 'n forth between the public timeline and my own.

As always, thanks for visiting.

Labels: , , , , , , , , , , ,

Tuesday, June 2, 2009

Adobe Flash Builder (formerly Flex), first looks: Compatibility with older Flex, different namespaces...other immediate differences?

Adobe Flash Builder (formerly Flex), first look: Compatibility with older Flex, different namespaces...any other immediate differences?

Yesterday, Adobe announced the general availability of Flash Builder 4 Premium Beta, and Flash Catalyst, which I may or may not discuss some other day. The coder tool is Flash Builder, and that's my primary interest by far, though Catalyst does look interesting...and possibly headache inducing, as it's a way for non-coders to generate code without actually understanding it. Historically, that's always been a mess.

This article focuses on my initial experiments with Flash Builder, which is the new Flex, rebranded. I installed it on my only non-work machine, which is a Windows XP box. Apologies to the Mac loyalists.

My first concern is, can I use old Flex projects in the new Flash Builder? This is primary to me because, if you went through the whole wrestling match of Eclipse Flex Plugin projects vs. Flex Builder Projects vs. Flash projects (which really don't exist, it's just a folder with relatively located assets), and of course the whole CS3 to CS4 upgrades with subsequent months of, "I don't have Flash CS4 can you export to CS3...I don't have Photoshop CS4 can you downgrade the .psd," you know that it's EXTREMLY important that you be able to import old projects, and export new ones in the older formats. This still makes the whole SVN thing a mess if people are using different versions, but that's more a team workflow/standards thing; a team should agree on a version and all upgrade at the same time.

Anyway, I found some issues. I'm sure I'll find more, and of course it's possible there's more for me to learn about the new tool and V4 SDK, but this is where I'm at onDay 1.

On launch, the new Flash Builder looks pretty much identical to the old one. Screenshot below.

Right off the bat, when I go to the File menu, there it is: "Import Flex Project" and "Export Flex Project (FXP)" menu selections. Alrighty, let's try the import process on a fairly big Flex project, the codebase for my PlanetSudoku game.

After selecting the project folder (which I just dragged onto my Windows desktop from my Mac Flex Builder 3 workspace), a dialog popped up asking me what Flex SDK I wanted to use. The default is Flex 4.0, but I could select any other SDK I had installed (it appears to also install 3.4 for you, which is nice). Let's be daring: I'll compile it with 4.0.

Continuing on, I get the warning, "If you convert, you won't be able to use this project in older versions of Flash Builder...". Hmm, ok, I guess I could always just use the Export feature if I needed to...more on that later.

Note: If you are getting the idea into your head that you can start using the Beta full-time now because you can import and export projects, that is a BAD idea. BAD. It's a beta product, you should NOT use it for production work. And as you read on, you'll see how bad it can be.

Without trying to run it, the import worked, here's a shot of the project structure. Good 'ol bin-debug is still there, html-template, my asset folders, my sounds, all the structure looks like it imported cleanly. Note that "Flex 4.0" is now it's own library category, and there looks like there's some new things in there. That'll have to wait for another blog post.

Ok, no errors, let's open an ActionScript file and look at the code editor. Here's a nice surprise; all .as files are nodes, which when expanded, show the structured outline of the file, just like the "Outline" window. I guess that window is sort of redundant now, though it does have sorting options and such.

At first glance, things look pretty much the same in the code editor window, though there does seem to be some new icons to assist in scanning through the lists of auto complete selections, like below (notice the "Native" icon):

Ok, enough dinking around, let's run this thang...AHAH! When I go to the Run button, I see a new choice, something that appeals to the "enterprise" in me...Execute Flex Unit Tests! Clearly evidence that Adobe is getting more serious about the more serious coder. Gotta look that one up in the help files ("Help" appears identical to old Flex help FYI). More :

Help says the following about the FlexUnit Test Environment:

The FlexUnit test environment allows you to generate and edit repeatable tests that can be run from scripts or directly within Flash Builder. From Flash Builder, you can do the following:

Create unit test cases and unit test suites

Flash Builder wizards guide you through the creation of test cases and test suites, generating stub code for the tests.

Run the test cases and test suites

You can run test cases and test suites various ways from within Flash Builder or outside the Flash Builder environment. The results of the tests are displayed in a test application. Flash Builder opens a Flex Unit Results View for analysis of the test run.

Navigate to source code from the Flex Unit Results View

In the Test Results panel, double-click a test to open the test implementation.

The Test Failure Details panel lists the source and line number of the failure. If the listed source is in the current workspace, double-click the source to go directly to the failure.

Ok, that's definitely another blog article in the making. There's unit testing frameworks out there for Flex that I've seen, but integrated? That's significant.

So, back to running the project...ARGH. A browser window pops up, but then an ActionScript error window comes up with the following message:

"VerifyError: Error #1014: Class IAutomationObject could not be found."

Ok, I know it's probably fixable using SDK 4, however, what I'm going to try is deleting the entire project, and reimporting it using the 3.4 SDK (which is the only other one available in the dropdown; I might actually not have another Flex SDK installed on this machine, so it's nice they seem to install 3.4 for you).

First thing I notice; the Flex 4 folder is now Flex 3.4, and some of those "new things" are gone. Ok, so the Flex 4 SDK is quite a bit different than 3.4, that's good to know.

No errors, let's try running it...SUCCESS! The project ran just fine.

So, Compatibility Lesson 1: DON'T USE THE Flex 4 SDK FOR 3.x SDK PROJECTS. At least, not unless you're willing to wrestle with differences to use the newer one. Predictable, but now confirmed.

Now, let's try a Debug run. No surprises. Seems to work just like the old one.

Time to try it the other way around. I'll create a "Hello World" project in Flash Builder 4, using the V4 SDK, export it, and try to load it into Flex Builder 3.

When creating the new project, I notice it's not a "Flash Builder" project, it's still a "Flex Project." All the choices look identical to Flex 3.The project created as expected, but I noticed one thing: The top level MXML file still contains the Application element, but it looks different (note the "s" and "fx" namespace declarations):

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="" xmlns:s="library://" xmlns:mx="library://" minWidth="1024" minHeight="768">


Application now falls under this namespace declaration: xmlns:s="library://". If you recall from the screenshot of the Flex 4 folder above, there is a .swc called "sparkskins". Hmm. Drastic changes afoot?

Aside from that, the dev tasks look the same. I'll drag 'n drop a button and a label, and set up the click event handler to populate label with "Hello Flash Builder Export Test!".

Bonk! When I went to type <mx:Script>, like I usually would, it didn't get recognized: no CDATA tags and closing </mx:Script> tags got generated. After a little dinking by looking at the declared namespaces, I found the Script tag in the fx namespace. This has the desired result...but oh jeezus. I'm going to have to unlearn some pretty basic things it seems.

The test code looks like this, and worked exactly as expected. Interestingly, no more weird Flex green background, it was just plain white (thank you was with that grey/green background anyway). No screenshot for this, just imagine a white background, with a Flex (erm..."Flash Builder") button, which when clicked, populates an mx:label (erm..."s:label"):

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="" xmlns:s="library://" xmlns:mx="library://" minWidth="1024" minHeight="768">

private function onClick ( event : MouseEvent ) : void
lbl.text = "Hello Flash Builder Export Test";

<s:Button x="192" y="28" label="Button" click="onClick ( event )"/>
<mx:Label id="lbl" x="96" y="86" text="Label" width="288"/>


Export time. I'll use the File...Export Flex Project (FXP) option. This creates a Flex Project archive, which I should be able to import nicely. Here goes...

...not even close. Again, undoubtedly because I created the project using the Flex 4 SDK. Meh, I was curious, but this is exactly what I expected. so I'll recreate the project using the 3.4 version and re-export it. In the new 3.4 SDK project, I notice that the "mx" namespace is back, everything looks kosher, just change the "fx" and "s" namespaces to "mx", and the code ported over fine.

Over in the Flex Builder 3 UI...import FXP...BLEARGH! It didn't work. This simple little project, when imported into Flex Builder 3, failed. Wouldn't build, nothing in bin-debug, nada. So it seems, Lesson 2: at least for now, DON'T BUILD PROJECTS IN FLASH BUILDER AND EXPECT FLEX USERS TO BE ABLE TO EASILY IMPORT THEM!

Sure, as always, there's things I probably don't know, but I appear to be following the guidelines pretty straight. Time to RTFM, look at the help docs more carefully, etc.

Anyway, that's a long enough post. Thanks for coming along on my first tour of Adobe's new Flash Builder.

Labels: , , , , , , , ,

Monday, June 1, 2009

Flash Flex on the iPhone? Setting up the Amazon Cloud Instance running Citrix XenApps

This is a continuation to my series of articles detailing how to get Flash Apps running on an iPhone...sort of. You really don't run Flash on the iPhone, you run it on a Citrix XenApps server, which runs on a Windows instance in the Amazon EC2 cloud.

My previous blog articles can be found here:

- Flash, Flex...on your iPhone?
- Monday, May 18, 2009 The Citrix Receiver Follow Up: Flash/Flex (and then some) on your iPhone...or Symbian...or WinMo...or...

Quick blurbs on what the technologies I mention above are:

- Flash/Flex/Air: if you're reading this article, no explanation needed.
- Citrix, simply, specializes in terminal-based delivery of applications. Think "thin client" delivery of applications.
- XenApps, in there own words, "Citrix XenApp virtualizes an individual application, be it Microsoft Office, PowerPoint, Excel, or SAP (sic, or Flash, etc.), allowing users to run those applications on a client directly from a XenApp server hosted with a Windows application."
- Amazon EC2, cloud-based computing infrastructure. I describe this more below.

So, my goal is to "Deliver Flash/Flex/Air apps, initially for the iPhone but eventually for any client, from the EC2 cloud running an instance of a Windows Server running Citrix' XenApps".

Whew. I could probably land a contract just by saying I know what that means.

In order to get this rolling, I'll have to get a Citrix XenApps instance running in the on the Amazon EC2 cloud. Citrix offers a video showing how to do this, you can view it here.

Three IMPORTANT notes, this is fair warning, and this is coming from somebody that has worked with resources in clouds before (I've just never been responsible for actually configuring and maintaining one).

- WATCH THE WHOLE VIDEO CAREFULLY. Believe me, you won't figure it out on your own if you've never done anything like this before.
- DO NOT USE SAFARI. If you're a Mac user, you probably know Safari doesn't always work well in sites that have multiple form submissions. The Amazon web pages broke quite a bit until I switched to Firefox.

Let's talk about what "an instance in the EC2 cloud" means. An "instance", is conceptually like a dedicated server...but it's not. It's an allocation of resources that appears to me to be a server, but which is disposable; when you terminate an instance, it's configuration is saved so you can restart it, but otherwise, the resources are freed up. The company, like Amazon, uses commodity hardware to build a platform to make instances available, and you pay for the time that each of your instances runs, because you're using resources in their cloud. When I terminate the instance, I don't get billed anymore, because there's no server to keep up and running, just a stored configuration that gets reconstituted into an instance if and when I start it back up.

Conceptually, the "cloud" is like a big ball of clay. When I need a chunk of clay, I grab off as big a handful as I need; I pay for that chunk based on the size of it, and how long I keep it out of the main big ball. When I'm done, I take a snapshot of the chunk, and just put it back onto the big ball. It's now available for anybody else to use, and my billing stops until I grab a new chunk, which by using my snapshot, can get instantly reshaped to the last known configuration. I can grab as many chunks as I need, shape them all differently, and so on.

It's a great model. In addition to a website hosted by Brinkster (where my blog and main site is), I currently pay almost $150 a month for a dedicated Windows server that I use for deployment and testing of customer apps. I pay for it whether or not I'm actually doing anything with it, which has irked me more than once. It's a business write off and all that, and IMHO an essential tool for any independent web-based software developer, but still, if I can economize by just using cloud instances of windows and linux servers, activating and deactivating them when I actually need them, and enjoy the easy flexibility of multiple environments (this one runs Tomcat on Linux...this one .Net on Windows Server 2008, etc.) I can cut that cost to a fraction and save myself multiple webserver config headaches and such.

Anyway, to get started, you go to the Amazon Elastic Compute Cloud EC2 Site. Initially, this is a little scary, because you see a list of usage fees by the hour, and you have to submit a credit card. But I'm intrepid, and have a business credit card, so on I go. I needed to set up an EC2 account, which lets me run select all kinds of pre-made server images that I can run as instances, and an Amazon S3 account, which is the storage mechanism for my files and so forth. They run independently of one another; again, remember that you're not actually running a server, you're running an allocation of resources, broken down into processing and storage. This way, I can run the same image as multiple instances, each with different (or differently configured) apps, using different amounts of processing power, all pointed at the same storage, or different areas of storage. Very flexible and elegant.

Anyway, the EC2 account I want to run my server images in is "$0.125 per Small Windows Instance (m1.small) instance-hour (or partial hour)". According to the documentation, it breaks down like this:

- You're paying by the hour, 12.5 cents, for every hour your instance is running. Hmm...let's assume I'll leave it up all day for a month: 12.5 x 24 = 300 cents = three bucks a day, x 30 = 90 bucks a month. I don't mind that as an investment in learning this technology and proving its use; if I land one contract because of this, it'll more than repay me in a couple of hours. And if course, I don't have to run it all the time.

- The specs for a Small Windows Instance, which should be plenty for my development experiments and demos: 1.7 GB of memory, 1 EC2 Compute Unit (1 virtual core with 1 EC2 Compute Unit), 160 GB of instance storage, 32-bit platform. Hmmm...we'll have to see how it goes. The large instance has 7.5 GB or memory, but is fifty cents an hour. So, here's hoping the Small Windows Instance can swing it.

So, you fill out the forms (again, don't use Safari), which when complete, takes me to a page with the following message:

"Thank you for signing up for Amazon Elastic Compute Cloud. We will e-mail you a confirmation when the web services are available for you to use. In order to begin using this service, you will need a X.509 certificate. You can Create a New X.509 Certificate or Upload Your X.509 Certificate." let's create the X.509 Certificate. If you don't know what one is, an X.509 certificate binds a name to a public key value; more generally, a public-key certificate is a digitally signed statement from one entity, saying that the public key (and some other information) of another entity has some specific value. So, by using a certificate, a browser and an application know that they are speaking to the intended targets by comparing those values; if it checks out, the communication is coming and going from where it's supposed to.

After a minute or so to create the certificate, I now have a certificate assoicated with my EC2 account, and my instances will be run using it.

That really seemed to be about all there was to it; strangely enough, by signing up for EC2, I seemed to have already signed up for S3; I went to the S3 page to sign up, but it told me I already had access, and as far as I know, I've never signed up for it before. It makes sense, but seemed a little implicit; I'd prefer to have at least received an explicit notice of some kind. It doesn't seem to cost me any additional money though.

Once that's done, you go to the EC2 Console and look up an image of the XenApps demo image. This image is located in the Community AMIs list after you click "Launch Instances" (search for "XenApps"). In order to do so, you'll need to create a security group and a key under which to run the instance; these items do things like open ports so that you can access the instance however you need, like HTTP, RDP, and via the Citrix clients. WATCH THE VIDEO, it explains exactly how to do this and what it means.

All in all, not so bad to get this end of it up and running. I still need to know how to upload and configure apps to make them available, but that's the next step. For now, I'm an independent developer with direct experience in setting up custom configured server instances in a cloud. I understand the benefit of it and can put out a wide number of configurations for any kind of client to access and test applications, and it's costing me twelve-and-a-half cents an hour to play with. Worth every penny IMHO.

Next, making Flash/Flex/Air apps available on my fancy new server instance running XenApps.

As always, thanks for visiting.

Labels: , , , , , , , , , , ,

Sunday, May 31, 2009

TcozTwitter: A Twitter Client using Adobe Air and the Flex Mate Framework - Day 3

TcozTwitter: A Twitter Client using Adobe Air and the Flex Mate Framework - Day 3

As @lancearmstrong says, "onward".

This is a continuation of TcozTwitter: A Twitter Client using Adobe Air and the Flex Mate Framework - Day 2, in which I decided to complete a number of technical exercises by building a Twitter desktop client using the Twitter API, Adobe Air and the Mate Framework.

This time around, I completed two major steps: the full parsing of a tweet with all associated data (so that I can display the message info finally), and preliminary incorporation of ads, which I tried to make as unobtrusive as possible.

Parsing the tweets turned out to be easy. If you want to get an idea of the XML that makes up a tweet, take a look at this file, which is a dump of the raw XML returned from the service call I discussed in the day 1 article. Make sure you view the source of the page; if you just click the link and view it as a regular web page, it'll look like an endless string of jumbled user data.

If you look at the XML, you see that a user's data is actually represented by an element called "status" that contains two parts; a top-level set of children that holds the message info, and a child element called "user", which contains all the user info, like name, id, number of followers, etc. Manager_Tweets gets fed all that XML when it returns from the EventMap handler (see days 1 and 2 for an explanation of this), breaks it up into an array of "status" elements, and pushes them onto Model_Tweets as an array of new Data_Tweet objects. So, whenever I want to grab the current list of public tweets, I just have to call Model_Tweets.getInstance ( )._publicTweets, and I'll get back an array of Data_Tweets. As I get more tweets, I just keep pushing them onto these waiting arrays on Model_Tweets, so I get a running list of tweets for the entire user session. As I work with different kinds of tweets, like Area, Trends, and different accounts, I'll just add more service calls to the EventMap, add more arrays to Model_Tweets, and push new Data_Tweets onto them.

Each Data_Tweet object gets one "status" element, which it cuts up into two XML fragments: the message, and user, parts. I then iterate each of the child elements in both parts and push the values onto objects, with the element names as the property names. The end result; each Data_Tweet exposes two objects, one with all that user's message info, and one with all that user's identity info.

The code in Data_Tweets that does the chopping up looks like this. Note that I've created two arrays filled with the property names I'm interested in, then I iterate those arrays, using the property names as the identity of the XML elements I want. This is sort of a lazy man's way of pseudo-typing data; eventually I'll probably just use real properties so that code hinting and such reveals the properties like any other typed object. But for now, this is a good, fast way to get the job done, and I am still using the actual property names instead of something made up.

_messageInfoProps = [ "created_at",
etc. etc. ];

_userInfoProps = [ "id",
etc. etc. ];

_messageInfo = new Object ( );
_userInfo = new Object ( );

var xml : XML = XML ( data );
for ( var each : String in _messageInfoProps )
_messageInfo [ _messageInfoProps [ each ] ] = XML ( xml [ _messageInfoProps [ each ] ] ).text ( ).toString ( );

var userPropsList : XMLList = xml.user;
var userPropsXML : XML = XML ( userPropsList.toXMLString ( ) );
for ( each in _userInfoProps )
_userInfo [ _userInfoProps [ each ] ] = XML ( userPropsXML [ _userInfoProps [ each ] ] ).text ( ).toString ( );

There's really nothing to it; get the XML from the Mate handler, pass it to Manager_Tweets, which breaks it into a list of "status" elements, then itereate that list, feeding each element to a new Data_Tweet, which parses the data into the pseudo-typed objects, then push those Data_Tweet objects onto a waiting array in Model_Tweets. I now have a subsystem to receive, parse, and store, tweets. For now I'm just using public ones, but I'm willing to bet that account-specific ones are no different.

Now onto the money shot: ads. ARGH, I know, god damn ads. But c'mon; I'm investing time and effort, not to mention using software and hardware I purchased, and so on; it'd be nice to actually make some money doing this, or at least, show that I understand how to do it, which is a great demo item for getting contract work.

I decided right away, that however I implemented ads, I wanted to make sure:

- The ad impression (an industry term for showing an ad) is immediately visible, but unobtrusive.
- There is only one "forced impression" per user session, and it won't last more than five seconds.
- There needs to be a way to view the ad again in case the user is interested.
- I want to be free to tweak this at will.

The implementation:

- The ad appears at the bottom of the app for five seconds, then fades out.
- After fading out, the ad is replaced with a very thin, translucent bar at the bottom of the app.
- This "ad bar" displays a message "Click to see the [name of advertiser] ad".
- When you click the bar, it shows the ad again for five seconds. If you never click it, you'll never see another ad.
- When you click the ad, it opens a browser window for the target URL.

Regarding freedom to tweak, that means, not compromising this unobtrusive design in any way, which means, I can't pander to the requirements of any particular ad agency. So, I actually set up my own ad server. I'm using the latest version of OpenAds, which is a free and full-featured ad server, used by such techno-luminaries as TechCrunch. I've worked with OpenAds before, but never actually built out an instance of it. I was pleased to find, OpenAds is simple to set up and simple to use. Just go through the instructions and tutorials carefully, and you'll have a full-featured, industrial strength ad server, with campaign provisioning and tracking, even marketing integration, all ready to go. From Flash, you make XML-RPC calls to the OpenAds server, it runs its logic, and returns an ad it selects as an XML response containing the info to display, like URL of the ad, target when you click it, etc.

To get started, I have a friend that owns a business called Genius Ride; he leases smart cars, delivered right to your door. I took his ad, dumped it into the OpenAds system, and set up an advertising campaign with it. The Flash client calls OpenAds when it starts, requests an ad (which at this time always returns genius ride, because it's the only campaign I'm running), and displays it as previously mentioned.

The screenshots below show the current in-progress state of the TcozTwitter desktop client.

As always, thanks for visiting.

With ad:

After ad fades:


Labels: , , , , , , , ,

Friday, May 29, 2009

"Buffering Video..." takes a hit: Akamai offers Flash Media Server 3.5 Dynamic Streaming

Akamai has recently announced support for Flash Media Server (FMS) 3.5 dynamic streaming; for the video developer muggle, this basically means that while watching a video, if your connection degrades, the player, coupled with the backend intelligence, can switch you to a lower bitrate video transparently. Although a lower quality video, the viewing experience will be interrupted considerably less--ideally, not at all--by buffering.

You can read the announcement here.

You can also see it in action at If you have a decent connection, you can watch videos encoded at bandwidths from 500Mbit to 3000Mbit, and the quality will toggle as bandwidth fluctuations happen. If you have a bandwidth throttler, Charles, Fiddler, whatever, this can be an interesting thing to check out.

This is an opportunity for the higher end Flash developer type to differentiate him/herself from the rest of the pack, which is oh-so-important in the indie software developer world. Read on...

My clients are primarily in the entertainment and media industry; I build widgets, sites, applications, whatever they need. Frequently, this means dealing with video, and if you deal with video on an industrial level, you will sooner or later (probably sooner) run into Akamai.

I don't mind it at all. Akamai has a developer kit that makes it pretty easy to hook into their streams, with passwords, bandwidth detection, whatever (in fact, in their developer sdk there is a class, HTTPBandwidthEstimate, which is a generally useful utility). You can find more out about how Akamai helps Flash developers get up and running with their technology at their Flash developer page.

Anyway, just knowing that--and being able to prove it--has landed me work. But now, Akamai offers more.

Video delivery has become a lot more sophisticated in a very short period of time. Even just two or three years ago, it was enough to serve a catalog of video in a generic player as long as it was relatively stable; all the things we see now, like seeking in on-demand video streams, ways to interact with the player, HD video over the web, and all that, were generally avoided because it was VERY difficult to get right; users didn't have the bandwidth or patience for the buffering, complex video infrastructures are difficult to implement; a video player that does nothing but break when you touch it is just frustrating, and so on (and how many of those have we seen). Nowadays, users want more; ways to interact with video, like commenting and clip sharing, and of course, a smooth, uninterrupted, and easily seekable, experience.

Akamai has always been out there though, working to make enterprise-level video serving less of a headache. The principle is pretty simple. You are not a video delivery company. We are. Pay us to house and expose your video, use our services, feeds, and developer kits, to make them available to the public. Or, try and do it by uploading all your video to in-house web servers, you tube, whatever. That may work for a small effort, but if you have a lot of content and need it monitored, maintained, looked after every day...good luck.

That's not to say Akamai is without its issues; I've heard grumbling about their downloader, and network outages have made many a corporate manager sweat all over their cel phone. Say what you want though, they've survived and grown in the industry, and like I said before, the heavy hitters use them liberally. Whatever they're doing, there's enough value for people to want them to keep doing it.

As an entertainment/media focused developer (which so many Adobe-based developers are), having worked with Akamai is a powerful resume item. Frequently, if you hear "video" in a contract, you can expect it to be followed by something like BrightCove or Akamai. So like I said before, if you have experience dealing with these video hosts, you've got a leg up.

Now, if you have that background, AND know how to take advantage of Flash Media Server's dynamic stream switching, you're at the top of the industry. FMS 3.5, as far as I know, was announced in November, so there's been opportunity to get your feet wet for about half a year. You can read about the release of FMS 3.5 here (note that the current version is 3.5.2, which is a maintenance update):

So Flash devs, get to the Adobe FMS and Akamai sites, and start gearing up; time to break out of the world of banner ads.

As always, thanks for visiting.

Labels: , , , , , ,