Flex Builder 3 lives! (Once I solved ‘Flex builder cannot locate the required version of Flash Player. You might need to install Flash Player 9 or reinstall Flex Builder’ error)

26 06 2008

So I just managed to finally install Flex Builder 3 which is quite exciting and may even deserve a whoop :)
Flex Builder 3

It’s been a while since I did a good ‘Hello World’ app so all good. I spent ages meddling about with my Flash Players (I already had the debug versions so I could have FlashTracer installed with Firefox 3) but when I went to run my app I got this error:

“Flex builder cannot locate the required version of Flash Player. You might need to install Flash Player 9 or reinstall Flex Builder” when I tried to run a perfectly acceptable bit of Hello World action:

<mx:application xmlns:mx=“http://www.adobe.com/2006/mxml” layout=“absolute” width=“668″ height=“500″>
<mx:script>
<!–[CDATA[
&nbsp;    import mx.controls.Alert;
&nbsp;  ]]–>
</mx:script>
<mx:button label=“Click Me” click=“Alert.show(’Hello World’);” x=“65″ y=“57″>
</mx:button></mx:application>

Flex builder cannot locate the required version of Flash Player. You might need to install Flash Player 9 or reinstall Flex Builder

It turns out this is because Firefox 3 is not suported by the Flex debugger. This is all documentewd nicely by the nice chaps over at Adobe who are working on it…

http://bugs.adobe.com/jira/browse/FB-13064

There’s a lot of guys on there saying the plugins are at fualt but I removed all of mine (Charles, ColorZilla, Firebug, the lot) restarted and rebooted & it still didn’t work). Only fix I could find is to use IE as the default browser for debugging. To set this up in the Flex GUI go:

Flex>Window>Preferences>General>Web Browser - Use Internal Web browser (Select IE7 )

Obviously using Ie7  is not great but it’s an acceptable workaround for now so thought I’d share. Hope tis useful



Flash 8 Actionscript 2.0 FileReference Upload issues

28 04 2008

I’ve had several problems with this that only affect the Mac version of the Flash Player - so frustrating - the joy of the Flash Platform is supposed to be that you don’t have disparate platforms to test! :( Anyhow if you’re struggling with this…

Add an extra output from the server to trigger onComplete on a Mac as outlined in Abdul Qabiz’s lovely post here:
http://www.abdulqabiz.com/blog/archives/flash_and_actionscript/workaround_file_1.php

Our ASP.NET backend had no trouble with this and even though the onComplete function was not the one throwing the error in my AS - fixing this seemed to have a domino effect of pleasurable error freeness. One point of note; contrary to many posts I have read; this deos not appear to be fixed in Flash Player 9 for Mac so do it anyway (can’t hurt)

Also maybe try:

- Making sure the FileReference Object never drops out of scope/gets removed too early

- Making sure you have a handler for onCancel (good for debugging)

- Using Delegate.create to specify the instance to handle:

this.referenceListener.onSelect = Delegate.create(this, refOnSelect);

Also be aware that you basically can’t send data back with the onComplete event:

http://www.mehtanirav.com/2006/04/29/filereference-on-mac-type-is-not-available/#comment-1252

We created a getUploadStatus Web Service that we called aftewards with the same UID we’d posted alomg with the upload to get around this.

P.S There is a FileReference.onUploadCompleteData event but it only works in Flash 9.0.28 and up…



Dalston Oxfam weekly tape rips

15 04 2008

Totally off technological topic but found an excellent blog of a guy who digitizes obscure cassettes from Dalston Oxfam…

Oxfam Tunes

Good work mate, that’s ace :)



Copy to clipboard from Flash (a lesson)

14 04 2008

You may well have appeared at my humble blog hunting for a method of copying data to the clipboard directly from Flash as I have had one of these posted for a while. The method I wrote uses Actionscript to call a JavaScript that writes the content you wish to copy into an HTML text input field in a hidden div via the DOM model and then uses JavaScript to copy it to the System clip. I have been using this method on production sites for ~6 months and it works great but as it turns is totally unnecessary ;) The following barely documented function could have saved me (and you) the whole run around…

this.createTextField(“in_txt”, this.getNextHighestDepth(), 10, 10, 160, 120);
in_txt.text = “lorum ipsum…”;
System.setClipboard(in_txt.text);

I guess sometimes as a Developer you just have to accept that you did things in the wrong way (although in my defence it works) but rather than hush it up I figured this is a lesson learned that I may as well share ;)

Who knows, someone may find my massively over the top JS Dom Model access version useful for something one day in circumstances where JS can do something Flash can’t?…



Firefix “Transferring data from www.somesite.com”

9 04 2008

