Tag Archive for 'Flex'

MXML in AS3 projects and fixing mxmlc

Not many people actually know that you can use MXML in pure AS3 projects. Here’s an example.

Create a new AS3 project, create a new file in package cp. Call it App.mxml. Flex Builder will not allow you to create an MXML component in a pure AS3 project, so you have to do it manually. Here’s my App.mxml.

<?xml version="1.0" encoding="utf-8"?>
<cp:Component xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:cp="cp.*" >
    <cp:Component var1="123"/>
    <cp:Component var1="124111"/>
    <cp:Component />
</cp:Component>

Notice that I’m using my own namespace and no flex components. Now define Component class in cp/Component.as.

package cp {
import flash.display.Sprite;

[DefaultProperty( "children" )]
public class Component extends Sprite {
    public function Component() {
        super();
    }

    private var _children:Array;
    public function get children():Array {
        return this._children;
    }
    public function set children(value:Array):void {
        this._children = value;
        trace( value );
    }

    public var var1:String;
}
}

In main project file I put:

package {
import cp.App;
import flash.display.Sprite;

public class mxml_test extends Sprite {
    public function mxml_test()
    {
        this.addChild( new App() );
    }
}
}

To compile it you need to have framework.swc in library path though. And [DefaultProperty( "children" )] doesn’t work neither in 3.4 SDK nor in 4.0 for some reason. People say it should work in 4.0 but it doesn’t.

That’s weird that Flex SDK 3.4 and Flex SDK 4.0 produce different code from MXML files. 4.0 adds much more useless Flex stuff to resulting SWF. If you want you can add -keep-generated-actionscript compiler parameter to check converted code. Flex 4.0 adds such functions for every object in original MXML.

private function _App_Component2_i() : cp.Component {
    var temp : cp.Component = new cp.Component();
    temp.var1 = "123";
    _App_Component2 = temp;
    mx.binding.BindingManager.executeBindings(this, "_App_Component2", _App_Component2);
    return temp;
}

I don’t like that executeBindings thing in my code and useless mx.* classes it puts in SWF making it 3.5Kb in size. So I decided to patch Flex SDK since it’s kind of open source. Flex SDK SVN can be found at opensource.adobe.com/svn/opensource/flex/ and it contains everything you should need to rebuild your own version of SDK. These links helped me a lot too, and thanks God I found those Eclipse projects inside after trying to resolve libraries issues for an hour.

There are only 2 places where I found this executeBindings stuff, both classes are in flex2.compiler.mxml.gen package. I commented this code and compiled mxmlc.jar. I’ve been doing it all evening but couldn’t get rid of it. I can’t get why. I am totally sure that new mxmlc.jar is used but this stupid string is there anyway.

I consider the final result to be a failure but at least I now know that you can patch Flex SDK as you wish. But I didn’t have time to try to understand how the whole compiler code works and where it handles bindings exactly. I didn’t find much on the internet so I guess not many people actually tried to build their own versions of compiler.

Running native processes in AIR2

Here is an example of using new AIR2 feature which allows you to run system native processes from your application. The guy uses a Java tool to grab screen images.

This might not be that exciting, but Java as AIR runs everywhere and this method allows you to basically use Java libraries in your Flash project. I need to parse PDF files for my needs and I am pretty much desperate on this one. But using Java might be a way out. There are plenty of libraries.

Flex UI and some Java logic should be good.

AirORM

There’s not much information on AIRORM library apart from Getting Started tutorial. Here’s the video which doesn’t really says much about it too but may be helpful.

Is it possible to create a perfect tool with AIR?

Since there’s no perfect tool for me I decided to create one myself.

If you want something done do it yourself.

Right now the only platform I can create application for without additional training is Flash/Flex/AIR. AIR looks perfect for this purpose, but I doubt flash can handle some of the features I need. Here’s the list of features from my previous post.

  • Be able to create rich text nodes,
  • Insert images, movies, audio files and PDFs,
  • Have everything searchable,
  • Tag everything,
  • Be able to sort nodes to folders and smart folders,
  • Be able to crosslink files,
  • Add small notes (as clouds) to everything,
  • Annotate PDFs,
  • Have a usable intuitive interface,
  • Run on a mac offline.

AIR can run on Mac, with Flash I can create any interface I need, I can show images, movies and mp3 files, I can edit text in a WYSIWYG mode (though I have yet to find a good one, and not only me), I can store data locally and online with full search index. But there’s huge problem with PDF support. Seriously, Flash PDF support sucks.

