Monday, November 25, 2013

Debug Flex Application Against Different Server Machine

Once in a while one of my server co-workers will ask me to test something on my current version of our client Flex application.  Generally they are asking me because they will use the same version of the client application as long as possible, which in some cases could be a couple weeks.  They also know that every morning I get a fresh copy of everything and always try to run the "latest greatest".

The other day I received one of these  types of queries, but with a twist; they wanted me to use my client application against their server.  Oddly enough this had never come up before, so I set out to get this working.  Oddly enough it took me a bit of searching before I found the solution, considering the end result was so simple.  Going forward I will refer to my machine as Machine A (client) and my coworkers machine as Machine B (server).  So if you jumped right in and tried to point your client right at Machine B you would get this error,  SecurityError: Error #2123: Security sandbox violation, because Flash is not happy about trying to access a server on a different machine.  However you can set up a cross domain file to allow this type of access.


  1. Create a new xml file named crossdomain.xml on Machine A.
  2. Download my sample cross domain file sample-crossdomain.xml (note these values allow any domain to access your server so you should fine tune it for your case if in a production environment). 
  3. Change the name to crossdomain.xml
  4. Send the crossdomain.xml file to the person using Machine B.
  5. On Machine B place the crossdomain.xml into the ROOT folder of the app server, so you can go to http://MACHINEB/crossdomain.xml and see the file from Machine B. 
  6. Open up the main application mxml file of your Flex application.
  7. Add an initialization event handler to the application if one doesn't already exist.
  8. Add this line to the initialization handler:  Security.loadPolicyFile("http://MachineB/crossdomain.xml");
  9. Finally wherever you have defined the URL for your AMF channel needs to be updated to point to Machine B.
Additional Resources

Friday, November 8, 2013

Flash Builder 4.7 Freezes Opening MXML

Why does Flash Builder 4.7 freeze when I try to open an MXML file?
There is a bug in the Flash Builder compiler when processing MXML components that are nested so that a component has a child that contains a reference to the parent component's type.  Adobe did send me a fix for this issue.
Steps to fix the issue:
  1. Close Flash Builder
  2. In Windows Explorer navigate to the c:/Program Files/Adobe Flash Builder 4.7/eclipse/plugins/com.adobe.flash.compiler_4.7.0.349722/AIRSDK/lib
  3. Copy the compiler.jar file to a directory in case you need to replace it.
  4. Download the patched compiler.jar I received from Adobe to the directory above
  5. Start Flash Builder

Compile Flash Builder Project Against a Different PlayerGlobal

I have always struggled with the limited right click functionality in Flash Player.  There are several Javascript workarounds for intercepting the click before Flash Player receives it, but depending on the wmode this might not work.  Using the out of the box context menu lets you add some basic menu items, but there are limits to the number of menu items and you always get the standard menu items at the bottom of the list.

So when Flash Player 11.2 was announced I was excited to read about the new functionality added for right and middle click events. See Flash Player 11.2 Release Announcement. I updated the Flash Player in my browser to 11.2 and then went to Flash Builder to try out the new right click functionality.  Unfortunately I ran into several problems and only after much trial and error and searching was I able to get it working.  I am using Flash Builder 4.7 with Flex SDK 4.6.23201.

Things I learned

  1. The Flex SDK has a minimum version of player version it will work with defined in the frameworks/flex-config.xml file of the SDK.
  2. The Flex SDK comes with at least one version of playerglobal.swc library which contains the class information for the version of Flash Player. The versions can be found in the frameworks/libs/player directory of the Flex SDK
  3. Each version of playerglobal.swc has a specific swf version that needs to be used when building your Flex swfs.
  4. Flash Builder can compile against any of the player version defined in the frameworks/libs/player directory of the Flex SDK
  5. The swf projects in Flash Builder need an additional compiler argument -swfVersion={XX} in order to compile correctly.

Steps to follow in order to get it working

  1. Get the PlayerGlobal.swc 
    1. Go to Adobe's Archived Flash Player Versions Page 
    2. Find the PlayerGlobal.swc Archives section.
    3. Download the playerglobal.swc library for the version of Flash Player you want to compile against.  
  2. Install the PlayerGlobal into your SDK
    1. In your OS navigate to the frameworks/libs/player directory of the Flex SDK.
    2. Create a new directory with the name set to the version of Flash Player you are trying to compile against.
    3. Copy the downloaded playerglobal.swc file into the new directory.
    4. Rename the file playerglobal.swc.
  3. Update your Flash Builder Project to compile against the new Flash Player version
    1. Open up Flash Builder.
    2. Right click on the project you want compiling against the new version of Flash Player
    3. Select the Properties menu item from the context menu to show the Properties Window
    4. Click on the Flex Compiler item in the list
    5. In the Adobe Flash Player Options box select the Use a Specific Version radio button
    6. Enter in the version of the Flash Player you want to compile against.
    7. Look up the correct SWF version
      1. Go to Chart of Flash Player and SWF Versions. If the version you want to use is not here then you will need to do a web search for it
    8. In the Additional Compiler Arguments enter a new argument -swfVersion={version from above}
    9. Click the OK button to save the changes
    10. Close the project
    11. Reopen the project
    12. Select Project > Clean... from the menu bar and clean the project
At this point you should be all set to use the new Mouse Events.  


Here are some errors I received along the way
Error Message: unable to open 'C:\dev\tools\adobe\sdks\4.6.0.23201\frameworks\libs\player\11.3\playerglobal.swc' Unknown Flex problem
Reason: The Flex SDK didn't contain the version I entered in the Adobe Flash Player Options specific version field of the project properties.