Annoyed by the Firefox loading bar message “Transferring data from www.somesite.com” appearing in your flash sites when you know you’re not in the process of transferring data?

Loading from domain screenshot

Me too - Make sure you are not using null references to clear Levels/MovieClips like this…

loadMovie(null);

and instead use a swf you’ve published with nothing in so that the HTTP request returns a 200 like so…

var assetNULL = “http://www.robmccardle.com/glue/bman/v6/null.swf”;
loadMovie(_global.assetNULL);

as it’s HTTP requests from within the Flash plug in that do not resolve which cause this to happen ;)



Script Generate on Stage Filters with JSFL

3 04 2008

Found a great JSFL tool to automatically convert any Fireworks style filters applied within Flash to AS… http://durej.com/?p=29

Script Generated Filters

Could be very useful so thought I’d share. Was originally looking for 9-slice scaling stuff and found this excellent resource page with a nice way of scaling PNG’s to 9 slice for buttons/UI elements. The AS2 version is at http://durej.com/?p=59

The AS3 one can be found with our friends over at Byte Array http://www.bytearray.org/?p=118



QR code battles and R&D

12 03 2008

Inspired by this QR code mobile phone battle event in the US  http://www.qrcode.es/?p=209&&language=en I had a look into these matters and found a wonderful QRcode generator over at http://qrcode.kaywa.com/ I thought I’d share.

QR code

Blending of the virtual and physical worlds in web applications being the fun it is I will be posting more on such matters soon but am flat out busy behind the scenes on a related project I can’t talk about yet ;)  More info soon



Cool IKEA Flash Video site

21 01 2008

This and the HBO Voyeur thing are very cool uses of Flash Video, I just thought I’d share it here :)

Cheerio



Final Flash Just Giving Parser

12 12 2007

Final Just Giving Example

Right so after several versions of this I finally have a nice class based AS2 version that’s optimised for performance and grabs the full data set. Thanks to all the team at Glue who worked on our Christmas card that inspired this research and also to Rich at Just Giving for his invaluable assistance and for amending their crossdomain.xml file to allow us Flash Devs access to their lovely RSS feeds:

FLA & com folder for download:

Download FLA

class com.glue.xmas.ui.JustGiving extends MovieClip {

        // Class assets
        private var serverStringPath:String = “http://www.justgiving.com/rss/getfundraisingpage.asp?eventgivinggroupid=”;
        private var jgGroupID:String;
        private var xmlIn:XML;
        private var xmlOut:XML;
        private var updateJustGivingObj:Object;
        private var updateJustGivingInterval;
        private var pollSeconds:Number;
        // On stage asset declarations
        private var justGiving_mc:MovieClip;
        private var target_txt:TextField;
        private var total_txt:TextField;
        private var online_txt:TextField;
        private var offline_txt:TextField;
        private var giftaid_txt:TextField;
        // Temporary conversion assets
        private var rcArr:Array;
        private var rcStr:String;
        private var t_arr:Array;
        private var t_arr2:Array;
        private var t_pounds:Number;
        private var t_pence:Number;
        private var t_total:Number;
        private var dStr_init:String;
        private var dStr_arr:Array;
        private var dStr_arr2:Array;;
        private var dStr_arr3:Array;
        // Core Variable - with Public Getter/Setters
        private var currentTarget:Number;
        private var currentTotal:Number;
        private var currentOnline:Number;
        private var currentOffline:Number;
        private var currentGiftAid:Number;

       
        function JustGiving(){
                // Poll secs & Just Giving Group ID
                init(10, “963699″);
        }

        private function init(secs:Number, groupID:String):Void{
                pollSeconds = secs;
                jgGroupID = groupID;
                justGiving_mc = this;
                setRepeat(pollSeconds, justGiving_mc, true);
                hide();
        }
       
        //////////////////////////////////////////////////////////////////
        // Hide & Show - Getters and Setters                            //
        //////////////////////////////////////////////////////////////////
       
        private function show():Void {
                justGiving_mc._visible = true;
        }
        private function hide():Void {
                justGiving_mc._visible = false;
        }

        public function set target(newTarget:Number):Void {
                currentTarget = newTarget;
        }
        public function get target():Number {
                return currentTarget;
        }
        public function set total(newTotal:Number):Void {
                currentTotal = newTotal;
        }
        public function get total():Number {
                return currentTotal;
        }
        public function set online(newOnline:Number):Void {
                currentOnline = newOnline;
        }
        public function get online():Number {
                return currentOnline;
        }
        public function set offline(newOffline:Number):Void {
                currentOffline = newOffline;
        }
        public function get offline():Number {
                return currentOffline;
        }
        public function set giftaid(newGiftAid:Number):Void {
                currentGiftAid = newGiftAid;
        }
        public function get giftaid():Number {
                return currentGiftAid;
        }
       
       
        //////////////////////////////////////////////////////////////////////////////////
        // Setup Interval Set and Clear to control update period of live RSS data              //
        //                                                                                                     //
        // Seconds to leave between updates                                                            //
        // Optional boolean - whether to execute instantly as well as on interval              //
        //////////////////////////////////////////////////////////////////////////////////
       
