Quick poll on debugging and tooling for Flex and PHP projects
As you know, one of my focuses as a Platform evangelist is Flex and PHP integration. Thus you can imagine I spend quite a lot of time doing Flex and PHP projects or research around these technologies. Lately I’ve been working on workflows for PHP and Flex (tooling, debugging, libraries) in light of the new tools (or new versions) we have been developing at Adobe. While some of these findings will see the light as articles, others are more intended as suggestions or feature request for upcoming versions of Flash Builder.
I’m really curious to find out:
- What tools are you using?
- What do you use for debugging?
- What frameworks (AMFPHP, Zend Framework, Doctrine etc) do you use when working on Flex and PHP projects?
- And the most important question: What features do you think Flash Builder needs in order to make you a happier/richer developer?
Please take some time and drop a comment with your thoughts around these questions.
And because I understand it takes some time to answer these questions, I want to give away three Flash Builder 4 licenses. I will choose randomly three lucky people from those who take the survey. The winners will be announced at the end of March, however you’ll get the licenses once we release Flash Builder 4 (now it is in Beta 2). Make sure you fill in your real name and a valid email address.
Flex SDK 3.5a is out
Yesterday we released Flex SDK 3.5a, an update to Flex SDK 3.5. This is from the Flex Team blog:
The Flex team has released an update to the 3.5 SDK that addresses an issue with the Flex-based AIR auto-update UI packaged within the SDK (SDK-24766). The refreshed build, SDK 3.5a, has only a few files modified in order to fix this issue and this change does not affect the signing and caching of the SDK 3.5 RSLs originally released in December.
We encourage all developers using SDK 3.5 to upgrade their build to SDK 3.5a to continue their development. The SDK 3.5a can be found in the “Latest Milestone Release Build” table here: http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+3.
Basically, this release fixes a bug related to the Update Framework: ApplicationUpdaterUI no longer works in Flex 3.5.
Webinar: using PHP and Flash for developing Rich Internet Applications
On December 2nd, together with Roy Ganor from Zend, I will host an e-seminar about PHP and the Flash Platform. We will show you how you can create a Rich Internet Application using the Flex framework, Illustrator, Flash Catalyst, and Flash Builder 4. Then we will show you how to connect the Flex application to a PHP backend and how easy is to debug the PHP and Flex code using Zend Studio 7.1 and Flash Builder 4.
You can register for free here. The webinar will start at 6:00 PM Central European Time (9:00AM Pacific Standard Time) on December 2nd.
LATER UPDATE:
You can download the slides from here, and next week the recording will be available you can watch the recording over here (you need to have a Zend account).
Magnifying Glass AIR 2 application or how to communicate with a Java program from AIR
My favorite feature in Adobe AIR 2 is, by far, Native Processes: the ability to launch and control and communicate with a native process. It could be any executable on the machine where the AIR application is installed. I think this feature opens up a whole new range of AIR applications. When you add this feature to the ability to create socket servers, you have a powerful platform to build RIA applications for desktops.
Once I heard that this feature would make it in AIR 2 I was very excited. Why? Well, back in 2008 when we launched AIR 1.0, my fellow evangelist Serge Jespers created one of the coolest AIR applications for the AIR Tour. It was the smallest video player in the world. Basically it let you watch videos in the application icon from the Dock.
The application is extremely cool, but it has a small issue: it is too damn small to be able to see what’s going on. Being an engineer, I spent some time trying to find an engineering solution. Of course, I could have asked Serge to rewrite the application to make it bigger, but this wouldn’t have been an engineering solution. It would have been something that an accountant or manager would come up with. My solution is to build a second AIR application that can be used to magnify the video played inside the icon. This application would act like a digital magnifying glass.
With AIR 2 I’m finally able to implement the magnifying glass app pretty easily. Below you can see a screenshot of my application in action. It has two windows. The first window is the view port of the magnifying glass. You can see how many frames per second it processes, you can control the amount of zooming, and you can drag it around your screen. The second window displays the magnified image.
The internals
How did I do it? The application has two main parts. One part is the AIR application itself. It renders the UI, controls the view port and the zoom factor, and scales the image. The second part is a Java program that captures a screenshot of a portion of the screen. The Java program is controlled by the AIR application.
Using the NativeProcess and NativeProcessStartupInfo classes from AIR 2, you can launch an executable. In order to communicate with the executable you can use standard input and standard output. I wrote the Java program to output the bytes of the screenshot to standard output. It listens to standard input for commands, such as take a shot, set the viewport, or terminate the program. I compiled the Java program as an executable JAR file and placed in the AIR application root folder.
In order to capture the output of the Java program all you have to do is to register a listener on the NativeProcess instance for the standard output events. When you want to send commands you write bytes to the standardInput property of the same object. Here is a snippet of code, for the complete code have a look at the ScreenShotService class from the AIR application.
1: private var nativeProcess:NativeProcess;
2: private var npInfo:NativeProcessStartupInfo;
3: //setting the arguments for starting the Java program
4: var arg:Vector.<String> = new Vector.<String>;
5: arg.push("-jar");
6: arg.push(File.applicationDirectory.resolvePath("screenshot.jar").nativePath);
7: arg.push("130");
8: arg.push("100");
9:
10: npInfo = new NativeProcessStartupInfo();
11: //setting the path to the native process
12: npInfo.executable = new File("/Library/Java/Home/bin/java");
13: npInfo.arguments = arg;
14:
15: nativeProcess = new NativeProcess();
16: nativeProcess.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onStandardOutputData);
17: //start the process
18: nativeProcess.start(npInfo);
19:
20: /**
21: * Read the data from the standard ouput.
22: * Before reading a png, first you have to read the length of the image
23: */
24: private function onStandardOutputData(e:ProgressEvent):void {
25: //reading the available bytes from the standard output buffer of the process
26: nativeProcess.standardOutput.readBytes(_processBuffer, _processBuffer.length, nativeProcess.standardOutput.bytesAvailable);
27: ...
28: }
29:
30: //sending take command to the Java process
31: nativeProcess.standardInput.writeMultiByte("take\n", "utf-8");
This is the relevant Java code (you can find the complete code inside the source folder of the application, ScreenShot.java):
1: /**
2: * @param width of the screen capture
3: * @param height of the screen capture
4: * @param args
5: */
6: public static void main(String[] args) {
7: if (args.length == 2) {
8: width = Integer.parseInt(args[0]);
9: height = Integer.parseInt(args[1]);
10: }
11:
12: ScreenShot s = new ScreenShot();
13: BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
14: String text = "";
15: String[] tokens;
16:
17: while (true) {
18: try {
19: text = in.readLine();
20: if (text.equals("take")) {
21: s.capturePortion(x, y, width, height);
22: } else if (text.equals("terminate")) {
23: return;
24: } else if (text.length() > 0) {
25: tokens = text.split("\\|");
26: if (tokens.length < 4)
27: continue;
28: x = Integer.parseInt(tokens[0]);
29: y = Integer.parseInt(tokens[1]);
30: width = Integer.parseInt(tokens[2]);
31: height = Integer.parseInt(tokens[3]);
32: }
33: } catch (IOException e) {
34: System.err.println("Exception while reading the input. " + e);
35: }
36: }
37: }
38:
39: /**
40: * Capture a portion of the screen
41: */
42: public void capturePortion(int x, int y, int w, int h) {
43: try {
44: if (robot == null)
45: robot = new Robot();
46: BufferedImage img = robot.createScreenCapture(new Rectangle(x, y, w, h));
47: ByteArrayOutputStream output = new ByteArrayOutputStream();
48: ImageIO.write(img, imageType, output);
49:
50: DataOutputStream dataOutputStream = new DataOutputStream(System.out);
51: //output the buffer size
52: dataOutputStream.writeInt(output.size());
53: //output the buffer
54: dataOutputStream.write(output.toByteArray());
55: dataOutputStream.flush();
56:
57: output.close();
58: } catch (AWTException e) {
59: System.err.println("Exception while capturing screen. " + e);
60: } catch (IOException e) {
61: System.err.println("Exception while writting the image bytes. " + e);
62: }
63: }
I am by no means a designer. Still, I think I managed to get a decent look of the main application window using Adobe Illustrator and Flash Catalyst. I created the design in Illustrator, and then using Flash Catalyst I transformed the graphics into a Flex application. And finally using Flash Builder 4 I added the logic.
Source code and native installers
You can download the Flex project from here, Mac installer from here, and Windows executable from here. This program requires Java 5 or newer and the Adobe AIR 2 runtime.
Things to know when working with Native Processes in AIR
In order to enable this feature you need to add the extendedDesktop profile to the application descriptor file. Add this tag as a child of the application tag:
1: <supportedProfiles>extendedDesktop</supportedProfiles>
When using this feature you can’t package your application as an AIR file for distribution. You have to use the native installer. The easiest way to do this is to export for release from Flash Builder (you get the AIR file you normally use to distribute your application). And then you use adt at the command line to create the native installer. If you want a Mac installer you do it on a Mac, if you want a Windows installer you have to do it on a Windows. The command looks like this:
1: adt -package -target native myApp.exe myApp.air
More on how to create native installers for AIR applications here (make sure you use the adt from AIR 2 and not one from an older version).
If you see an error like in the picture below when you install an application using the generated native installer, you should create a file named .airappinstall.log in your home folder. This log file can tell you what was wrong. In my case the error was “failed while validating native package: Error: Missing digested package file: .DS_Store starting cleanup of temporary files” (I fixed the problem by deleting the .DS_Store file from the source folder).
Finally, you can check at runtime if the application has extended desktop capabilities by using this:
1: if (NativeProcess.isSupported)
2: //extended desktop profile is available
3: else
4: //extended desktop profile is not available
What’s next?
If you haven’t already, download the Adobe AIR 2 runtime and SDK and play with the new features. You can find a nice article about the new features from AIR 2 on Christian Cantrell’s blog.
I already have another idea: what about an AIR application that does screen sharing? Keep an eye out I might be able to pull it off!
PS. Many thanks to my friends Chicu and Raul from the Romanian AIR team for their help.
Later Update: My friend Benjamin Dobler created a nice screen recording application with AIR 2 (it captures the sound as well). Although for now the source code is not available, I still think it is worth having a look.
PHP and Flex Webinars
Last week I visited Zend headquarters, and I had an interesting talk over there. One effect of this meeting is this: we will start to do webinars together with Zend.
If you want to find more about Zend Studio and other products related to PHP from Zend, or learn more about the integration between the Flash Platform and PHP (Flash Catalyst, Flash Builder, Flex framework) you shouldn’t miss this opportunity. I know that webinars don’t offer the same experience as in-person events. On the other hand, you can attend them from the comfort of your own home, there is no traveling involved and no need to convince your boss to let you attend the event.


