Advertisement

Create a Facebook Graph API App in Flash: Setup and Design

by

In this series of tutorials, I will teach you how to create a complete Facebook Application from scratch, using Flash and Actionscript 3 SDK for Facebook Platform API. While not a "real" app, it will tackle the use of the Graph API with AS3. We'll create a complete application that can be deployed as a Facebook Application.

Today, Facebook applications are at the top of the development industry. A huge number of development and gaming companies are focusing their products and platforms for smartphones, internet and of course, Facebook. There are even companies that have their sole interest in Facebook apps, and they are really more successful than some financial institutions, like Zynga, which is well known for its huge social games (Mafia Wars, Empires and Allies).


Also Available in This Series:

  1. Create a Facebook Graph API App in Flash: Setup and Design
  2. Create a Facebook Graph API App in Flash: Generating Embed Code
  3. Create a Facebook Graph API App in Flash: Loading Events
  4. Create a Facebook Graph API App in Flash: Displaying Facebook Info

Final Result Preview

This application allows you to select a Facebook album or event list from one of your public pages (not your personal profile) and turn it into a slideshow for your page tab. When the users enter your page, they will see photos from your chosen album, with your photo title and description, or event name, date and invites (for the Event tab).

In future parts of this series, we'll create the actual Flash slider that does just that; meanwhile we'll create the generator for the embed code that will reside at the Facebook application URL.

You'll need to be logged in to Facebook in order to see this demo: https://apps.facebook.com/activetuts_tabmaker/


Step 1: Get the Required Libraries and Dependencies

For this tutorial, create a folder for all the sources and assets of the app. I have called mine "activetuts_tab_maker".

We'll need the Actionscript3 SDK for Facebook Platform, which you can download from http://code.google.com/p/facebook-actionscript-api/.

Download the the as3corelib library available from https://github.com/mikechambers/as3corelib.

Lastly, get the Greensock TweenLite library from http://www.greensock.com/tweenlite/. We'll use this for some light fades and animations.

Extract all the libraries somewhwere temporary and copy the "com" folder from every library into the "activetuts_tab_maker" folder, overwriting the files as neccesary. These are essentially all the sources we'll need. Of course, you should also keep the documentation if you intend to use it, or if you're in a train. Of course you can access it online instead.



Step 2: Creating the Flash File and the Top Bar

