Where I've Been

english mobile

You've probably noticed that I haven't posted much lately. This is because in January, I was hired to do contract work in ASP Classic and SQL Server for a company called voip.com. While working for them, I've done a couple of Flash projects, but no Flex so far. They also keep me hopping pretty well, so I haven't had as much time for blogging as I'd like.

I also recently signed up to do a weekly blog for InsideRIA, which isn't so specifically focused on Flex as this blog is, so it will allow me to talk about the work that I am doing. Check out my first post, Demystifying Web Services.

New Adobe User Group

english mobile

A little known fact is that I met my husband, Steve Howard on the old macromedia user forums. At one point, he and I were both members of Team Macromedia, then we made the transition together to being Adobe Community Experts. Adobe and I had some "differences of opinion," so I am no longer a Community Expert. However, we both still have a close and friendly relationship with Adobe.

He applied late last year for a Gulf Coast Adobe User Group, and this was approved. The user group site is now up and running. So, if you're using Adobe products on the central Gulf Coast, please join the group. We already have a full boxed copy of Flex for a giveaway at the first meeting, and we may collect even more swag in the meantime. So, y'all come by. We'd love to see

Example of casting contents of swfLoader to an interface

english mobile

Last weekend, someone asked for ane example of being able to load a swf generated from a Flex Application that implements an interface and being able to load a Flash swf that implements the same interface. Once the swf's are loaded, the poster wanted to be able to cast them to the interface and then use the interface to call methods on the loaded swf.

So, I've posted an example of casting swfLoader content to an interface.



I chose to go pretty generic with this example, so the interface just enables you to make the component "blush" and stop blushing. However, this could have a lot of uses, for instance, you could write an interface that allows you to stop all animation within a swf.

Lazy Loading Tree example file posted

english mobile

A lot of people on the flexcoders yahoo list have asked about creating a tree that uses a custom DataDescriptor to allow lazy loading of the data. In other words, it gets the first level of data when the application loads, but does not call for the children of the branches until each node is open. I had a bit of down time this week, so I thought I'd put one together.

This example actually has two ways to lazy load. The first is the obvious one using a custom DataDescriptor that is designed to work with any class that is written to the LazyLoading Interface. The major things it does are


  1. Tell the tree that the branch "intends" to have children even when no children have been loaded.

  2. When a branch is loaded, it tells the LazyLoading to load its children.


This could be slicker, in that I could have extended the Tree to listen for the load to finish, but I chose not to do that.

The second way that the lazy loading can be done is to not use the DefaultDataDescriptor at all, but to instead let the instances of Classification load themselves. This code is in place in the hasChildren setter--you'd just need to uncomment it.

This example is unusual in that it not only uses RemoteObject to retrieve the data, it contains the php files and instructions to recreate the mySQL database, so even if you're mainly looking for an AMFPHP example, you might find it helpful.

The bad part about about this example is that I can't post the working example due to reasons I've already blogged about, so you'll just have to look at this pretty picture and take it on faith that if you follow the instructions below that you've got a really good shot at producing a working lazy loading tree application. (As of 1-14-09, you can click this image to see the working example with View Source enabled. See note at end of post.)


  • First, install AMFPHP to your server. I'm going to assume in these steps that you did it to the "flashservices" directory referred to in the installation instructions. I'd suggest that you test the service browser at this point to identify any showstoppers before you get too far.
  • Next, download the flex project zip file and import it to your Flex builder workspace.
  • Download the rtf translation of the mySQL database table export. This is simply the ".sql" file created from the table export with the extension changed to rtf and some formatting added to make your life easier.
  • Download the zip with the php services files. Extract them and place them in the flashservices/services directory. If you didn't install AMFPHP to the flashservices directory, adjust accordingly.
  • Create a new mySQL database called 'RemoteServiceTest'.
  • Open the classification.rtf file you downloaded earlier.
  • Log into phpAdmin or whatever you're using to administer your mySQL databases. Select your new database, and go to the "SQL" panel. In the classification.rtf file, select all of the text that is bold and red and copy it. Paste it into the sql window and run the query. Repeat with the blue, bold text (but only once with each block of text). I got an error with this one about a duplicate key, but it all seemed to come in just fine.
  • Adjust your project properties so that your debug and release builds are exported to the right location relative to the flashservices directory. Alternatively, adjust the setChannels() function in the ClassificationGetter to point to where your service actually is.
  • Enjoy!

Updated 1-14-09:

Reader David Becarra in Mexico donated a subdomain running PHP 5 so that I could show a running example of this. I don't think that he's accepting new hosting subscribers at the moment, but his website is http://www.misitioweb.net/. BIG THANK YOU, David!!

