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".

Thursday, December 17, 2009

Flash Builder: Spark Skinning Issue to look out for (hopefully they'll fix this)

If you're in the ActionScript world and haven't cracked open the beta of Flash Builder (the latest version of Flex Builder, just rebranded), it's time to hit the Adobe site and pull it down. There's a lot to like about it.


It ain't perfect yet though. Here's a brief post about a couple of things I've discovered that might throw you when you get started.


Spark Skinning

The new Spark components (get ready for the new s: namespace) seem to work great, and have a lot less overhead than the old mx flex ones. For instance, "groups", like s:HGroup and s:VGroup, can be used instead of "boxes", like HBox and VBox. They work the same way, but don't contain logic for scrollbars and such. This somewhat mediates the old Flex issue of nested containers impacting performance. Although you should still always be careful nesting containers, its good to know that, at least to a point, you can be a little more creative about their use without overtly damaging your app's perf. You can also do more with CSS than in the past as far as skinning, fonts, and so forth. Great stuff.


However, it's still in beta, and I stumbled across what appears to be more of an API/OOP design flaw than a bug, but nevertheless still feels like something is broken, so here it is:


When using a Spark List component, you may want to reskin the Scrollbar (let's face it, the default scrollbars are UGLY). To skin the scrollbar, you would implement a new skin class for the part of the scrollbar that you want to alter, then simply apply it to that element of the scrollbar. The easiest way to to this would be to just copy the content of the default skin class, put it in a new class, modify it to suit your needs, then apply it in place of the default one. Note that the Spark documentation says this is the way to go; you shouldn't override or extend skin classes.


However, the default scrollbar skin for the increment and decrement arrows contains an "Arrow" MXML piece. Remember, this is the SKIN class, not the implementation class. Even if I omit the skin class entirely, I would expect the app to still compile and run; a null check would avoid any errors, though you may not see a skin for the scrollbar, or a default system skin would be used; something other than the app completely breaking without any compile-time errors.


You can find the Spark skin classes in [FB Install folder]/sdks/[version]/frameworks/projects/sparkskins/src/mx/skins/spark, which is great; using them as a starting point for skinning you Spark components makes this actually very easy.


Anyway, in those default Arrow classes (the ones I'm interested in are ScrollBarUpButtonSkin, and ScrollBarDownButtonSkin), you'll see this MXML fragment:



<!-- arrow -->
<s:Path horizontalCenter="0" verticalCenter="-1" id="arrow"
data="M 3.5 0.0 L 7.0 7.0 L 0.0 7.0 L 3.5 0.0">
<s:fill>
<s:RadialGradient rotation="90" focalPointRatio="1">
<s:GradientEntry id="arrowFill1" color="0" alpha="0.65" />
<s:GradientEntry id="arrowFill2" color="0" alpha="0.8" />
</s:RadialGradient>
</s:fill>
</s:Path>


Now, I don't want that, because I'm drawing some very custom shape in place of this default arrow. So, I omit that MXML fragment, and replace it with a Graphic object, in which I use the new drawing MXML stuff to create a new arrow.



<s:Graphic width="25" height="20">
<s:Path data="M 0 0
L 25 0
L 25 10
L 12.5 20
L 0 10
L 0 0" >

<s:stroke>
<s:SolidColorStroke color="0x29a094"/>
</s:stroke>

<s:fill>
<s:LinearGradient rotation="90">
<s:GradientEntry color="0xFFFFFF" alpha="1"/>
<s:GradientEntry color="0x7ac8c5" alpha="1"/>
</s:LinearGradient>
</s:fill>

</s:Path>
</s:Graphic>


After making the new class with the Graphic element instead of the old "arrow" drawing path one, I applied it to my Spark List component and compiled; new errors. I ran the program though, and it crashed right away. The error was that the "arrow" property could not be found, and there was no default value, etc. So, out of curiosity (and the desire to get the app running), I just added a public var, "arrow" : Object, and again compiled without errors. Running it though caused another error, and then another, because "arrowFill1" and "arrowFill2" were not found, no default value, etc.


So, I had to add these three public vars to my custom class to get the app to run.



// don't remove these, they are placeholders for the wonky "arrow" mxml that isn't needed here.
public var arrow : Object = { };
public var arrowFill1 : uint = 0;
public var arrowFill2 : uint = 0;


After that it worked.


To me, this is broken; as long as the skin class is properly made, it shouldn't need to contain ANYTHING in order to run properly, as long as any necessary interfaces are implemented (a well built API should be interface based). Implementation of functional objects should not be a concern of the skin class. But it is; you have to put in those dummy properties to get this to work.


I circulated this find, and the consensus seemed to be that yes, this should be fixed; there's no reason a required visual object should be in a skin class, circumventing compile time errors and crashing the entire app when it tries to instantiate a skin for a scrollbar. Evidently, more hacking away found that this is the case in a number of Spark skins.


Insurmountable? Nah, just add the public properties to satisfy the Spark parent component demand for whatever it's looking for. But it's wonky and, as far as the consensus of the people I referred the error to, should be addressed by Adobe before the product is released, for the sake of elegance if nothing else.


As always, thanks for visiting.

Labels: , , , , , ,

Thursday, July 30, 2009

Flex: Masking Images using other remotely loaded images

I had to do this recently, due to their being a very large number of images in the project I'm working on, which needed the backgrounds knocked out; it was easy to generate the masks in an automated way, it was not easy to alter the images to alpha out the backgrounds.

In Flex, they say one display object can work as a mask for another. This is true of course, but for dual remotely loaded images, properly making sure the images are entirely loaded via load.complete events, and so forth, is the key.

The following little technique shows this, code snippet below. This is proving to be quite a timesaver for the team as a whole, since the graphics guys don't have to worry about altering their entire catalog of images. I've already recommended that a back-end process should generate AND apply the masks so that Flash doesn't have to make 2x the requests for images (every image needs a mask): from a performance standpoint this is a bit of a nightmare, but, it's a solution that is moving the project forward and is easy enough on my end to implement.

Note that the images I'm using for masks are not the standard black/white masks you use in photoshop. They are PNG-8s, with everything BUT the shape you want to see alpha'd out, with 8 colors, not converted to sRGB, no metadata, etc. A roughly 400x400 image mask comes in at around 2kb with this profile.

I'm aware this isn't exactly new, and it's documented, but it's solving such a significant problem I figured I'd make it visible. I actually use this code snippet in an itemrenderer, so that I can just chuck an array of objects at a tilelist, and have the item renderer do the two-step loading.

Notice also:

- I'm combining pngs and jpgs, it doesn't matter it's all rendered as bitmaps by the client in the end anyway.
- I'm using a two-step loading chain; it seems you don't have to do this necessarily, but every now and then, it seems to fail if you don't. The two step ensures the mask is ready to go before the image every time.

import mx.controls.Image;
import mx.events.FlexEvent;

private var _mask : Image;
private function onCreationComplete ( event : FlexEvent ) : void
{
_mask = new Image ( );
_mask.cacheAsBitmap = true;
_mask.addEventListener ( Event.COMPLETE, onMaskLoadComplete );
_mask.load ( "images/testmasks/picturemask.png" );
}

private var _img : Image;
private function onMaskLoadComplete ( event : Event ) : void
{
_img = new Image ( );
_img.cacheAsBitmap = true;
_img.addEventListener ( Event.COMPLETE, onImageLoadComplete );
_img.load ( "images/testmasks/picture.jpg" );
}

private function onImageLoadComplete ( event : Event ) : void
{
addChild ( _img );
addChild ( _mask );
_img.mask = _mask;
}


As always, thanks for visiting.

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 businesses...free 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%"
itemRenderer="com.tcoz.twitterclient.renderers.Renderer_Tweetr"
paddingBottom="0" paddingTop="0" paddingLeft="0" paddingRight="0" />
</mx:Canvas>

<mx:Canvas label="Public Timeline" width="100%" height="100%" backgroundAlpha="0">
<mx:TileList id="publicList" backgroundAlpha="0" borderStyle="none"
height="100%" width="100%"
itemRenderer="com.tcoz.twitterclient.renderers.Renderer_Tweet"
paddingBottom="0" paddingTop="0" paddingLeft="0" paddingRight="0" />
</mx:Canvas>

</mx:ViewStack>


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="{ data.user.name }" />
<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>

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


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 ) }" />
</mate:EventHandlers>


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.

YOU ARE BUILDING SOFTWARE, and that ENTAILS SPECIFIC SKILLS.

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 say...no 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 hand...now 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: , , , , ,

Monday, June 8, 2009

Flex Mate: If you've asked "Why don't my events seem to be getting to the EventMap", this may help. Consider performance though.

I see this a lot out there, so figure a blog post might be very helpful to developers exploring the Flex Mate framework. If you're not familiar with Mate, go to the ASFusion Mate site.

People hear how great and lightweight the Mate framework for Flex development is, and it is interesting to work with (though it does have its issues...however, what framework doesn't). Invariably, every developer crashes into the same problem:

"I have a class that extends EventDispatcher. I dispatch an event from it. The EventMap has the correct type of event registered in its MXML markup, I've got my Manager set up to handle the logic for the event, exactly as it shows in the examples. I then dispatch an event from the Manager. WHY DOESN'T IT WORK the EventMap never seems to see the event ARGH!".

The first thing to note is, there's no explicit listener set up for your event handling. Mate just seems to magically know that you dispatched an event.

Naturally, there's nothing magic about it. The general idea is, if you dispatch an event, it needs to be told how to find a handler. Typically, you just set up an addEventListener for the type of event on the object you want to listen for the event from, then from that object, you dispatch the event. It's a many-to-one thing, but it's explicit. If no object has set up a listener for that event, then even if the event is dispatched, nothing will happen.

However, events have an argument you may have seen: "bubbles". By default, this is set to "false", which is how the vast majority of developers are used to using it. As the name implies, if it's "false", the event will not "bubble".

But, if "bubbles" is set to "true", then the dispatched event will "bubble" up through it's object hierarchy until it finds a handler set up to listen for that event.

From the documentation (note that ancestors mean "objects that came before", e.g. parents):

In the bubbling phase, Flex examines an event's ancestors for event listeners. Flex starts with the dispatcher's immediate ancestor and continues up the display list to the root ancestor. This is the reverse of the capturing phase.

For example, if you have an application with a Panel container that contains a TitleWindow container that contains a Button control, the structure appears as follows:

Application
Panel
TitleWindow
Button

If your listener is on the click event of the Button control, the following steps occur during the bubble phase if bubbling is enabled:

Check the TitleWindow container for click event listeners.
Check the Panel container for click event listeners.
Check the Application container for click event listeners.


So now you get an idea of how the EventMap works. The EventMap is put in the top-level Application (or WindowedApplication for Air developers). So, all events need to "bubble" to the top, so that the EventMap, which has the listeners, will receive them.

So you might think, "great, put in my EventMap listeners, then, just set all my events to bubbles=true and voila."

If only it were that simple; notice in the first line of the documentation quote, it says, "Display List". If you're not familiar, here's the relevant documentation blurb regarding the display list and events:

Every object in the display list can trace its class inheritance back to the DisplayObject class. The DisplayObject class, in turn, inherits from the EventDispatcher class. The EventDispatcher class is a base class that provides important event model functionality for every object on the display list. Because the DisplayObject class inherits from the EventDispatcher class, any object on the display list has access to the methods of the EventDispatcher class.

This is significant because every item on the display list can participate fully in the event model. Every object on the display list can use its addEventListener() method--inherited from the EventDispatcher class--to listen for a particular event, but only if the listening object is part of the event flow for that event.


In other words, if the object you dispatch the event from is not in the display list...so, if your object does not inherit somewhere along the way from DisplayObject, and hasn't been added as a child to some other object that inherits from DisplayObject, which ultimately can trace its DisplayObject ancestors back to level where the EventMap is, it'll never get there.

Why is this a problem? Say you dispatch an event from a DisplayObject that is in the display list that resolves to the EventMap. So far so good, the EventMap will pick it up, and send it to a specified Manager to run a function and complete the handling. Now, from that Manager, after it does something, like set properties on a model or whatever, you want to dispatch an event, the handler for which has been set up in the EventMap. The Manager extends EventDispatcher, the event is set to bubble.

No dice. The EventMap won't see it, because the Manager is not a DisplayObject; it's not in the display list.

The solution: in your non-DisplayObject and/or not-in-the-display-list object, declare a public variable of type GlobalDispatcher (I usually call it "dispatcher"), and either instantiate it in the constructor, or right before you dispatch your event. Use it to dispatch your event. The EventMap will now see it.

If you've never encountered GlobalDispatcher before, it's not that terrible an oversight; it's not a Flex thing, it's a Mate thing. If you've looked at the Mate framework source, you find it in the "core" namespace. The comment in the code indicates:

/**
* GlobalDispatcher is the default dispatcher that "Mate" uses.
* This class functions as a dual dispatcher because we can register to
* listen an event and we will be notified if the event is dispatched in
* the main application and in the SystemManager.
* <p>Because SystemManager is the parent of all the popup windows we can
* listen to events in that display list.</p>
*/

Example code:


public class Manager
{
[Bindable] public var dispatcher : GlobalDispatcher;

public function Manager ( )
{
dispatcher = new GlobalDispatcher ( );
}

public function doSomethingThenDispatch ( data : Object ) : void
{
dispatcher.dispatchEvent ( new Event ( Event.SOMETHING_EVENTMAP_IS_LISTENING_FOR ) );
}
}


Note that because you are using a GlobalDispatcher, Manager doesn't have to extend EventDispatcher. You may want to get a little more OOP about this, inheriting from a base Manager class that has the global dispatcher on it already, and then just either override a function in an extended class or just use the dispatcher parent instance directly, whatever floats your boat.

I wonder about this kind of global dispatching and the wisdom of it from a performance perspective; I suspect that bubbling all your events through the entire display list in an application can degrade performance, and that seems to be a supported notion. Take a look at this quote from the April 2009 issue of Adobe's Edge newsletter:

There are performance considerations with this approach. Because we are relying on bubbling to communicate our event all the way up the Display List, Flash Player must broadcast an event all they way through the ancestor chain of the component that dispatched the event. If our component is buried deep inside many HBoxes, VBoxes, and Canvas containers, then our event could bubble through hundreds of objects before it reaches the top. If our application is communication-heavy, the overall performance of the application could degrade when a large number of messages need to be passed on. This is a factor developers must consider when choosing this solution

An experienced Flex/Air developer may say, "well of course. Don't build apps that nest heavily. Break up your event maps. Only bubble events that are logical to bubble". Fact is though, people use frameworks because they want a prescribed model; the EventMap is EASY. So just nest your containers based on what works fast, and bubble the events to the EventMap. Bang. The bigger your app gets, the more this will degrade performance, until you eventually top out some ceiling and it all comes down.

So, it would seem that a best practice for Mate would be, even more so than usual...CAREFULLY NEST CONTAINERS, and, don't use the EventMap, or numerous EventMaps, for all your events. ONLY bubble events that are otherwise not practical to set up dedicated listeners for, i.e. for components that you would might consider taking the easy way out with things like "this.that.that.that.addEventListener", and that sort of thing. There's no reason that you can't use the standard ActionScript model, and the Mate model, to get the best of both worlds and build a solid application.

As always, thanks for visiting.

Labels: , , , ,

Wednesday, June 3, 2009

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 aside...like 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 ", event.info );
}


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="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/halo" minWidth="1024" minHeight="768">

</s:Application>


Application now falls under this namespace declaration: xmlns:s="library://ns.adobe.com/flex/spark". 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 Adobe...wtf 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="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/halo" minWidth="1024" minHeight="768">

<fx:Script>
<![CDATA[
private function onClick ( event : MouseEvent ) : void
{
lbl.text = "Hello Flash Builder Export Test";
}
]]>
</fx:Script>


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

</s:Application>



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, May 25, 2009

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

QuickStart: This subject of this article is a project that satisfies three goals:

- To complete a practical exercise of using the Twitter API.
- To create complete a practical exercise of using the Flex Mate framework.
- To have a Twitter desktop client that works *exactly* the way I want it to.

To that end, I decided to build a Twitter client, using Adobe Air and the Mate Framework.

Onto the discourse...

Why this group of technologies?

Twitter: If you're reading this article, I don't have to tell you why it's important, as a developer, to do more than dabble with it.

Air: I really like building Air apps. At it's most basic level, you could say that Air is Flash running on your desktop in a native dedicated runtime manager (called "Air"). Freed of the browser sandbox, Air has a lot of capability Flash doesn't, like real local file access and data storage, and doesn't suffer from some of the general performance issues of the browser-based Flash player. The NY Times has dumped Microsoft Silverlight in favor of Air, as has the Major League Baseball tech organization. It's a pretty exciting technology, and if you're already good with AS3/Flex, the learning curve is more a speed bump than a hill; write one Air app, run it on any machine with it's OS-specific runtime installed.

Mate: I'm predisposed to being dubious of Mate, because I prefer frameworks and patterns that translate to as many technologies as possible, and I prefer to avoid markup for UI layers whenever possible, because it tends to create scripted spaghetti. PureMVC, for example, is easy to implement in just about anything, and inclines the developer to some level of genuine C-style OOP. Mate, on the other hand, is inherently Flex targeted; it makes heavy use of Flex MXML and databinding. But, love it or hate it, I realized a while back that avoiding MXML isn't good for my business, so I skilled up, and these days a lot of people are loving Mate, so I should get a working knowledge--though I will say, this is often the case of things that make a complex technology seem easy, and it all collapses once you hit big apps.

If you want to know more about the Mate Framework, go to the Mate Flex Framework Home Page. There you can find the SVN and/or SWC downloads, tutorials, etc. etc.

Add these three things up, and it'd seem that, if I put in the time, I'll have a pretty cutting edge Twitter desktop client, insofar as the technologies involved to make it work are concerned.

Anyway, down to the bits 'n bytes of Day 1, TcozTwitter. I'll assume you know about things like Flex, working with APIs, and so on.

As I said, I have mixed feelings about Mate; it's true that it's pretty easy to learn and get working, which no doubt contributes to it's popularity. People talk about it like the second coming, and say that it doesn't prescribe a particular kind of development, your app isn't tied to it, etc. But from what I can see initially--granted I'm no Mate expert, but I've worked with other frameworks pretty deeply--this isn't true. Your app is VERY tied to it.

For example, Mate prescribes how you use events in a VERY particular way. Events dispatched directly from non-views (typically "managers" in Mate parlance) don't hit the all-important EventMap (essentially a clearing house for event handling), because in Mate, you bubble all your events up to the top-level application for handling, and bubbling is a function of the DisplayList; non-views need not apply.

There is a workaround; in the non-view, create an instance of a GlobalEventDispatcher and use that to dispatch the event so that it immediately hits the top level app, which contains the main EventMap, but that's not at all what I'd typically do; usually I'd just have the non-view extend EventDispatcher, either directly or in a base class, and dispatch away. I was surprised by this; in Cairngorm or PureMVC, the basis of how you dispatch an event isn't prescribed by the framework; what you do with that event once you catch it is. I guess this is a matter of perspective, and no doubt this statement will annoy the Mate advocate, but there it is.

Note: I don't dislike Mate. It's growing on me. But at this point I still prefer PureMVC. This may change over time, we'll see.

If you'd like to try some Mate twittering yourself, for your first Twitter call, here's a simple MXML fragment showing what to put in your MainEventMap (which is essentially a manager for handling bubbled-up events in the Mate framework):


<mate:EventHandlers type="{Event_GetLatest20Public.GET}" debug="true">
<mate:HTTPServiceInvoker url="http://twitter.com/statuses/public_timeline.xml" resultFormat="xml">
<mate:resultHandlers>
<mate:MethodInvoker generator="{Manager_Tweets}" method="storePublicTweets" arguments="{resultObject}" />
</mate:resultHandlers>
</mate:HTTPServiceInvoker>
</mate:EventHandlers>


Notice in there we have an HTTPServiceInvoker pointing to the twitter endpoint that dumps out the latest 20 public timeline tweets. You can grab them in a variety of formats just by changing the extension of the public_timeline call (instead of .xml, use .json for example). This is strictly preference; I like XML, so that's what I'm using. In addition to this, you'd have to write your Manager_Tweets class, with the "storePublicTweets" method, and dump it onto a model for binding and so on. If you need a primer that shows you how to set this all up (it's very easy), go through this tutorial. I used this as as starting point for my Mate explorations a while back and it was very helpful. While there's certainly a lot more to learn about Mate, understanding how the EventMap works in conjunction with Managers is the most important part, and this tutorial makes it very clear.