Open Flash Pro and create a new FLA with a size of 760x600px and a framerate of 25. Make the background black (#000000). Save it as TabMaker_app.fla.

Let's make the top bar, which will contain the logo for the app and some buttons. Using the Rectangle Tool (R), create a 760x60px rectangle, and give it a gradient from top color #5E5E5E to bottom #3C3C3C, like in the picture:



Step 3: Top Bar and Logo

With the rectangle selected, hit F8 and turn it into a movieclip called top_bar. Tick Export For Actionscript and give it a class name of TopBar. Ignore the warning that a class does not exist with that name. I have placed a logo on the left, as seen in this picture:



Step 4: Creating the Button Style

We'll use a couple of buttons, so we'll create a main button style and then duplicate the button for other uses.

Create a 123x28px rectangle and drag guides in all four sides. We'll use this to create a rounded rectangle in the same spot. Delete the rectangle and using the Rectangle Tool again, enter 30 for corner radius. Then create a rectangle the same size using the guides and you'll have a rounded rectangle for the button.


Select the rounded rectangle and give it a gradient from #484848 to #262626; then, using the Ink Bottle Tool (S), give it a stroke of 3 with the color #404040. You should end up with something like this:



Step 5: Create the Logout Button

Select the rounded rectangle, hit F8 to turn it into a button and enter Logout in the name field. We'll use this button as a logout button.


Double click the newly created button and in the button timeline, create another layer and name it text. In this new layer, create a static TextField with the text "Logout" and the color #BBBBBB. Set the width of the textfield to the width of the button and x and y to 0. Set the text's align property to center. Don't forget to make the label not selectable, so you don't destroy the functionality of the button.



Step 6: Create the Button States

Make different colors and gradients for every state, like in the picture:



Step 7: Create Other Buttons We Need

In the library, select the button, right-click and select Duplicate. Then create duplicate buttons for every button we need and change the textfield label with its correct name, like in the picture:


For the login button, I made a slightly lighter color, added a logo in the text layer and exported it for Actionscript. We'll use this button in the center when the user is not authenticated in Facebook. You'll notice the login button is centered in the stage, so the registration point will be in the top left side as it will be easier to just use addChild() without specifying the x and y. We'll be creating two more buttons with this design, but later.


Step 8: Library Assets

Place the logo and the two buttons in the top_bar movieclip. The top_bar movieclip shoud look like this:


I have also created two buttons: AlbumTab, with the class name "AlbumTabButton" and EventTab, with the class name "EventTabButton".

I used the Vegur font for the title and also added a description field under the title. Be careful to make the hit area big enough for the whole button; I have used a rectangle. Also, don't forget to embed the font, if you need it.


I used the images from the Crystal Project iconset: you can download the folder icon from here and the event icon from here. Inside the button, I have converted the images to a sprite and altered the brightness effect for the different states:


This is how all the interface elements should look:


Step 9: Base Document Class

Let's get started on the development of the app. Create a new folder tabmaker in the source directory of your flash file. We'll put all our classes in our custom package tabmaker

 
package tabmaker 
{ 
 
	import flash.display.*; 
	import flash.events.*; 
	import flash.net.*; 
	import flash.text.*; 
	import flash.external.ExternalInterface; 
	import flash.system.*; 
	import fl.motion.Color; 
 
	import com.greensock.*; 
	import com.greensock.easing.*; 
 
	import com.facebook.graph.Facebook; 
	import com.facebook.graph.data.FacebookSession; 
	import com.facebook.graph.net.FacebookRequest; 
 
 
	public class TabMaker extends Sprite 
	{ 
 
		//App ID 
		private var APP_ID = ''; 
		//Permissions 
		private var PERMS = 'publish_stream, user_photos, manage_pages'; 
		 
		private var logged = false; 
		private var login; 
		private var app; 
		private var top_bar; 
		private var album_button; 
		private var events_button; 
		private var err; 
		private var ct; 
 
 
		public function TabMaker() 
		{ 
			debug('App started.'); 
		} 
 
		public function debug( msg ) 
		{ 
        	trace( msg ); 
			ExternalInterface.call('console.log', msg ); 
		} 
 
	} 
}

Hit Ctrl+F10 to test the movie and you should get "App started" in the output bar. In the debug() function, we're also calling the JavaScript function console.log() which we'll use to see data from Flash when we run in the browser.

Step 10: Facebook Application Creation

Before we get further, we need to make a Facebook application in Facebook. I won't go into detail on creating a Facebook application, there are many resources for that.

What we are interested in is the App ID and App Secret. You should also create an app namespace, as it will make your application URL easier to type in the browser. It's important to set the App Domain to your hosting domain, depending on where you'll host your files.


In the Integration tab, select Website and App on Facebook. Complete the URL with your hosting URL. Facebook has partenered with Heroku so you can host your application on Heroku, but for this simple app it would be overkill to go all the way for the purposes of this tutorial.



Step 11: Create the index.html File and Test the Application

We'll use a template provided in the Actionscript 3 SDK for Facebook's api examples. Copy the
index(dynamic).html file from the Embedding folder to your Flash directory and, in the HTML, modify the src attribute so that it points to your SWF and uses your SWF width and height.


Now, upload both files ( index.html and tabmaker_app.swf ) to your configured hosting and go to http://apps.facebook.com/{your app namespace here} to test your app. You should see the traced message appear in the browser's console. ( I use Chrome's console to see this ).


Step 12: Facebook Initialization

Go back to the source and enter your App ID in the APP_ID variable. We'll need to initialize the Facebook object, which holds all the API functionality:

 
 
	public class TabMaker extends Sprite 
	{ 
 
		//App ID 
		private var APP_ID = '{your app id here}'; 
		//Permissions 
		private var PERMS = 'publish_stream, user_photos, manage_pages'; 
		 
		private var logged = false; 
		private var login; 
		private var app; 
		private var top_bar; 
		private var album_button; 
		private var events_button; 
		private var err; 
		private var ct; 
 
 
		public function TabMaker() 
		{ 
			debug('App started.'); 
           init(); 
			app = null; 
		} 
         
        private function init() 
		{ 
			 
			ct = new Color(); 
			ct.tintColor = 0xCCFF00; 
			ct.tintMultiplier = 0.5; 
 
			Facebook.init( APP_ID, on_init, {scope: PERMS} ); 
		} 
         
        public function on_init( res, fail ){ 
			if( res ){ 
				debug('ok, logged in'); 
			} else { 
				debug('not logged in'); 
			} 
		} 
 
		public function debug( msg ) 
		{ 
        	trace( msg ); 
			ExternalInterface.call('console.log', msg ); 
		} 
 
	} 
}