Before you start with AMFPHP...

english mobile

Last week, I had some down time, so I decided to create an AMFPHP example and post it to my website. I have a Windows account with my web host, but they do support php, so I figured it would work. I successfully created the example on my local machine, which I will blog about tomorrow, but I won't be posting the working swf, unfortunately.

Let me tell you why, so that if you need to post to a server that someone else controls, you don't go off all half cocked like I did and make an AMFPHP application that you then can't put out on the Internet.

My first step was to try to export my mySQL database and import it to the server's database. Long story short, the versions didn't match, so I had to find a workaround, which I'll be detailing in the next post.

When I tried to test the service browser, it didn't work. I did a web search for the error I was getting, and I only found one useful link, which suggested that the problem could possibly be with permissions on the folder that contains my mySQL databases. So I went back and checked an old app I had written that writes to a different database. That one totally froze on write. The problem was exacerbated because some time between the last time I worked on a PHP project on my site and now, they'd turned off "display errors." This made the whole problem difficult to debug.

I opened a problem ticket with the web host and got a guy who assumed I was a Jenny Graphic Designer (apologies to serious developers with the name Jenny, but I think you know the attitude I mean) who can barely spell PHP, and so I wasted quite a lot of time getting him to pass me to someone who actually understood the phrase "make sure the default Internet User account has read/write/execute priveleges to the folder containing my database." So once that was resolved, AMFPHP still didn't work.

So, I posted to flexcoders and it seems that the latest AMFPHP requires PHP 5.2.3, and my host had stalled out somewhere in 4. Bottom line, I can't post a working example unless my host upgrades, I switch hosting plans/hosts, or I can find a remoting option which will work on PHP 4.

In summary, here are some things you should do before embarking on an AMFPHP project that will be deployed to a commercially hosted site:

  1. At least know if the version of mySQL on your development and production servers are the same and be prepared to work around it if they're not.
  2. Create a test database on your production server and make sure you can run a simple INSERT query into it from a php page to make sure the appropriate permissions are set on the directory with the database.
  3. Make sure that the right version of PHP is running on your server.

Why I love development perspective

english mobile

I have to tell you, I spend a lot of time debugging. So for a long time, I just left Flex Builder in Debugging persoective unless I needed to work in design view for some reason. But then I realized that Development Perspective gave me more vertical space in the code window, and I started switching to it more often. I'll admit, that's not exciting enough to post about.

But once I started working in Development Perspective more often, I started noticing that the Outline pane was much more useful than what I previously thought. Whenever I'd seen the Outline pane presented before, it was just a way to get hold of items in Design view that were underneath other items or otherwise hard to select. But Outline view is an aid I use daily now, because I can see the overall structure of a class at a glance, or click on a method or variable and instantly be taken to where it is defined in the code.

I don't know how I missed the documentation of this wonderful feature.

Implementing IEventDispatcher

english mobile

Recently, I had to have a class that took arguments in its constructor and also was able to dispatch events. Rather than trying to extend EventDispatcher and worry about separating the arguments the rest of the class needed from the ones EventDispatcher needed, I decided to implement IEventDispatcher. Problem was, I hadn't done this in a while, and I couldn't remember the right way to do this and had no idea what project had an example of it. So, I went searching on the web and refreshed my memory that you need to include an EventDispatcher instance in your class and route your IEventDispatcher methods through that object.

I created some boilerplate code that I can just cut and paste to add IEventDispatcher support to a class, and I share it with you now.



//--------------Support for IEventDispatcher--------------//


private var _ed:EventDispatcher;

public
function addEventListener(type:String, listener:Function,
useCapture:Boolean=false, priority:int=0,
useWeakReference:Boolean=false):void
{
_ed.addEventListener(type,
listener, useCapture, priority, useWeakReference);
}
public function
removeEventListener(type:String, listener:Function,
useCapture:Boolean=false):void
{
_ed.removeEventListener(type, listener,
useCapture);
}
public function
dispatchEvent(event:Event):Boolean
{
return
_ed.dispatchEvent(event);
}
public function
hasEventListener(type:String):Boolean
{
return
_ed.hasEventListener(type);
}
public function
willTrigger(type:String):Boolean
{
return _ed.willTrigger(type);
}



Enjoy!

Updated 12/15/08:
Note that you'll need to put an instance of EventDispatcher in _ed in the constructor of the class that's implementing IEventDispatcher:

_ed=new EventDispatcher(this);

Updated 12/21/08:
Josh McDonald posted code that shows how to implement IEventDispatcher with boilerplate that doesn't require adding a line to the constructor.