With all that understood, my first effort was to take that XML and bind it into a TileList, which has an itemRenderer that receives the individual data objects, which have properties that map to the original XML elements. So, in the itemRenderer, just by setting the image component's source to "data.profile_image_url", and the top text components text property to "data.name", I get the expected result; a scrolling TileList of the latest 20 public posts, with profile images and names.

It's not pretty; I didn't work out the sizing or layout, or scrolling, etc. This is entirely the first step. But hey...I've got an Air client, using the Mate framework, hitting the Twitter API and displaying user data. I'm on the way to achieving the three goals I mentioned at the top of this article.

So far so good. Next step; clean up that UI to display the scrolling list more neatly, and add in the message and metadata to that display of public posts.

As usual, thanks for stopping by. Pic of in-progress client below:




Labels: , , , , , , ,

Monday, May 18, 2009

The Citrix Receiver Follow Up: Flash/Flex (and then some) on your iPhone...or Symbian...or WinMo...or...

I said I'd follow up on my story Flash, Flex...on your iPhone?, (this story generated a lot of press, got picked up by TechCrunch and blogs all over) and here it is. 

As a quick recap, I looked at the Citrix Receiver iPhone app, and was impressed with the experience. It's not a VNC or RDP solution; Citrix has created a client that, by use of a highly optimized communication protocol, lets you view apps running in the EC2 cloud (for the layman, that means "you see it on your phone but it's actually running somewhere else") without installing them on your phone. This means that you can build an application out of any technology, deploy it to the remote server infrastructure, and access it on your phone, or computer, or any device that runs the Citrix Receiver. The technology is optimized for this use; there's no awkward, blocky screen redraws, no browser toolbars, etc. A properly designed application appears to be running as a full-screen application on the phone, no matter what technology it's built out of. This suite of tools is branded "XenApps" for the most part; I'm not one of their marketers and know there's more to it, but "Xen..." is a big Citrix branding buzzword these days.