We haven’t set the first event date yet, but it should be in the first week of December, and probably it will be in the evening (Central European Time).
Keep an eye on my blog for the exact date and time.
PayPal Express Checkout with Flex and Adobe AIR
Miti was very busy this summer and if you read his article you can see why. If you want to integrate your Flex application (web or AIR) with PayPal his article on this matter is a must.
In this article, I will show you how to integrate PayPal Express Checkout with either a Flex application running in Flash Player or an Adobe AIR application. Express Checkout streamlines the checkout process for PayPal buyers, but there are security implications for using it in stateful applications.
l will review the security and UI considerations, introduce the architectural approach, and then show you how to implement the whole thing. You can also download working samples to see how everything works together.
New Flex 4 samples in Tour de Flex
Holly Schinsky (from Adobe) created 22 Flex 4 samples that were added to Tour de Flex. More are planned. Check her blog for more about these samples, and check Tour de Flex to see the examples.

Flex for PHP developers article
Finally, I managed to finish an article that introduces Flex to PHP developers comparing features from both worlds (when it makes sense). I’ve been working on this subject from the beginning of this year. Thus I am so happy that I feel I should go out and smoke a fine Cuban cigar
While working on this article I realized two things:
- Writing books it is not easy. My work doesn’t compare with a book at all, but still the amount of work was huge. Now, I have an idea about what it means to work on a book.
- Learning a client-side technology coming from the server-side world will never be an easy and straightforward task. You have to adapt to a new world and adopt a different mindset. But then again, with big efforts usually come big rewards! And from my experience, when I learn something new I can always apply some of this knowledge to the concepts I’ve already known.
Enjoy the article and let me know what do you think!
About unloading Flex modules
Alex Harui (he’s part of Flex SDK team) has a great post about what could cause a module not to be unloaded. Actually you might want to keep an eye on his blog, because you can find great tips for Flex there.
Enjoy!
Flex 4 bidirectional data binding: chicken or egg?
One of the many new features in Flex 4 is bidirectional data binding. I think it’s a useful addition because many times you have a data model that you bind to a form, and you want any changes in the form to be reflected back into the data model. With bidirectional data binding you can do this on the same line that you defined the binding, so there is no need of additional code (as was the case in Flex 3).
Here are the two syntaxes for declaring the binding as bidirectional:
- <s:TextInput id=”txt” text=”@{value}”/> – notice the addition of “@”, this is the operator used to mark the binding as bidirectional
- <fx:Binding destination=”txt.text” source=”value” twoWay=”true”/> – notice the twoWay attribute
However, I have to warn you that it might not work as you’d expect. Let’s have a look at the following code:
1: <?xml version="1.0" encoding="utf-8"?>
2: <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"
3: xmlns:mx="library://ns.adobe.com/flex/halo" minWidth="1024" minHeight="768" creationComplete="init()">
4: <fx:Script>
5: <![CDATA[
6:
7: [Bindable]
8: private var labelValue:String = "Hello World!";
9:
10: private function init():void {
11: trace(labelValue);
12: trace(txt.text);
13: }
14:
15: ]]>
16: </fx:Script>
17: <s:TextInput id="txt" text="@{labelValue}"/>
18: </s:Application>
We have a String variable with the default value “Hello World!”, and this variable is the source of data binding for the TextInput text variable. You might think that the execution of init() function will output:
1: Hello World!
2: Hello World!
Actually, the output is nothing! When I run this code for the first time I was puzzled. I then used the debugger to see what it was happening behind the curtains.
This is what I found:
- The application starts to initialize
- First the labelValue variable is initialized and triggers the property watcher (because it is used in binding)
- But at this point, the TextInput field is null, and the binding cannot be completed
- Next, the initialization of TextInput starts
- By default, the text property of this field is an empty string “”
- Because the TextInput is part of data binding too (remember the data binding is bidirectional in my code), the property watcher executes and sets the value of labelValue to empty string
- Finally, the application finishes its creation and the init() function is executed. By now, both the variable and the text property of the TextInput have the same value, empty string
Elementary my dear Watson!
If I want the code to work as I intended, I have to initialize the labelValue variable on the creationComplete event or after:
1: private function init():void {
2: labelValue = "Hello Wold!";
3: }
I guess this is one of those problems: who was first, the chicken or the egg?

