Showing posts with label flex. Show all posts
Showing posts with label flex. Show all posts
Friday, June 05, 2009
Wednesday, April 22, 2009
ActionScript Quickie: Check for Required Params
private function validArgs(...args):Boolean{
return args.every(function(arg:Object, ...crap):Boolean {
return arg ? true : false; });
}
Usage:
var firstName:String = ...
var lastName:String = ...
var iq:int = ...
var friends:Array = ...
validArgs(firstName, lastName, iq > 100, friends.length);
Wednesday, November 19, 2008
Gumbo and Data
Recently I finished an article for IBM on using Grails and Flex together. In the article I created a Digg-clone and used things like Flex DataGrid and Forms to browse and submit stories. I decided to see how well the new Flex Builder tools could create the same code for me. So I took the existing service and imported into Flex Builder

The screenshots give you an idea of the process. As you can see from the final screenshot, there is a lot of code generated! A service proxy and return types are both generated. Actually for each there is a base class with all of the guts and empty class built for you to customize. There is a modeling class that contains metadata about the return type. The base service class uses a new Flex class HTTPMultiService. It is a lot of code, a lot more than I wrote. Most of it seems reasonable though.
You can also generate a data grid for displaying the data. This worked perfectly for me. Gumbo also promises that in the future you will be able to generate other components, in particular a Form.
Tuesday, November 04, 2008
Wednesday, October 22, 2008
AjaxWorld 2008
1.) Comet. There were a lot of talks about some form of data push from the server to the browser. Kevin Nilson did a nice job of differentiating Ajax (infinite loop of XHR polls) vs. Comet (long poll.) The folks at ICEFaces have built some nice abstractions on top of Comet. There was also a lot of interest around WebSockets, especially the work by the folks at Kaazing. A duplexed socket connection to the server sounds great on paper. I think there will be some very interesting technologies that grow around that.
2.) Don't make me learn JavaScript! There seemed to be a lot of folks advocating the "only know one language" approach to the web. In most cases that language was NOT JavaScript (even though the Jaxer guys say it can be.) Vendors liked Oracle and ICEFaces preached abstractions that shielded the developer from JavaScript. Of course the GWT folks say do everything in Java. Microsoft says use Silverlight so you can do everything in C#. Of course one of the best sessions was by Doug Crockford who told everyone to man up and learn JavaScript. I tend to agree with Crockford, even though I prefer ActionScript...
Labels:
ajax,
ajaxworld,
comet,
flash,
flex,
gwt,
icefaces,
javascript,
kaazing,
silverlight,
websockets
Tuesday, September 30, 2008
WSDL in ActionScript
This is ok for a single developer or even a small team. Once you get to larger scale development, you usually want to keep code generated artifacts separate for the source code that generated them. Often you never want to check-in generated code. Why? Because then you have two sources of truth: the artifact (WSDL in this case) and the generated code. You don't want to have to keep these things in sync manually, you want your build process to do it. So you don't check in the generated code, and your build system generates it instead.
So ideally the code generation in Flex Builder could be invoked outside of Flex Builder. This may be the case, but so far I have no luck in this. It is certainly not a documented part of the SDK.
I looked for an alternative and found wsdl2as. This looked promising, but did not work out. First, it expects you to send in XML literals when sending SOAP messages. Sure it generates the boilerplate around the core message, but if I wanted to work directly in XML, I would not have bothered with a code generator. It has an option that seems designed to deal with this, but did not. Even worse, it does not handle anything except the simplest WSDLs. The first WSDL I tried with it defined complex types for the input parameter and return type of the web service. This caused wsdl2as to choke, as it expected any type information to be inlined. Sigh.
Thursday, August 28, 2008
Search Twitter from Flash
Twitter's API is all based on Rails ActiveResource ... which is awesome. It turns any resource (often a database table) into a RESTful service. REST is often associated with XML, but Rails (and thus Twitter) supports it as JSON (Twitter supports ATOM and RSS as well) too. For ActionScript, XML is great. Or I should say POX is great and that is what Rails serves up.
The Twitter Search API is different. It supports two formats: ATOM and JSON. No POX. I went with the ATOM format. For JSON, I would have used Adobe's corelib. It works well, but I didn't want to add the weight. Plus, JSON tends to parse much slower in AS3 than XML. That is because AS3 implements E4X. To get E4X to work with ATOM, you have to be mindful of namespaces. For example, here is the code I used to interate over the entries: for each (entryXml in xml.atom::entry). Here the xml variable is the parsed result from search.twitter.com and atom is a Namespace object. Not as pretty as just xml.entry, but oh well.
Monday, June 09, 2008
Gears and Flash
This was not too hard. It is just a matter of using ExternalInterface to create a bridge between the two worlds. I wrote a quick POC, using a simple DB table for storing name/value pairs. I think it would be fun to re-implement the flash.data package that is normally only available in AIR apps...
Here is the JavaScript code:
function dbCall(sql, args){
var db = google.gears.factory.create('beta.database');
var rs = null;
try{
db.open('database-test');
db.execute('create table if not exists little_table (key varchar(20), value varchar(100))');
rs = args ? db.execute(sql, args) : db.execute(sql);
data = [];
while (rs.isValidRow()){
row = {};
for (var i=0;i<rs.fieldCount();i++){
var name = rs.fieldName(i);
row[name] = rs.field(i);
}
data.push(row);
rs.next();
}
return data;
} finally {
rs.close();
}
}
Here is the ActionScript code:
import flash.external.ExternalInterface;
[Bindable]
private var rs:Array = [];
private function load():void{
rs = ExternalInterface.call('dbCall', 'select * from little_table');
}
private function save():void{
var key:String = keyIn.text;
var value:String = valueIn.text;
ExternalInterface.call('dbCall', 'insert into little_table values(?,?)', [key, value]);
keyIn.text = "";
valueIn.text = "";
load();
}
private function clearData():void{
ExternalInterface.call('dbCall', 'delete from little_table');
load();
}
And here is the MXML I used to test it out:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="load()">
<mx:DataGrid x="202" y="59" id="grid" dataProvider="{rs}">
<mx:columns>
<mx:DataGridColumn headerText="Key" dataField="key"/>
<mx:DataGridColumn headerText="Value" dataField="value"/>
</mx:columns>
</mx:DataGrid>
<mx:Label x="10" y="251" text="Key"/>
<mx:TextInput x="74" y="249" id="keyIn"/>
<mx:Label x="242" y="251" text="Value"/>
<mx:TextInput x="285" y="249" id="valueIn"/>
<mx:Button x="460" y="249" label="Save" click="save()"/>
<mx:Button x="243" y="298" label="Clear" click="clearData()"/>
</mx:Application>
Labels:
actionscript,
air,
flash,
flex,
google gears,
javascript,
ria
Friday, May 09, 2008
Flex at JavaOne
Currently I'm watching talk where they are building an app with Flex, JSF, and WPF (Silverlight?) The speaker is developing live on stage. This seems dangerous, but it is going quite well. It is barely tapping the potential of Flex, but is very convincing. An interesting comment was that Flash is limited because it cannot do any 3D. Of course this comment is coming from a NVDIA engineer, but it is a valid point.
It is very nice to have so many non-Java related talks at JavaOne. The content of JavaOne has really aligned well with the interests of the attendees. I think next year it will be even more so. I predict that next year the dynamic languages will take over and command the biggest audiences.
Monday, April 21, 2008
Video Solution
Video Importing/Editing: iMovie. This is what I was already using. iMovie is famously easy to use. The importing is easy, the editing is easy. The default export is .m4v files, which are H.264 files designed to work on iPods. This is important.
Video Playing: Flash. I wrote my own video player using Flex. The Flash player has built-in support for H264 video. Thus the videos I export out of iMovie play naturally in the Flash player. They just need some Flash code to load and control the video stream. I wrote this myself as it was pretty straightforward. I created an external XML file as a metadata repository. This tells my player what videos are available and information about each video, like its size. I hosted the custom built player and metadata files on Google Page Creator.
Video Storage: Amazon S3. This was the most difficult part. S3 is relatively cheap. It is NOT easy to use, contrary to what others might say. I was shocked to discover that there is no interface (web or desktop) for uploading and managing files stored on S3. I wound up using S3Fox. It seems like a nice interface, but buggy. Amazon really should offer administrative tools.
Next Steps: Ideally I would build a plugin for iMovie that would upload the video to S3 and write the metadata about the movie to my Google Pages. I am thinking of doing an AIR app for this first, and then maybe go Cocoa. I must also monitor my usage to make sure that S3 is cheaper than other alternatives like Box.net.
Tuesday, April 08, 2008
Twitter API in ActionScript
It needs a lot of work. I basically removed the old authentication scheme, since it relied on setting the Authorization HTTP header and that is no longer allowed starting in Flash Player 9.0.115. This also let me remove a dependency on a third party base 64 encoder. I guess a base64 encoded string that includes your username and password is supposed to be secure :-) I also fixed the loadFriends method, as this now returns users not status messages. I will get the API up to date, but if anyone wants to help out then just send me a note.
Thursday, March 13, 2008
Silverlight Stocks
This look-and-feel is all defaults. It looks like a web page! It's usually easy to spot Flex apps, but that is not as true with Silverlight. Everything works the same as with the Flex or GWT versions, except the color-coding for stocks that are up or down. I figured out how to define styles with Silverlight (more on that) but could programmatically set the style. Let's take a look at the code. First the UI code.
<UserControl x:Class="SilverStocks.Page"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Enter Symbol "/>
<TextBox x:Name="symbol" Width="100" KeyDown="symbol_KeyDown"/>
<Button Click="Button_Click" Content="Get Info" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Company Name: "/>
<TextBlock x:Name="company"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Price: "/>
<TextBlock x:Name="price" Text="$"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Change: "/>
<TextBlock x:Name="change" Text=""/>
</StackPanel>
</StackPanel>
</UserControl>
Pretty similar to MXML, but distinctive. As with ASP.NET pages, Silverlight puts all code in a code-behind file:
public partial class Page : UserControl
{
const string url = "http://localhost:8080/Stocks/Stocks?symbol=";
public Page()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
invokeStockService();
}
private void invokeStockService()
{
string symbol = this.symbol.Text;
WebClient service = new WebClient();
service.DownloadStringCompleted += new DownloadStringCompletedEventHandler(handler);
service.DownloadStringAsync(new Uri(url + symbol));
}
private void handler(object sender, DownloadStringCompletedEventArgs args)
{
if (args.Error == null)
{
this.showInfo(args.Result);
}
}
private void showInfo(string xmlContent)
{
XDocument root = XDocument.Parse(xmlContent);
var stocks = from xml in root.Descendants("stock")
select new Stock
{
Symbol = (string) xml.Element("symbol"),
Company = (string) xml.Element("companyName"),
Price = Decimal.Parse((string)xml.Element("price")),
Change = Decimal.Parse((string)xml.Element("change"))
};
foreach (Stock stock in stocks)
{
this.company.Text = stock.Company;
this.price.Text = stock.Price.ToString();
this.change.Text = stock.Change.ToString();
}
}
private void symbol_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
this.invokeStockService();
}
}
}
Notice that I used the LINQ-XML cleverness, as advocated by Scott Gu. Most dynamic language folks will probably favor ActionScript's E4X over using this lambda-ish query language and a statically defined class. Actually I'm sure I could refactor this to not use the class at all, and just set the text fields during the query.
Finally, the other major difference between the two is the Flex framework's mx:HttpService. This component encapsulates the call to the back-end and provides dynamic binding. There is no handler code in the Flex version because of the binding. Will data source bindings and components like mx:HttpService find their way in to Silverlight?
Labels:
actionscript,
c#,
flash,
flex,
gwt,
linq,
microsoft,
ria,
silverlight
Wednesday, March 12, 2008
JsonViewer Updated
I updated Flex Builder 3 to the GA version and updated AIR to 1.0. I imported the old project. It picked up my Subversion settings and what not, very nice. I did a new "export release version" and it worked just fine. I tried to execute the .air file and it bombed. It told me that my AIR file was damaged.
WTF!? I tried to run the app directly from Flex Builder. It did nothing. No errors, just nothing. So I tried debugging. Then I finally got an error message about using the wrong version of AIR. I opened up the JsonView-app.xml. There was no "setting" in here for AIR version, but then I saw this
<application xmlns="http://ns.adobe.com/air/application/1.0.M6">
Yep the .M6 was killing me. I removed it from the XML namespace declaration, and voila! Everything worked perfectly. Show your appreciation for my pain by downloading JsonViewer.
Friday, February 29, 2008
AJAX, the REST Killer
After the presentation, one of my colleagues pointed out that a lot of times we are forced into GETs because of cross-domain calls. He was right, and made me realize how the hack-that-is-AJAX is always rearing its ugly head. Cross domain calls are part of life for any large, distributed site. In an AJAX world you either have to use JSONP style calls, i.e. using a Script tag to make your call, or you have to use a server proxy. Of course going directly to the appropriate domain is much more efficient, so JSONP is going to usually win. There's no way to do an HTTP POST on a Script tag, so there you go. Forget all about respecting the REST protocol.
Of course Flash and Silverlight (gotta include it now!) both allow for declarative cross domain security. No need for JSONP hacks. Now if only they both supported HTTP PUT and DELETE...
Labels:
ajax,
flash,
flex,
jsonp,
rest,
silverlight,
web development
Thursday, February 28, 2008
Silverlight Slim and Fat Flex
When Adobe announced that the Flex framework could be cached on the Flash player across domains, I wondered why the didn't just included it with the Flash player. I have even bugged Flex evangelist Ted Patrick with this question. His response to me was that they would open themselves up to "DLL hell." In other words, there could be problems with people building their app against Flex framework version X, but a user has an older version installed.
As if this doesn't already happen! Let's not forget that Adobe jumped ActionScript from version 2.0 to 3.0 and thus required Flash player 9 or higher for anything authored using 3.0. This was not just some update in framework, it was the entire programming language being overhauled. It is common to use JavaScript to detect Flash player version and require people to upgrade. It is so common and so part of Flash development, that Adobe distributes the ExpressInstall SWF for doing this as easily as possible. Heck, I usually require users to be on 9.0.28 or higher, since that is the version that fixed some bugs with ExternalInterface.
So back to the Flex framework/DLL hell issue. It would simply require people to check for a certain minimum version of the Flash player (since that would correspond to a version of the Flex framework) and prompt for an upgrade if needed. In other words, it would require something that most folks already do today.
To me the real reason is that it is more economical for Adobe to not include the Flex framework. Ted has a widget he wrote showing over 3.9 billion downloads of Flash player 9. Add an extra 200K to that and you get over 726 TB. That's a lot of bandwidth to pay for. That's a price Microsoft wants to pay, because it would indicate lots of folks with Silverlight installed. Perhaps once that happens, Adobe will reconsider.
Labels:
actionscript,
adobe,
flash,
flex,
microsft,
silverlight
Tuesday, February 12, 2008
New Version of JsonViewer: Now Open Source!
So you can get the latest version here, or you can check out the source code for yourself. I was almost embarrassed to show the source because it so trivial!
Thursday, January 10, 2008
Flash and HTTP Headers Redux
The opinion seems to be that Adobe does not allow this because not all browsers will provide this information to the Flash player. I have not seen a list of what browsers have this limitation, though I will speculate it must be older versions of popular browsers... Some of the evidence of this is that this is provided in AIR. In AIR, it is the runtime itself that makes HTTP requests. In a SWF running in a browser, the runtime relies on the browser. So restrictive browsers could be an issue on a SWF, but never for an AIR app.
Could another reason be security? In particular, cookies are passed back-and-forth via HTTP headers. There are numerous cases of cookies being stolen by malicious JavaScript, which has total access to HTTP headers. Adobe made a lot of significant security improvements between Flash Player 8 and 9. In a world of mashups, are they better off continuing to deny access to HTTP headers?
All of that being said, I recently ran across another case where this causes problems. I had a SWF that could be loaded by two different pages. It needed to show slightly different features depending and have a different look and feel depending on what page it was on. The easiest thing to do would have been for it to "know" what page was loading it by looking at the referrer on the HTTP request that loaded the SWF. This is a header of course, and thus not available. Instead a FlashVar could be passed in to tell the SWF what to show. That's a better way to do it, but required changing the code of the page hosting the SWF, which was not an option. The hack that had to be used was to have to logical copies of the same SWF, foo_A.swf an foo_B.swf. The SWF could then look at its this.loaderInfo.URL to figure out what to show.
Thursday, November 29, 2007
Meebo Platform and ActionScript
Several things jump out quickly, but let's state the obvious ones. They provide a Flash component for Flash 8. Now it's cool that they provide a component (even if "installing a component is arcane), but Flash 8. Seriously? Clearly this is something written in ActionScript 2.0. Now it would be one thing if they wanted to provide some support for AS2 developers, but what about AS3? It just seems crazy for a brand new platform to not support the latest version of one of the two languages it supports. It would be like Silverlight only supporting C# 1.1.
There's also the issue of providing support for the Flash IDE exclusively as well. I guess with AS3 support only, this is all you can expect. The Flash IDE is not made for developers, it is made for designers. Flex Builder is obviously the choice for developers, though it has its drawbacks.
I didn't see if Meebo provides the source code for the SWC. If they did, it probably wouldn't be too hard to compile it for AS3. Actually you might be able to use the AS2 component within an AS3, I haven't tried that. Still, if you're going to launch a me-too platform, at least do it right.
Tuesday, November 13, 2007
The Network Application Pattern
The list of technologies was all over the place: PowerBuilder, Swing, and Visual Basic. The reasons for the conversions were pretty similar though: make things more easily accessible. It was much easier to say “you need InternetExplorer 5.5 or higher” to run an application, than it was to require somebody to download and install, and stay upgraded to the latest version of an application. The hardest part about these conversions was trying to reproduce all the functionality. You just could not do it, and there were always compromises that you had to work out with the clients on this.
These days I am starting to think that such compromises are unacceptable. The days of the thin client are coming to an end. At the same time, the days of the thick client are not coming back. Instead a different pattern has emerged, and it is going to win. I call it the Network Application, though other folks have different names and different takes on it. Here is what it is.
Misuse of Big Iron
To make things as accessible as possible generally meant to require as little as possible on the end user’s machine. The browser wars necessitated this as well. Inconsistencies across browsers required a least common denominator approach. The browser become a rendering device, and nothing else really.
All the computation required to determine the interface shown to a user was performed on servers. For awhile these servers were Big Iron -- look at how well SUNW did in the late 90’s. Moore’s Law caught up and lots of cheap servers replaced Big Iron, but the usage pattern remained unchanged. Programming languages flourished around this. Look at all the UI frameworks in Java, the explosion of PHP, and the emergence of Ruby on Rails.
Another Shift
I am not one of those melodramatics who look for a single event and say “this epoch caused everything to change.” Things started changing. Browsers stabilized and Moore’s Law kept moving along. Microsoft’s attempt at subverting web browsers by creating IE-only extensions, ultimately backfired on them. They created XMLHttpRequest, which ultimately allowed for exactly what the Netscape think tank had always hoped for and Microsoft always feared: web applications that were on-par with desktop applications. Well sort of...
Web applications still have a lot to be desired. As I mentioned earlier, it can be really hard to reproduce a desktop experience in a browser. There are a lot of things going on to solve that, and some of them might even work. Orthogonal to the technologies at play is the pattern of how to program applications that are as feature rich as desktop applications, but can be run from a browser with no software to download or worry about updating.
The Pattern
The key to the pattern is to stop using servers for creating user interfaces. If you like to think of UIs using the popular Model-View-Controller paradigm, the server should only be a place for Models. Your View and your Controller should be running on a client computer, not a server. Your server will probably serialize a Model to send to the client so it can use it in a view, but otherwise the boundaries should be very clear.
Why does this help with the problem of creating desktop-like applications? Because when all the view logic is located on the client, there are no limitations to the interactivity. For an example, think about infinite scrolling like you see in Yahoo Mail (I usually rip on Yahoo, so I thought this would be a nice change of pace.) If the view of the list of your emails is formed on a Yahoo server, then to scroll past the bottom means recalculating that view on a Yahoo server, even if it is to show one more email that is just past the bottom of the list. If you had to do it that way, you would not allow scrolling. You would force pagination, like GMail does. However, if you already have the code for creating that view on the client, then all you need on the client is the data to display.
Servers Are for Services
The beauty of this pattern is that your servers become specialized in serving up data, not HTML. There is still some overhead in de-serializing the request and serializing the response and making it all work over HTTP, but it’s a lot less than the alternatives. Of course it’s not a read-only world, so you’re not just sending out data. You are also receiving changes to the data, either directly, or (hopefully) via a service interface. Just because we’re getting clever with our presentation design, doesn’t mean our middle-tier design can be garbage.
Notice I used the Service word. This is the same word used by those SOA guys, and it means the same thing. There’s no reason that the clients that you build for your service (in this case user interfaces) cannot leverage the same infrastructure that clients built by other folks use. Now you may want to expose more services to the user interfaces that you built, or maybe you don’t... The point is that if you decouple the so called business logic of your system, then it is easy to build Network Applications that provide rich user interfaces to the end users of your system.
Implementations of the Pattern
Like most patterns, this was one has emerged from implementations. It is not something I dreamed up in my ivory tower in San Jose. One of my favorites is the Google Web Toolkit. GWT let’s you build things kind of like you would for the old-school thick clients using Swing, but it turns around, turns everything into code that runs on the client. One of my friends was starting to learn GWT recently and I think he was surprised when I told him that everything in GWT becomes static assets that can be served up by any web server directly. They are very cache-able assets as well... There are GWT ways to hook up your server calls as well, and of course this does require a Java application server. But that part of your code can be done in JavaScript, using GWT’s JavaScript Native Interface (JSNI.) The nice thing about using the GWT server code is that you get to use the same object model on client and server.
GWT is tied to JavaScript, and thus it inherits the limitations of JavaScript. My other favorite implementation of the pattern is Adobe Flex. Flex Builder 3 even has code generators for creating Java or PHP data services for communicating to your Flex application. Flex applications run inside the Flash player, and don’t have nearly as many limitations as JavaScript applications. Flex applications are usually much bigger than JavaScript ones, but are also very cache-able. Bandwidth is becoming less of an issue in terms of user experience, though it is still a cost issue.
The Moral of the Story
If you are a UI engineer, you should not be writing HTML. You should only be writing code that executes on the client. There are many other options out there. In the JavaScript world, there’s Dojo’s Dijit, the Yahoo UI Library, even script.aculo.us. Ruby on Rails’ RJS has some similarities to GWT, but is not there yet. The Rails guys are still perfecting the last generation of web applications, and have not moved on yet :-) Straddling the JS and non-JS worlds is OpenLaszlo. I would be more enthusiastic about Laszlo if it was using new Flash technologies. On the non-JS side, the two chief non-Flash entities are Microsoft’s Silverlight and JavaFX.
Now again, these are all technologies that can be used with this pattern. They can also be used outside of the pattern, though I would say that is probably a mistake :-)
Labels:
design patterns,
flex,
gwt,
javascript,
laszlo,
microsoft,
mvc,
webdevelopment
Friday, November 02, 2007
ActionScript Getters and Setters
It's always nice when a programming language surprises you in a pleasant way. ActionScript 3 has get/set property syntax, very similar to C#:
public class Person implements IPerson
{
private var m_name:String;
public function get name():String
{
return m_name;
}
public function set name(value:String):void
{
m_name = value;
}
}
What was an even nicer surprise is that you can define properties in an ActionScript interface:
public interface IPerson
{
function get name():String;
function set name(value:String):void;
}
And then write code that makes it look like you're accessing the field of an inteface:
var person:IPerson = new Person();
person.name = "Michael";
Now if only we had this syntactic sugar in Java...
Labels:
actionscript,
c#,
development,
flash,
flex,
java,
programming
Subscribe to:
Comments (Atom)