It's amazing how many people responded negatively, clearly without trying the Citrix Receiver demo. For the most part the issues are around the rampant abuse of Flash all over the web; poorly programmed banners, autoplay video players, that sort of thing. I concede: the web is full of bad Flash, and if that's the extent of your experience, you'll probably be pretty close minded about the subject. I've been a Flash developer for a long time though, and have never programmed a banner. I work on enterprise-level applications that make companies money; I've built applications that you've more than likely used, and that have helped people sell companies, and is currently helping a startup stay in business. Flash development, with Flex and Air, is stronger than ever and isn't going anywhere. Hating it is a waste of time. 

To continue my rant, I'll tell you one thing for sure: I don't want to be in the business of porting those apps to every different platform on earth. Yes, I could make money doing it. But it's boring and doesn't move me along to the next new project. People say, "forget Flash just build an iPhone app". Erm...what about Android? And Blackberry? And Symbian? And Windows Mobile? And Windows desktop? And OSX Desktop? Hire all those developers....maintain all that code...I've got better things to do. I want my app to have as much reach as humanly possible with as little work as possible, and porting the code to everywhere isn't a good strategy. 

Note: Citrix said that for Blackberry and Android clients, we have to "stay tuned". The guys on the call wouldn't nail in any dates or promises about this, but they didn't say "no". I'd assume that, considering how attractive this technology could be to corporations, a Blackberry client would be a no brainer. There is currently one for the iPhone, Symbian, and Windows Mobile 6.1.