I have added a function init() which calls the Facebook.init() function. This function checks to see whether there's a logged in user, and gets an access token if so. This function accepts an app id, a callback function and an object with options. I have provided permissions with the scope parameter. I also create a Color object for tinting the buttons later on click.

If you test the movie now, you'll see "ok, logged in" or "not logged in", depending on whether you're logged into facebook or not. Let's create the main functionality next.


Step 13: Login and Logout

Let's continue our intialization with making the login button if the user is not logged in and adding the top bar if he is:

 
       
      private function init() 
      { 
           
          ct = new Color(); 
          ct.tintColor = 0xCCFF00; 
          ct.tintMultiplier = 0.5; 
 
          Facebook.init( APP_ID, on_init, {scope: PERMS} ); 
      } 
       
      public function on_init( res, fail ){ 
        if( res ){ 
            top_bar = new TopBar(); 
            addChild( top_bar ); 
            top_bar.alpha = 0; 
            TweenLite.to( top_bar, 0.6, {alpha:1} ); 
                 
            //setup event handlers 
            top_bar.getChildByName('logout_btn').addEventListener( MouseEvent.CLICK, handle_logout_click ); 
            top_bar.getChildByName('album_btn').addEventListener( MouseEvent.CLICK, run_app ); 
            top_bar.getChildByName('events_btn').addEventListener( MouseEvent.CLICK, run_app ); 
            album_button = new AlbumTabButton(); 
            album_button.name = 'album_btn'; 
            album_button.addEventListener( MouseEvent.CLICK, run_app ); 
            addChild( album_button ); 
            events_button = new EventTabButton(); 
            events_button.name = 'events_btn'; 
            events_button.addEventListener( MouseEvent.CLICK, run_app ); 
            addChild( events_button ); 
           
            hide_login(); 
        } else { 
          	show_login(); 
        } 
      } 
 
      public function debug( msg ) 
      { 
          trace( msg ); 
          ExternalInterface.call('console.log', msg ); 
      }

In the refactored init function, I add the top bar, set its alpha to 0 and then fade it in with TweenLite. I attach click event handlers to logout_btn, album_btn and events_btn, which we'll get into later. I also add the two buttons I created which basically mirror the functionality of the top bar buttons.

You'll notice I give the buttons I create a name property. Because the buttons in the top_bar movie clip have instance names of album_btn and events_btn, I add the same names so inside the run_app() function ( which we will code in a bit ), we can find out which action the user has chosen ( album slideshow or event_slideshow ).


Step 14: show_login() and hide_login()

Let's make the helper functions show_login() and hide_login()

 
private function show_login(){ 
    login = new LoginButton(); 
    addChild( login ); 
    login.addEventListener( MouseEvent.CLICK, handle_login_click ); 
    login.alpha = 0; 
    TweenLite.to( login, 0.6, {alpha: 1} ); 
} 
 
private function hide_login(){ 
    if( login ){ 
        TweenLite.to( login, 0.6, {alpha:0, complete: function(e){ removeChild( login ); } } ); 
    } 
}

In show_login, I create a new LoginButton, add it to the stage and fade it in. In hide_login(), I check that the login variable is defined and fade the button out and remove it from stage after the fade with the use of complete argument in the TweenLite call.


Step 15: handle_login_click() and handle_logout_click()

There are 2 more helper functions which take care of the login and logout button clicks:

 
private function handle_login_click( e ){ 
    Facebook.login( on_init, {scope: PERMS } ); 
} 
 
