Monday, April 13, 2009

Flash CS3, ActionScript 3.0, JSON keep it simple tutorial

Here's what I recently found to work if you want Flash CS3 to read JSON structured data via ActionScript 3 and the Adobe core library:

1. Create the JSON file. My file is called numbers.php which looks like this and the JSON is echoed via PHP:

[ {"name":"Jaylo", "number":"3243251"}, {"name":"Jenny", "number":"8675309"}]

Note: having var People= {} ; People.numbers = [The above JSON data] seems to break Adobe's decode static function so JSON needs to be in pure form.

2. Download the adobe core library. After download, the files you should be concerned with are located in src/com/adobe/serialization/json.

3. Create a new layer in your flash file, label it "actionscript", select frame 1 on that layer, then hit F9 (Windows)/Option + F9 (Mac) to open the Actions window. Here's what the ActionScript 3.0 should look like inside of the Actions window:

/*Import all the classes you need (you can skip the next three imports if your ActionScript is NOT in an external package but in frame 1 of the main flash file. */

import flash.net.URLRequest ;
import flash.net.URLLoader ;
import flash.events.* ;

import com.adobe.serialization.json.JSON /*Path to the JSON class (in JSON.as). NOTE: make sure to keep all the classes in the original json folder together and that at the very beginning of each class file in the json folder, the file path after the word 'package' accurately reflects that path to the FOLDER in which all the classes are located. E.g. package com.adobe.serialization.json*/

/*Create the objects you need*/

var loader:URLLoader = new URLLoader() ;
var request:URLRequest = new URLRequest() ;

/*Connect to and load the data within the numbers.php file*/

request.url = "http://path_to_file.com/numbers.js" ;
loader.load(request) ;

/*Attach a listener to the loader object that will point to and fire a decodeJSON function upon completion of the file load.*/
loader.addEventListener(Event.COMPLETE, decodeJSON) ;

/*decodeJSON function will decode (convert the data into a Flash object) and present the data. Function will not return anything (:void).*/

function decodeJSON(event:Event):void {

var loader:URLLoader = URLLoader(event.target) ;
var People:Array = JSON.decode(loader.data) ;

/*Trace the JSON data, remember it used to look like this ([ {"name":"Jaylo", "number":"3243251"}, {"name":"Jenny", "number":"8675309"}])*/

trace(People[0].name) ; //Jaylo
trace(People[0].number) ; //3243251
trace(People[1].name) ; //Jenny
trace(People[1].number) ; //8675309

/*Or, you can also use a loop...*/

for (var key:Object in People) {
trace(People[key].name) ;
trace(People[key].number) ;
}

}

There you have it, a way to connect to a JSON file via Flash. Happy programming.

Download Example Package

14 comments:

storypixel said...

Thanks for posting this, it was helpful. I admire you for taking time to dispense useful advice.

Also just a personal anecdote of how I used your code. My JSON had a slightly strange structure so I simply added a line to suit my own needs...

> var loader:URLLoader = URLLoader(event.target);
> var jsonresponse:Object = JSON.decode(loader.data);
> productJsonData = jsonresponse[0].result;

The client's JSON data was wrapped/buried in an array. Just demoing for anyone in a similar boat JSON-wise.

Bob said...

Hi!
I seem to be stuck on this one.

This is my JSON:

[{"indicator":"U","totalVolume":"98094596.64","percChangeClose":"21974339.87","securitySymbol":"ybgm","lastTradedPrice":"88735912.73","id":1,"securityAlias":"Ldnzcykqxicadaq"},{"indicator":"D","totalVolume":"889765.12","percChangeClose":"824716.54","securitySymbol":"ALL","lastTradedPrice":"","id":2,"securityAlias":"All Shares"},{"indicator":"D","totalVolume":"555899.03","percChangeClose":"865866.43","securitySymbol":"PSE","lastTradedPrice":"","id":3,"securityAlias":"iPSE Composite Index"},{"indicator":"U","totalVolume":"464921.58","percChangeClose":"769307.04","securitySymbol":"FIN","lastTradedPrice":"","id":4,"securityAlias":"Financials"},{"indicator":"U","totalVolume":"852156.49","percChangeClose":"327567.25","securitySymbol":"IND","lastTradedPrice":"","id":5,"securityAlias":"Industrial"},{"indicator":"U","totalVolume":"417316.06","percChangeClose":"756512.55","securitySymbol":"HDG","lastTradedPrice":"","id":6,"securityAlias":"Holding Firms"},{"indicator":"U","totalVolume":"366512.40","percChangeClose":"796385.30","securitySymbol":"MO","lastTradedPrice":"","id":7,"securityAlias":"Mining and Oil"},{"indicator":"D","totalVolume":"878402.06","percChangeClose":"620225.12","securitySymbol":"PRO","lastTradedPrice":"","id":8,"securityAlias":"Property Index"},{"indicator":"D","totalVolume":"697662.88","percChangeClose":"438808.16","securitySymbol":"SVC","lastTradedPrice":"","id":9,"securityAlias":"Services Index"}]