The Citrix Receiver, backed by the Citrix technology on the server side, is the sort of thing that makes this possible. Again I'll say, and Chris Fleck, VP of Solutions Development for Citrix agreed readily, that it's not for every kind of app; if you have something that requires lots of real-time graphical updates, like a MMORG or something, you should probably consider going native. But that's the minority of apps; 75% of the stuff I've seen in the iPhone app store, or more, could be served using the Citrix technology, which would give the developers the opportunity to deploy it to all the new platforms coming out. 

One big thing though; the Citrix Receiver is branded Citrix. This was a big downside, and I told the Citrix guys so; if I'm MTV, or Thomson Reuters, or CNN, or Disney, I'm not going to want my front-end gateway UI to be branded Citrix. I want people searching their platform's app store for my brand, and when they pull it down, I want to see my logo on their phone. Here's what it currently looks like:




To this, Citrix responded, "that's a real valid point. We're going to look into this". One of their developers that was on the call seemed to think it would be a no brainer to implement. So, from what I can see, Citrix is going to enable this. So, you brand the Citrix Receiver as your own...

...YOU DON'T EVEN HAVE TO BUILD IT. You just brand it and get it in the [ fill in mobile platform ] app store. 

Then you take your code base, deploy it to the Citrix solution on the EC2 cloud, and that's it. Anybody with the receiver can use your app, no matter what technology it's built out of. It just stuns me that people don't see the potential for this. If Citrix really puts in the time and makes this solution rock solid, it could very well represent a significant direction of the next wave of mobile device use. 