private function handle_logout_click( e ){ 
    Facebook.logout( on_logout ); 
} 
 
private function on_logout( succ ){ 
    if( top_bar ){ 
        removeChild( top_bar ); 
    } 
    show_login(); 
}

When the login button is clicked ( in case the user is not logged in ), the Facebook.login() function is called. This function is similar to Facebook.init(). In the logout function, I call Facebook.logout(), passing a callback function on_logout(), which removes the top_bar and shows the login button again.


Step 16: Choosing the Right Action in run_app()

In order to test the functionality up to this point, we need to create the run_app() function which gets called when we click any of the action buttons. Let's code it now:

 
private function run_app( e ){ 
    album_button.visible = false; 
    events_button.visible = false; 
     
    if( e.target.name == 'album_btn'){ 
        debug("User has selected an album slideshow"); 
        top_bar.getChildByName('album_btn').transform.colorTransform = ct; 
        top_bar.getChildByName('events_btn').transform.colorTransform = new Color(); 
    } else { 
        debug("User has selected an event slideshow"); 
        top_bar.getChildByName('album_btn').transform.colorTransform = new Color(); 
        top_bar.getChildByName('events_btn').transform.colorTransform = ct; 
    }; 
}

In this function, we get the name of the button that was clicked. Because I named the album_button and events_button the same as the buttons in the top_bar, clicking any of them will trigger either an album action or an event action. I also set the top_bar button's colorTransform object to the color object I defined at the begining, to set the clicked button as "selected". This will function as a cue that will tell the user where he is.

Test the application now and you should be able to log in, log out and select an appropriate action.


Step 17: AlbumMaker and EventMaker Classes

Let's create the two classes that will hold the generation functionality of the app:

 
private function run_app( e ){ 
    album_button.visible = false; 
    events_button.visible = false; 
     
    if( app ){ 
        removeChild( app ); 
        app = null; 
    } 
    if( e.target.name == 'album_btn'){ 
        app = new AlbumMaker( this ); 
        top_bar.getChildByName('album_btn').transform.colorTransform = ct; 
        top_bar.getChildByName('events_btn').transform.colorTransform = new Color(); 
    } else { 
        app = new EventMaker( this ); 
        top_bar.getChildByName('album_btn').transform.colorTransform = new Color(); 
        top_bar.getChildByName('events_btn').transform.colorTransform = ct; 
    }; 
    addChild( app ); 
}