        private function setRepeat(repeatTime:Number, mcScope:MovieClip, alsoCallOnInit:Boolean):Void {
                updateJustGivingObj = new Object();
                updateJustGivingObj.updateFromRSS = function():Void {
                        //On Interval - Parse RSS
                        trace(“Requesting Fresh RSS Data…”);
                        mcScope.parseJGRSS(mcScope.serverStringPath, mcScope);
                }
                updateJustGivingInterval = setInterval(updateJustGivingObj, “updateFromRSS”, repeatTime*1000);
                // Optional Instant Execute
                if(alsoCallOnInit == true){
                        updateJustGivingObj.updateFromRSS();
                }
        }
       
        private function clearRepeat():Void {
                clearInterval(updateJustGivingInterval);
        }

        private function onJGFeedParse():Void {
                target_txt.text = “”+target;
                total_txt.text = “”+total;
                online_txt.text = “”+online;
                offline_txt.text = “”+offline;
                giftaid_txt.text = “”+giftaid;
                show();
        }

        //////////////////////////////////////////////////////////////////////////////////
        // Main Parsing function and 2 String & Datatype Manipulation functions used by //
        // removeCommas()                                                                                                                //
        // jgFeedStrToNum()                                                                                //
        // parseJGRSS()                 //
        //////////////////////////////////////////////////////////////////////////////////

        private function removeCommas(args:String):String {
                trace(“Removing Comma’s from tridecimal string “+args);
                // Split the string into tridecimal strings and reconcatenate without the commas
                rcArr = args.split(‘,’);
                var rcStr:String = “”;
                for (var i=0; i<rcArr.length; i++) {
                        rcStr += rcArr[i];
                }
                return rcStr;
        }
       
        private function jgFeedStrToNum(args:String):Number {
               
                // Remove any commas as Just Giving add them at triddecimals e.g "£1,056,234"
                if (args.indexOf(‘,’) != -1) {
                        args = removeCommas(args);
                }
                // Split Donations string into Pounds/Pence - (or Dollars/Cents)
                t_arr = args.split(‘.’);
                // Remove any trailing space from after the Pence/Cents string
                t_arr2 = t_arr[1].split(‘ ‘);
                var t_pounds:Number = new Number(t_arr[0]);
                var t_pence:Number = new Number(t_arr2[0]);
                //trace("Pounds "+t_pounds+" Pence "+t_pence+" Pence in Pounds "+(t_pence/100));
                var t_total:Number = t_pounds+(t_pence/100);

                return t_total;
        }

        private function parseJGRSS(jgRSSUrl:String, mcScope:MovieClip) {
                var xmlIn:XML = new XML();
                var xmlOut:XML = new XML();
                xmlIn.ignoreWhite = true;
               
                xmlIn.onLoad = function(success) {
                        if (success) {
                                //////////////////////////////////////////////////////////////////////////////////////////////
                                // PROCESS THE "Item Description" NODE TO GET ALL THE FINANCE TOTALS                        //
                                //////////////////////////////////////////////////////////////////////////////////////////////

                                trace(“Loaded Feed & Parsing RSS…”);
                               
                                var dStr_init:String = this.firstChild.childNodes[0].childNodes[6].childNodes[2].childNodes[0].nodeValue;

                                // Split XML node string by html list end symbol
                                dStr_arr = dStr_init.split(‘</li>’);

                                // Get Fundraising Page Target :
                                dStr_arr2 = dStr_arr[0].split(‘;’);
                                currentTarget = mcScope.jgFeedStrToNum(dStr_arr2[1]);
                                //trace("currentTarget = "+currentTarget);
                                //mcScope.target_txt.text = currentTarget;
                                mcScope.target = currentTarget;
                                                       
                                // Get Total donations to date :
                                dStr_arr2 = dStr_arr[1].split(‘;’);
                                currentTotal = mcScope.jgFeedStrToNum(dStr_arr2[1]);
                                //trace("currentTotal = "+currentTotal);
                                //mcScope.total_txt.text = currentTotal;
                                mcScope.total = currentTotal;
                       
                                // Get Online donations to date :
                                dStr_arr2 = dStr_arr[2].split(‘;’);
                                currentOnline = mcScope.jgFeedStrToNum(dStr_arr2[1]);
                                //trace("currentOnline = "+currentOnline);
                                //mcScope.online_txt.text = currentOnline;
                                mcScope.online = currentOnline;
                               
                                // Get Amount raised offline :
                                dStr_arr2 = dStr_arr[3].split(‘;’);
                                currentOffline = mcScope.jgFeedStrToNum(dStr_arr2[1]);
                                //trace("currentOffline = "+currentOffline);
                                //mcScope.offline_txt.text = currentOffline;
                                mcScope.offline = currentOffline;
                               
                                // Get The UK Gift Aid Reclaimed :
                                dStr_arr2 = dStr_arr[4].split(‘;’);
                                dStr_arr3 = dStr_arr2[1].split(‘</strong>’);
                                currentGiftAid = mcScope.jgFeedStrToNum(dStr_arr3[0]);
                                //trace("currentGiftAid = "+currentGiftAid);
                                //mcScope.giftaid_txt.text = currentGiftAid;
                                mcScope.giftaid = currentGiftAid;
                               
                                mcScope.onJGFeedParse();
                               

                        } else {
                                trace(“RSS Load Failed”);
                        }
                };
                xmlOut.sendAndLoad(jgRSSUrl+jgGroupID, xmlIn);
        }
}