Citrix showed me how easy it is to do it; in fact, it looks so easy, and so cost effective to get up and running, that I'm going to try it with my Planet Sudoku app. They even have a little app shell, called "AppViewer" which you can embed your tech in, that takes care of the full-screen look-and-feel for you. 

Initially, I was going to port this thing to the iPhone, but now, as an experiment, I'm going to just refactor the UI to fit the iPhone, use the AppViewer shell, and deploy it with the Citrix solution; you'll be able to play my Sudoku client on your iPhone in a lot less time than if I retooled the whole thing to Objective C. More blogging to come on that one I'm sure. 

Is it really that easy? I don't know for sure, but as far as I can tell, this is a heck of a lot easier than porting the app to Objective C. In their own words (note that where they say "Windows", you can sub in "apps that run on Windows", like Java, Flash, Flex, Air, Silverlight, etc.):

"While unmodified Windows applications can be delivered to mobile devices via Citrix XenApp, XenApp also provides an excellent platform for delivering custom mobile applications. Citrix is seeing interest in this area from a number of it's ISV partners. The concept is to build the application using tools normally used to build full Windows applications, but simply design the user interface with the smaller screen size and resolutions of mobile devices as a design consideration. The concept is to reskin the UI of larger applications with a smaller form factor UI. As long as the custom mobile application can be published on Citrix XenApp, it can be delivered to mobile devices with the Citrix Receiver installed."