Here is the complete code of the TabMaker class:

 
package tabmaker 
{ 
 
	import flash.display.*; 
	import flash.events.*; 
	import flash.net.*; 
	import flash.text.*; 
	import flash.external.ExternalInterface; 
	import flash.system.*; 
	import fl.motion.Color; 
 
	import com.greensock.*; 
	import com.greensock.easing.*; 
 
	import com.facebook.graph.Facebook; 
	import com.facebook.graph.data.FacebookSession; 
	import com.facebook.graph.net.FacebookRequest; 
 
 
	public class TabMaker extends Sprite 
	{ 
 
		//App ID 
		private var APP_ID = '283591785046507'; 
		//Permissions 
		private var PERMS = 'publish_stream, user_photos, manage_pages'; 
		 
		private var logged = false; 
		private var login; 
		private var app; 
		private var top_bar; 
		private var album_button; 
		private var events_button; 
		private var err; 
		private var ct; 
 
 
		public function TabMaker() 
		{ 
			debug('App started.'); 
			app = null; 
			init(); 
		} 
 
		private function init(){ 
			 
			ct = new Color(); 
			ct.tintColor = 0xCCFF00; 
			ct.tintMultiplier = 0.5; 
 
			Facebook.init( APP_ID, on_init, {scope: PERMS} ); 
		} 
		 
		public function on_init( res, fail ){ 
			if( res ){ 
				debug('ok, logged in'); 
				 
				top_bar = new TopBar(); 
				addChild( top_bar ); 
				top_bar.alpha = 0; 
				TweenLite.to( top_bar, 0.6, {alpha:1} ); 
				 
				//setup event handlers 
				top_bar.getChildByName('logout_btn').addEventListener( MouseEvent.CLICK, handle_logout_click ); 
				top_bar.getChildByName('album_btn').addEventListener( MouseEvent.CLICK, run_app ); 
				top_bar.getChildByName('events_btn').addEventListener( MouseEvent.CLICK, run_app ); 
				album_button = new AlbumTabButton(); 
				album_button.name = 'album_btn'; 
				album_button.addEventListener( MouseEvent.CLICK, run_app ); 
				addChild( album_button ); 
				events_button = new EventTabButton(); 
				events_button.name = 'events_btn'; 
				events_button.addEventListener( MouseEvent.CLICK, run_app ); 
				addChild( events_button ); 
				//hide login button 
				hide_login(); 
			} else { 
				debug('not logged in'); 
				 
				show_login(); 
			} 
		} 
		 
		private function run_app( e ){ 
			//removeChild( album_button ); 
			//removeChild( events_button ); 
			album_button.visible = false; 
			events_button.visible = false; 
			 
			if( app ){ 
				removeChild( app ); 
				app = null; 
			} 
			if( e.target.name == 'album_btn'){ 
				app = new AlbumMaker( this ); 
				top_bar.getChildByName('album_btn').transform.colorTransform = ct; 
				top_bar.getChildByName('events_btn').transform.colorTransform = new Color(); 
			} else { 
				app = new EventMaker( this ); 
				top_bar.getChildByName('album_btn').transform.colorTransform = new Color(); 
				top_bar.getChildByName('events_btn').transform.colorTransform = ct; 
			}; 
			addChild( app ); 
		} 
		 
		 
		 
		private function handle_login_click( e ){ 
			Facebook.login( on_init, {scope: PERMS } ); 
		} 
		 
		private function handle_logout_click( e ){ 
			Facebook.logout( on_logout ); 
		} 
		 
		private function on_logout( succ ){ 
			if( app ){ 
				removeChild( app ); 
				app = null; 
			} 
			if( top_bar ){ 
				removeChild( top_bar ); 
			} 
			show_login(); 
		} 
		 
		private function show_login(){ 
			login = new LoginButton(); 
			addChild( login ); 
			login.addEventListener( MouseEvent.CLICK, handle_login_click ); 
			login.alpha = 0; 
			TweenLite.to( login, 0.6, {alpha: 1} ); 
		} 
		 
		private function hide_login(){ 
			if( login ){ 
				TweenLite.to( login, 0.6, {alpha:0, complete: function(e){ removeChild( login ); } } ); 
			} 
		} 
 
 
		//helper functions 
		public function debug( msg ){ 
			ExternalInterface.call('console.log', msg ); 
		} 
 
	} 
}

Step 18: AlbumMaker Class

In this part, we're going to tackle the begining of the AlbumMaker class, so let's get going! Create two new AS files in the tabmaker folder, called AlbumMaker.as and EventMaker.as and enter the following startup class templates:

 
package tabmaker 
{ 
	import flash.display.*; 
	import flash.events.*; 
	import flash.net.*; 
	import flash.text.*; 
	import flash.external.ExternalInterface; 
	import flash.system.*; 
	import fl.motion.Color; 
 
	import com.greensock.*; 
	import com.greensock.easing.*; 
 
	import com.facebook.graph.Facebook; 
 
 
	public class EventMaker extends Sprite {		 
    	 
         
        public function EventMaker( m ){ 
        	m.debug('EventMaker started.'); 
        }	 
         
         
    }    
}

And the AlbumMaker class:

 
package tabmaker 
{ 
	import flash.display.*; 
	import flash.events.*; 
	import flash.net.*; 
	import flash.text.*; 
	import flash.external.ExternalInterface; 
	import flash.system.*; 
	import fl.motion.Color; 
 
	import com.greensock.*; 
	import com.greensock.easing.*; 
 
	import com.facebook.graph.Facebook; 
 
 
	public class AlbumMaker extends Sprite {		 
    	 
         
        public function AlbumMaker( m ){ 
        	m.debug('AlbumMaker started.'); 
        }	 
         
         
    }    
}

Save your work and test it. You should end up with a message of the instanced class when you select an action. Remember to always save your work, as the code is particularly long.