The plan.

First, I need to research a lot more about handling the PDF issue. If I fail to find a good solution I should probably stop and spend time learning Objective-C for native OS X programming. Right now there are several possible ways to go:

  1. pdf2swf library. It comes with C source code. The easiest way is to invoke it from command line from AIR application but this is not right. I might be able to modify it a bit and compile to SWC using Alchemy. The problem is that I don’t know C and have never tried to do anything with Alchemy. pdf2swf has some issues too, especially with fonts.
  2. Port a Java PDF library. With Flash 10 it is much easier to port a Java library to AS3, there’s even a special syntax converter and there should be AS3 implementations of core Java classes. This should be much easier than rewriting from scratch. This is what PDFCase has done, but I can’t contact its author. It is a port of PDFBox Java library. I played a bit with it but am not sure still what exactly it parses PDFs to. I am getting a lot of COSObjects and don’t know what they contain and how to work with them. Also, it takes 20 seconds to parse a 60 pages PDF file with several images. So in a port there must be a way to break the whole task into small subtasks not to hang the player. And I still have to understand how PDFBox works to start porting it.
  3. Write my own PDF parser. From what I saw PDF format is complicated. And I couldn’t find a free format spec.

Another question is what to do after I parsed a PDF file to simple instructions. I need to render them with Flash. This might be a problem too, especially with fonts.

Well, if I find a solution to the problem above the rest is pretty straightforward: prototype the interface, use Flex and Swiz to code it, fix bugs.

Afterthoughts.

I think that AIR might be not the tool of choice (see the irony?) for this type of project. I might need to learn Objective-C and code this application as a native OS X app, because there are frameworks to work with PDFs for Objective-C. For example PDFKit and SkimNotes. This might take some time but I am an experienced programmer after all. How Objective-C can be so different from ActionScript? Doubt it.

Process terminated without establishing connection to debugger

I had to fix my old AIR application, so I found the source, downloaded and set up AIR SDK, but when I tried to compile it I got an error saying “Process terminated without establishing connection to debugger…”. Thanks the Internet and blog.empiregpservices.com, where I found out that I should just change runtime version in application config.

<application xmlns="http://ns.adobe.com/air/application/1.1">

change to

<application xmlns="http://ns.adobe.com/air/application/1.5">

And now it works.

Flex on Rails is too fast

Ruby on Rails evolves so fast that at version 2.3.2 all the code from a year 2008 book doesn’t work in April 2009.

Well, Flex + Ruby on Rails is great, the speed with which simple applications are made is astonishing. I’m reading right now Flex on Rails: Building Rich Internet Applications with Adobe Flex 3 and Rails 2 and as I said every once and a while I get stuck into compatibility problem.

Right now the problem is the following — in Flex HTTPService class though it says that method = “GET|POST|PUT|DELETE”, but the actual data is sent with GET or POST (for some reason I’m sure that 90% users don’t even know that PUT and DELETE exist). But in case with RoR they are essential, for example GET accounts/1 returns account information, PUT accounts/1 updates account and DELETE accounts/1 deletes an account. The book says just that and as a workaround it suggests to add ?_method=put to URL. But in 2.3.2 it doesn’t work anymore. Trying to do that we get

ActionController::MethodNotAllowed (Only get, put, and delete requests are allowed.)

Google says that I should to send method=put with request itself. Requests are sent in XML but I can’t have 2 roots in AS3 XML, so <_method>put</_method><data /> doesn’t work. Wrapping the whole construct into another root fails.

After googling a bit more I found out that I must set header HTTP_X_HTTP_METHOD_OVERRIDE = PUT. But it didn’t work. I almost gave up but visited this chinese link where our communist friend solved the problem!. It seems that Rails somehow adds to headers another HTTP_ prefix and doesn’t know what to do with things like HTTP_HTTP_X_HTTP_METHOD_OVERRIDE = PUT.

So, here’s the code which works

<mx:HTTPService id=”accountsUpdate”
url=”{CONTEXT_URL}/accounts/{accountsGrid.selectedItem.id}”
method=”POST” resultFormat=”e4x”  contentType=”application/xml” headers=”{{X_HTTP_METHOD_OVERRIDE: ‘PUT’}}” >
</mx:HTTPService>

I hope that this text helps people trying to learn Ruby on Rails and how it works with Flex.