So, if this indie software developer can make this work, I'd pretty much say that anybody can, not matter what your reach is. You don't need deep corporate pockets; I don't actually know this for a fact yet, but I'm optimistic, and am actually trying it now, so I'll let you know. 

For more info on this topic, and/or to learn how to get involved in this sort of development, visit the Citrix developer community site, and take a look at the Tips and Tricks sections. 



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

Friday, May 15, 2009

Flash, Flex...on your iPhone?

I'm a Flash/Flex/Air developer primarily, with expertise in what I think of as "supporting" technologies (gateways and data layers built out of .Net, Java, PHP, Ruby, etc.). My usual contract gig is, I manage and/or work on an application's UI, using ActionScript technologies, and offer whatever assistance is needed to set up the gateway and data transfer backends. Sometimes I build all of it, sometimes I just have to work with the backend guys to understand how something like OpenAMF or Fluorine works, it depends on the client's expertise, but that's why they hire me. 

Flash/Flex, however, has been one of my greatest disappointments with the iPhone. We were promised "the complete web", and it's one of the reasons I jumped on the OG iPhone day one. Shortly after dumping my other phone and signing onto AT&T, I visited one of my ActionScript-based web apps...

...and discovered there was no Flash. Apple and their fanbois came back with a few short, lame justifications for this disclosure omission: "we support the open web, Flash is proprietary", "the Flash player is not really a Web 2.0 technology", were some of the things I saw bandied about. Fact is, it's the best solution for RIAs, and is getting stronger all the time. I've been doing this for 15 years, picked Flash/Flex for a reason, and the industry seems to support my decision; the NYTimes recently dumped Silverlight for Adobe Air, MLB did the same thing a while back if I remember correctly, and I'm currently working on a very large project that I can't talk that much about, but which will go live soon (and then I'll talk about it as much as I can). 

I have actually viewed Flash apps on my iPhone over VNC and RDP connections (check out WinAdmin in the app store). This lets me pull up a browser remotely, and access any web page I want, including ones with embedded flash apps. If the Flash app is designed properly, with a web page that properly sizes the browser, removed as many tool/status bars as possible, and so on, the experience isn't bad, but, I admit it's unreasonable to ask your average user to buy and install WinAdmin, or some other VNC client, to play a Flash game. I'd also have to provide the server for browser access, etc. 

It seems somebody has set out to solve this problem: Citrix. Take a look at this:

http://citrixcloud.net/

They offer a client for iPhone, called Citrix Receiver, which offers a 2-hour session, expires-in-24-hours, demo of access to the CitrixCloud. In their own words, the CitrixCloud, or C3 is "a complete set of service delivery infrastructure building blocks for hosting, managing and delivering cloud-based computing services. C3 includes a reference architecture that combines the individual capabilities of several Citrix product lines to offer a powerful, dynamic, secure and highly available service-based infrastructure ideally suited to large-scale, on-demand delivery of both IT infrastructure and application services. "

For the layman, that means more or less, "you can use our products to expose your apps to pretty much any client. With one of our viewers, a user can use any application on just about any client as if it was installed on their desktop". 

So, by now you may have guessed: The Citrix Receiver can provide access to Flash and Flex applications in a very compelling way. 

Ultimately, it's still the iPhone accessing web pages, but, it's not doing it through Safari, which can't run the Flash player. It's accessing a browser on a Windows machine remotely. The Citrix Receiver hides this though; you wouldn't really know it unless you were looking for it. The applications are sized full-iPhone-screen, some for landscape, some for portrait, and there's no browser toolbar or anything like that; you appear to be using a full-screen Flash/Flex app. 

So, when they go live with this (again, Citrix Receiver is a demo), does this mean I'll have to install the Citrix Receiver and understand all this cloud stuff to simply run an iPhone game?

Yes...and no. Here's a total hypothetical. Say you're an internet game company of some kind, something like a Pyzam. You're in the business of buying and developing Flash games, integrating advertising, all that. You create a branded version of the Citrix Receiver, and get your cloud infrastructure set up. Users go to the App Store, and get your branded viewer for free. They create an account, log in, and happily play Flash/Flex/Air games on their iPhone, with advertising and whatever else the developers build into the games/widgets/etc. 

I think that's compelling. Sure it needs more thinking through, and at this point is probably most useful to corporations or organizations housing large portfolios of Flash apps. But this is a direction that shows that, with some ingenuity, even today, you can offer applications built out of pretty much any technology on the iPhone. This also works with Windows apps, Silverlight, and so on, but I'm really interested in Flash/Flex. 

Also, it gets around a lot of the "pay for and we must approve" apps scenario, and enables use of ActionScript development resources, which are nowhere near the scarcity and premium of good iPhone development. If Apple doesn't like your content, they can reject your viewer though I suppose. 

So in the end...will phones just become all about the screen, and what viewer/cloud-access apps they can run? The thin-client finally plants its flag for good in the mobile world? Hmm...

Below are some screenshots from the Citrix Receiver demo. As always, thanks for reading Tcoz Tech Wire. 

Remember, these are Flash and Flex apps. They look great, and work as expected. These are screenshots right from the iPhone.

These two photos are of the Citrix Receiver interface for accessing different kinds of apps:







These images show some basic Flash/Flex apps from their demo. The first is a pretty standard reports app, the second shows network statistics in real time, the meters moved and everything just like a native app:







These images show a Shirt Configurator: you select colors, styles, logos, etc., and can save the profile. I found this very interesting.






Labels: , , , , , , , , ,

Monday, May 11, 2009

Climbing Mount iPhone Developerest: At the Foot (Getting it Up and Running)

If you didn't know from the blog description or my profile, I'm a software developer by trade. I've worked for American Express R&D, Microsoft, count Citigroup, Spectrum/IEEE and Thomson Reuters among my current project clients, and have run my own cottage dev shop for five years (lucratively enough to make a living, thank the powers).

My specialty for quite some time, actually as long ago as 10 of my 15 years in the field, has been, on top of competency with Java, .Net, PHP, and assorted ECMA scripting languages and whatnot, ActionScript development. I don't consider myself a "Flash" developer; "ActionScript programmer" is more accurate, though these days, I would add "Flex Developer" as well, since I work with and manage resources for some pretty big Flex projects. Facebook development is also up my alley, I actually was a paid reviewer for both O'Reilly Facebook dev books, but on the tech side, that really boils down to skill with ActionScript, JavaScript, and PHP (I do understand that integration of the social graph is another and equally important matter).

Note: Check out my Facebook Sudoku app, Planet Sudoku, at http://apps.facebook.com/planetsudoku.

Based on a history of development tools and languages that focus on the UI, and the fact that I own an iPhone and find it indispensable, it's probably no surprise that I got interested in iPhone development.

So there you are one day, saying out loud to nobody in particular (well, I do that now and then anyway), "I gotta get this rolling," and off we go.

Note: I'm aware of the open source alternatives to the official Apple SDK and so on; at this point, I'm only interested in being a fully legit, licensed, Apple iPhone developer, particularly because Apple makes it clear that any unsanctioned use means no App Store approval. I'm sure I won't be good enough to fool them for a long time, if ever, and I'm not prepared to take up the Jolly Roger for that cause right now.

So, my learning process, in a nutshell:

- Get a beta or something of the dev kit.
- Get the language book.
- Put on the strong black tea.
- For a month or so, allocate the time used for relaxing, working out, and playing guitar, to going through the samples, cursing at the screen, eventually figuring out how to make hello world appear when you click a button, getting the eventing mechanisms straight, learning how to call and use data, figuring out how to manipulate images...all the key stuff that you'd have to understand to be able to translate requirements, into features, into an app.

Additionally:

- Find the useful community resources (often done by googling for things that either seem broken in the book, or just because you know from experience there has to be a better way to do a certain something)
- See if any frameworks I already work with exist for the given environment (e.g. PureMVC for iPhone).

FYI, PureMVC for iPhone: http://www.darklump.co.uk/blog/?p=185. I will more than likely blog my experience with this port some day.

- See if you can find some practice certification material, or get the cert book; this is important to me not because I necessarily want to get certified (I used to take certification seriously, I don't anymore, but that's a topic for another day), but it's valuable to me to make sure I understand what's considered "essential" areas for a given technology.
- Maybe take a class or two. Instruction can never hurt, and it shows real interest to a potential client. This can be costly, but it's a write off.
- Avoid the design-time GUI tool until I know how to create basic applications with just the language. I firmly believe, if you don't know how the basic plumbing works and depend entirely on the UI design tool, and something doesn't work the way you expect, you'll be seriously behind the 8-ball.

That's how I've always done it, it's always worked, and that's how I intended to start my climb up Mt. iPhone Develeporest.

So...

- Go to the iPhone Developer Center, http://developer.apple.com/iphone/.

Tutorials, community, and download for the dev tool, XCode. So far so good, several of my steps knocked right out.

- Get the language book.

I got this one first, and recommend it, but I'll say it right now, it is NOT enough, even to get you started: iPhone SDK Application Development, O'Reilly, Jonathan Zdziarski.

I say "NOT enough" for two main reasons:

First, Objective C is different from C-based languages in many ways syntactically; at first glance, it's really cryptic. You ultimately see that it's actually not bad at all, but all the brackets and unfamiliar keywords, and having to write two distinct parts for every class (interface and implementation), can take you out of your comfort zone. I love interfaces and such, I'm an OOP nut, but I still found the conventions of Objective C a bit disorienting.

Second, iPhone development involves understanding "Views" and class hierarchies related to them. If you don't understand the language already, working with the iPhone API to implement views and attach things to them is not easy at all.

Realizing all this quickly, I got this book: Programming in Objective-C 2.0, 2/e, Stephen G. Kochan.

Now we're talking; excellent book that demystifies Objective-C. For the most part, you write "utility apps", like simple calculators and so forth, but it gets you grounded in the language, which really unlocks the iPhone API for you. I like the language now and have no issue writing classes and having them work together nicely.

Alrighty; I understand the language, at least enough to work with the tool somewhat productively. XCode has an iPhone emulator, so I've ported some of the utility examples from the Objective C book to the iPhone (like adding real buttons for the calculator) and run them in the emulator with no errors. I'm starting to feel like an iPhone developer.

So, let's get one of these sample apps on the iPhone. You have to register your phone as a "developer" phone...ok, not so bad, the iPhone site walks me through this, yeah yeah I know if I blow it up or it catches fire Apple is not responsible...alrighty let's get "Hello World" on and see how this process works...BLAMMO. Dead stop.

In order to put an app on your own iPhone (now registered as a dev unit), you have to register as an iPhone developer with Apple, and they have to send you a license key, which you use in combination with a certificate, to sign your app, so that it can be transmitted via your usual USB connector to your iPhone (XCode actually makes this seamless, very nice). Otherwise, you'll just develop with the emulator forever (again, I am not interested in hacks or workarounds to this).

This process takes time, and may not be as easy as it sounds. You can register a number of different ways; for example, as an independent developer under your own name, or as a business. I opted for the latter; Tcoz Tech Services, a sole proprietorship with a DBA that I've used for five years. Apple required that I fax (can you believe they don't accept emails of scanned forms?) my business registration documents to them, and that they review them, etc. If approved, you go on to the next step.