Step 19: Class Variables

We'll need to define some variables that will hold the various functionalities of this class:

 
public class AlbumMaker extends Sprite {		 
    private var state; 
    private var main; 
    private var heading; 
     
    private var rs; 
    private var page_id; 
    private var album_id; 
    private var container; 
    private var ct; 
    private var next_pager; 
    private var prev_pager; 
    private var offset; 
    private var cbox; 
    private var instr; 
    private var show_titles; 
    private var PAGE_ROWS = 3; 
    private var ALBUMS = 4; 
    private var PHOTOS = 9; 
     
    private var EMBED_CODE = '<object src="album_tab.swf?album_id=%s&%arg"></object>'; 
 
    public function AlbumMaker( m ){ 
        m.debug('AlbumMaker instanced'); 
    }

Let me explain briefly the variables:

The state variable will maintain the state, or where we are in the current action, as we will have three levels of loading: the pages, the albums and the photos.

The main variable will hold a reference to the TabMaker class. We'll use this for tracing data, so instead of reproducing the whole debug function we can just use main.debug().

heading will hold a field for indicating where we are. The rs variable will be an array with all the data loaded at a time, for easy looping trough results.

page_id and album_id will hold the id of the page and album respectively. We have some more variables which are just holders for different movieclips, paging buttons and codebox, which I won't go into in detail.

Finally, we have three important variables that will help us restrict the results: PAGE_ROWS, ALBUMS and PHOTOS. As the SWF has a fixed size, we'll restrict the number of results and page them with Next and Previous buttons.


Step 20: Getting the Pages

We need a way for the user to select a page and from that page an album which will be featured on the slideshow. Go to http://developers.facebook.com/tools/explorer, get an access token and load /me/accounts. You'll notice a list of pages, or an empty JSON array if you have no pages. What you see in the API console will match the result in Flash.


Let's load the same api connection in flash. Let's modify the AlbumMaker constructor function:

 
public function AlbumMaker( m ){ 
    main = m; 
    main.debug('AlbumMaker instanced'); 
     
    //get the accounts 
    Facebook.api('me/accounts', accounts_loaded, {limit: 100} ); 
} 
 
private function accounts_loaded( succ, fail ){ 
    if( succ ){ 
        main.debug( succ ); 
    } else { 
        main.debug('Could not load accounts connection'); 
    } 
}

If you test the movie now, you'll get the result logged in the console. Of course, you'll have to test it on your own server, as debugging the movie from flash won't work, the Facebook API SDK works only on a live app. Being JSON, it can be output as a string and you can easily see it in the Chrome console as an object. You'll notice I used Facebook.api(), which accepts an api connection, a callback and an object with options. I use the option object to limit the result to 100 rows.

The Facebook API has its own paging functionality, but I have found that it doesn't always work the way it should. ( We have to give them a break, after all the data is changing so fast, I don't even know how they paginate them :) ).


Step 21: Showing the List of Pages

Let's quickly make a list of the pages loaded and display it in Flash:

 
private function accounts_loaded( succ, fail ){ 
    if( succ ){ 
    	var buff = ''; 
    	for( var i=0; i < succ.length; i++ ){ 
        	buff += succ[i].name+'\nCategory: '+succ[i].category+'\n'; 
        } 
     
        var txt = new TextField(); 
        txt.defaultTextFormat = new TextFormat('Helvetica',14,0xffffff,true ); 
		txt.text = buff; 
        txt.multiline = true; 
		txt.autoSize = 'left'; 
		txt.x = 20; 
		txt.y = 100; 
        txt.width = 300; 
		addChild( txt ); 
         
    } else { 
        main.debug('Could not load accounts connection'); 
    } 
}

Test the movie now and you should have a list of all the pages, along with any application you have created. Of course, for the purpose of the application, we only need to get the pages, but we'll do this in the next part.



That's It For Now

This is the end of part 1. In the next part, we'll create the clickable page items, the albums and the code generation functionality. In the later parts, we'll build the photo tab which will appear in the page, after you paste the generated code. In the end you'll be able to create your own Flash-based page tab widgets.

Advertisement
Related Posts