Error Message: TypeError: Error #2007: Parameter type must be non-null.
Reason: The swfVersion argument was missing from the additional compiler arguments of the project properties.

UPDATE:
Here are some details on deploying the playerglobal.swc to Maven for use by FlexMojos 4.

Run this command to install it in your local repository
mvn install:install-file -Dfile=playerglobal.swc -DgroupId=com.adobe.flex.framework -DartifactId=playerglobal -Dversion={FLEX_SDK_VERSION} -Dpackaging=swc -Dclassifier={FLASH_PLAYER_VERSION} 

Run this command to deploy it to your repository manager
mvn deploy:deploy-file -Durl={repositoryURL} -DrepositoryId={repositoryID} -Dfile=playerglobal.swc -DgroupId=com.adobe.flex.framework -DartifactId=playerglobal -Dversion={FLEX_SDK_VERSION} -Dpackaging=swc -Dclassifier={FLASH_PLAYER_VERSION}

Friday, September 6, 2013

Passing Extra Data to the Server in Flex Login Message

I was tasked with trying to send extra information, the browser's locale to be more specific, to the server during the authentication process of my Flex application.  I am using Granite Data Services for handling remote calls to the web server.

The code to perform the login on the ChannelSet did look like this:
var token:AsyncToken = RemoteObject(service).channelSet.login(user,pwd);
token.addResponder(responder);

The above code will get the ChannelSet from the RemoteObject and calls the login() function on it to retrieve an AsyncToken.  A responder is then added to the token and it is then sent off to the server.

Usually when making calls to the server, outside of login, we just make a call on the RemoteObject for a method defined by the server. If I was dealing with one of those calls I could add a new argument for the locale and be on my way, but for authentication the login function of ChannelSet is set in stone.

So after a little debugging and toying around I found that the AsyncToken contains an IMessage property, which has a headers property.  On the server side I have a class which extends org.granite.spring.security.SpringSecurity3Service that handles the authentication.  From inside that class I can get an instance of the HttpGraniteContext . I found the IMessage object from the AsyncToken was available inside the HttpGraniteContext .  Since it is available on the server sign I simply needed to add a new property to the headers object.

So now the code looks like this:
var token:AsyncToken = RemoteObject(service).channelSet.login(user,pwd);
// Adding the locale to the CommandMessage's headers map.
token.message.headers["myLocaleKey"] = locale;
token.addResponder(responder);

On the server side the new header can be accessed like this:
HttpGraniteContext graniteContext = (HttpGraniteContext)GraniteContext.getCurrentInstance();
graniteContext.getAMFContext().getRequest().getHeader("myLocaleKey")

That's it!

Friday, May 3, 2013

iPhone Tip of the Day: Easy Saved Drafts Access

In the Mail app if you tap and hold the "Compose" button with a list of previous drafts will show up. Much easier than navigating to the Drafts folder.

Tuesday, April 30, 2013

iPhone 4S & 5 Tip of the Day: Siri Relationships

Tell Siri your relationship to people to avoid saying their full name. For example, after telling Siri, "Brendan Sands is my brother." I could text him by saying, "Text my brother 'How is Connor today?'"

Thursday, April 25, 2013

iPhone Tip of the Day: Adjust Music Scrubbing Rate

In the Music app, when dragging the scrubber to move to a different part of a song, if you slide your finger down you can adjust the scrubber rate.

Wednesday, April 24, 2013

iPhone Tip of the Day: Safari History

Tapping and holding the back button in Safari will show your history, this will save you from having to press back multiple times.

Monday, April 22, 2013

iPhone Tip of the Day: Screenshot

Take a screenshot by pressing the home and lock buttons at the same time. This is probably something you have done by accident and wondered how it happened and why you have this weird picture in your camera roll.

Thursday, April 18, 2013

iPhone Tip of the Day: Double Space Bar

Double tap the space bar when typing to add a period, space and capitalize the next letter.

Wednesday, April 17, 2013

iPhone Tip of the Day: Number/Symbol Keyboard Shortcut

On the keyboard if you have to type a single character from the "Number/Symbol" keyboard, just tap and hold on the "123" key, with your finger still down drag to the number/symbol you want and let go. The keyboard will then return to the ABC keyboard. #saveatap

Friday, April 12, 2013

iPhone Tip of the Day: Notification Center

iPhone Tip of the Day: Slide down from above the time at the top of the screen to reveal Notification center. You can see Weather, Stocks, Notifications and post to social media.

Thursday, April 11, 2013

Wednesday, April 10, 2013

iPhone Tip of the Day: Swipe to Camera Roll

In the Camera app if you swipe from left to right, it will bring you to the last photo in your camera roll. Swipe right to left to get back to the camera.

iPhone Tip of the Day: Volume Button Shutter

In the camera app the Volume Up(+) button can also be used to take a photo. Makes self portraits easier from the front facing camera.

iPhone Tip of the Day: Lock Camera

If you launch the camera from the lock screen, you can lock it again by swiping downward from the top of the screen.

Thursday, January 31, 2013

ActionScript Dollar Sign Character in Variables

I recently came across some 3rd party ActionScript code that used the dollar sign ($) in argument variable names.  At first I thought it was a way of using the same variable name as a classes member variable, because the functions argument name appeared to be the same as one of the member variable names.  It turns out the $ just like the _ is one of the only valid non alpha-numeric characters that can be used for variable names.  So the $ wasn't some special modifier, but instead it was just a different way of naming the variable.  An important thing to note is that ECMA recommends the dollar sign only be used for generated code.