So, I complied. Again, BLAMMO. I don't live at the address that I originally registered the business under anymore. Apple won't approve your registration unless the mailing address you apply under, and the addresses on the documents (in my case, a DBA), are identical. This held me up for almost two months, so I will say in caps:

IF YOU ARE A CONTRACTOR RUNNING A SOLE PROPRIETORSHIP WITH A DBA, AND WANT TO REGISTER YOUR BUSINESS WITH THE IPHONE DEVELOPER PROGRAM, MAKE SURE THE ADDRESS OF YOUR BUSINESS REGISTRATION MATCHES THE ONE YOU REGISTER WITH!!!!!

Fair warning.

After quite a bit of back and forth, Apple did allow me to change my registration address to the one on the DBA; this was reasonable, because there is no law saying I have to live at the same address, it's entirely Apple's policy. It held me up, but they worked with me and I pushed it through. One day, Apple telephoned me, asked me some confirmation questions, welcomed me/my business to the program, and said I'd receive a mail taking me to the last step.

Hah, guess what...the last step is to PAY. That's right. You don't have to pay to learn Objective-C, or get the XCode dev tool, or the emulator. But that's all meaningless if you want to be an independent developer building iPhone apps that sell in the App Store. You need to be able to put them on the iPhone accordinlg to Apple hoyle, and unless you pay up (a little more than $100 a year), you can't do it. Talk about incentive to build and sell at least 120 copies of my first 0.99$ app!

I grumbled, and again considered going the open source hacker route (interestingly, as I understand it, the developers of the first iPhone SDK are in fact the guys that wrote the open source unofficial one, which preceded the official one), but no, I'm a pro, do the right thing, keep it above board.

After a journey of roughly four months, all the pieces are in place, and I'm now testing apps on my iPhone. Look out for my first iPhone app; will it be a hit? I don't know. It certainly won't be my magnum opus, but I do know it's original; I've looked carefully and there isn't one available that does what I have in mind.

Feel free to contact me at tcoz@tcoz.com if you have any questions.

Labels: , , , , , , , ,