and when I execute these lines of code:
var loader:URLLoader = URLLoader(event.target);
var tickerData:Array = JSON.decode(loader.data);
trace("Ticker Data: " + tickerData.toString());

I am getting
Ticker Data : [object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]

which is not what i expected...

Thanks,
Bob

Bob said...

By the way here's the full source: http://pastebin.com/m5dfe754d

and the json: http://pastebin.com/m3937d99a

Thanks again!

DesignerOfArt said...

How do I get the data to output the SWF. I see the data in the Output pane in Flash but not as text in the SWF. I am a bit new at the data stuff. How would I go about getting that info to show up in the SWF for people to view it.

DesignerOfArt said...

Do I need a dynamic text box or boxes to show separate data. We are setting up a weather data pull and the JSON works but getting the data to show up is the issue I am having. The data is in the Output pane but not physically showing up on the SWF.
Example
Temperature: JSON data here
Wind: JSON data here

How in Flash would I make the JSON data show up. Is it a Dynamic text box with an instance name? or is there more AS3 to do. Any help would be greatly appreciated. Thank you.

Andres said...

Wow, I'm new to blogspot, so just realized an email from a reader is actually a comment. The good thing is, I replied to my readers, bad thing is, no one else got to see. That said, here's my last reply @DesignerOfArt:

The output you're seeing is only for the developer since you're
sending it out to the error log via the trace() function. For a text
box, you can create it with something like
var textBx:TextBox = new TextBox();

Then add data to it:
textBx.value = [your data here];

Then add the textbox to your stage. If I remember correctly, it's
appendChild(textBx) and Flash already assumes the parent object is
your stage (the main SWF canvas). In other words, you don't have to
do something like stage.appendChild(textBx).

Double check those semantics (I'm currently working in JS right now so
my Flash memory is kinda rusty) through Google ("Flash how to create a
text box", "how to add a text box to stage") and I'll try to perfect
it more when I get some time. I even have some examples lieing around,
but this should provide you with a strong lead.

Oh, also open up the Flash component window/library, and if you right click it, then go to properties, you'll see its class name (textBx:className = ..... Again, this is all from memory...

Dilip said...
This post has been removed by the author.
Dilip said...

This is my json data

{"_id":"d222b341930664d908b8508906c95d4a","_rev":"4-1126643241","gameid":1}




and i am using the json decoder as follows


var loader:URLLoader = URLLoader(event.target)
;

var jsonarray:Array=(JSON.decode(loader.data) as Array);




I am getting the following error

TypeError: Error #1009: Cannot access a property or method of a null object reference.
at Scoreboard/handleXMLResponse()
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at flash.net::URLLoader/onComplete()

Jake said...

Hey great code, works perfectly - if my JSON is in the same domain as my swf.

Any suggestions on how to handle when my JSON lives on another Domain? I'm making banner ads and don't want to have to constantly update a crossdomain.xml file on the other server with locations of all the different ads..

Bill said...

Hi Jake,

You have 2 options:

1. Have every server that hosts the flash create a proxy to your web service

2. In your crossdomain.xml file, you can use a wildcard (*) in the allow-access-from node

Using a wildcard opens you up to to security issues though, so make sure you understand the implecations and have taken appropriate steps to secure your server.

Option 1 is more secure, option 2 easier to implement

Vera said...

Dear Bob,

the advantage JSON has over XML is that the type of data you are receaving is defined when you parse it. There is no point in adding the toString() part. Maybe that's your problem

Fahim Akhter said...

Hey, sadly my json is passed at function something(jsonobject){

..............
}

the rest I have to do in the something function. but everything stops at the function name

Ankit Patni said...

Hi,

I want vice versa for Json.

Let say i have something in jSon file which is called in one text box. how to do vice versa through flash text box to Json file?

I search lot of things but non of that meet to my target.


Thanky in advance

leeboone.com said...

@storypixel
Thanks!

Post a Comment