Flash justgiving.com RSS Parse v2

10 12 2007

BananasUpdated the Flash Just Giving method to use XML.sendAndLoad instead of LoadVars and I’ve also included the Pence/Cents calculations if you need to do Maths on the returned value. You should be able to work out from this whatever properties you need from the RSSXML: all my source is below:

// Just Giving RSSXML Parsing V2
var xmlIn:XML = new XML();
var xmlOut:XML = new XML();
xmlIn.ignoreWhite = true;
xmlIn.onLoad = function(success) {
if (success) {

// HERES ALL THE PROPERTIES OF THE RSSXML
/*
trace("Title "+this.firstChild.childNodes[0].childNodes[0].childNodes[0]);
trace("Link "+this.firstChild.childNodes[0].childNodes[1].childNodes[0]);
trace("Description "+this.firstChild.childNodes[0].childNodes[2].childNodes[0]);
trace("Language "+this.firstChild.childNodes[0].childNodes[3].childNodes[0]);
trace("Last Build Date "+this.firstChild.childNodes[0].childNodes[4].childNodes[0]);
trace("TTL "+this.firstChild.childNodes[0].childNodes[5].childNodes[0]);
trace("Item Title "+this.firstChild.childNodes[0].childNodes[6].childNodes[0].childNodes[0]);
trace("Item Link "+this.firstChild.childNodes[0].childNodes[6].childNodes[1].childNodes[0]);
trace("Item Description "+this.firstChild.childNodes[0].childNodes[6].childNodes[2].childNodes[0]);
trace("Item Publish Date "+this.firstChild.childNodes[0].childNodes[6].childNodes[3].childNodes[0]);
*/

// HERES HOW TO PROCESS THE <item> TO GET THE CURENT DONATIONS TOTAL</item>

var donationStr:String = this.firstChild.childNodes[0].childNodes[6].childNodes[0].childNodes[0].nodeValue;
//testing only - donationStr = "So far this page has raised £980.07 "

// Split XML node string by pound sign (change to dollars $ if your currency is US)
arr = donationStr.split(‘£’);

//At this point - if all you need is a string just use this..
trace(“Donations as a String = “+“£”+arr[1]);
// However if you want a Number you can do Maths on you’ll have to do a touch more…

// Split Donations string into Pounds/Pence - (or Dollars/Cents)
arr2 = arr[1].split(‘.’);
// Remove any trailing space from after the Pence/Cents string
arr3 = arr2[1].split(‘ ‘);

var tdPounds:Number = new Number(arr2[0]);
var tdPence:Number = new Number(arr3[0]);
//trace("Pounds " + tdPounds + " Pence "+tdPence + " Pence in Pounds "+(tdPence/100));
var totalDonations:Number = tdPounds + (tdPence/100);

trace(“Donations as a Number = “ + totalDonations);

} else {
trace(“RSS Load Failed”);
}
};
// http://www.justgiving.com/gorillarob
//xmlOut.sendAndLoad("http://www.justgiving.com/rss/getfundraisingpage.asp?eventgivinggroupid=499910",xmlIn);
// http://www.justgiving.com/gluexmas
xmlOut.sendAndLoad(“http://www.justgiving.com/rss/getfundraisingpage.asp?eventgivinggroupid=963699″,xmlIn);

Example FLA for download:
Download FLA