Space of Flex/AIR technologies

Beyond Plain Old Html Objects

Archive for the ‘Facebook’ tag

Desktop and Browser Facebook Apps with AIR and Flex

with 3 comments

Last week I was presenting at AUG Poznań and today remotely via Adobe Connect at AUG Trójmiasto, where I showed how to build applications usign AS3 API for Facebook that is available at Google Code. My goal was not only to show how to use Facebook API but also how you can build desktop and browser versions of the same app using conditional compilation in Flex. I took the approach of two Flash Builder projects one with minimum set of Flex (browser) code and AIR (desktop) project with common sources for both. Flex project actually links to AIR project src-common folder in Flash Builder. The structure of both projects looks like this:

Screen shot 2009-09-24 at 9.02.59 PM

Below you can also find example of MainView.mxml code that is common for both projects. Within that example you can see sections that will be compiled based on specified options for each project. I actually defined two compiler options CONFIG::AIR and CONFIG::FLEX. You can find more info about defining compiler options and conditional compilation here. Another very good approach especially in more complex cases is described here on Adobe Developer Connection.

Here is the link to my Demo of AS3 API on Facebook and also below is the badge with desktop version.


You can look at the source code of each example by right-clicking and choosing View Source option. Also you can download Flash Builder project archives from here and here, one with Flex and the other with AIR code.

<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
		 xmlns:s="library://ns.adobe.com/flex/spark" 
		 xmlns:mx="library://ns.adobe.com/flex/halo" width="100%" 
		 height="100%" currentState="CONNECTING">
 
	<fx:Script>
		<![CDATA[
			import com.facebook.Facebook;
			import com.facebook.commands.batch.BatchRun;
			import com.facebook.commands.friends.GetFriends;
			import com.facebook.commands.users.GetInfo;
			import com.facebook.data.batch.BatchCollection;
			import com.facebook.data.batch.BatchResult;
			import com.facebook.data.friends.GetFriendsData;
			import com.facebook.data.users.FacebookUser;
			import com.facebook.data.users.GetInfoData;
			import com.facebook.data.users.GetInfoFieldValues;
			import com.facebook.events.FacebookEvent;
			import com.facebook.net.FacebookCall;
 
			import flash.net.URLRequest;
			import flash.net.navigateToURL;
 
			import mx.collections.ArrayCollection;
			import mx.controls.Alert;
 
			CONFIG::AIR
			{
				// DesktopSessionHelper import required for AIR and Facebook Connect
				import com.facebook.utils.DesktopSessionHelper;
				import com.facebook.session.DesktopSession;
 
				// Session variable when running as AIR app
				protected var session:DesktopSessionHelper;
			}
 
			CONFIG::FLEX
			{
				// FacebookSessionUtil import required for Flex (browser) app
				import com.facebook.utils.FacebookSessionUtil;
 
				// Session variable when running as Flex (browser) app
				protected var session:FacebookSessionUtil;
			}
 
			/**
			 * Facebook class used to access FB remote API's
			 */
			protected var fbook:Facebook;
 
			/**
			 * Logged-in FB user
			 */
			[Bindable]
			protected var user:FacebookUser;
 
			/**
			 * Collection of logged-in user friends
			 */
			[Bindable]
			protected var userFriends:ArrayCollection;
 
			/**
			 * AIR init function
			 */
			CONFIG::AIR
			public function init():void
			{
				// Creating session based on API key
				session = new DesktopSessionHelper("795c0879607643aa3c5a363d09ce5384");
				// Registering handler when connected
				session.addEventListener(FacebookEvent.CONNECT, onConnect);
			}				
 
			/**
			 * Flex init function
			 */
			CONFIG::FLEX
			public function init():void
			{
				// When running in iFrame API key and secret values are not necessary
				// these are passed with flashVars from GET parameters
				session = new FacebookSessionUtil(null, null, loaderInfo);
				// Registering handler when connected
				session.addEventListener(FacebookEvent.CONNECT, onConnect);
				// Setting fbook from session properties
				fbook = session.facebook;
 
				// Checking if fb_sig_session_key was set from IFrame GET params
				if(loaderInfo.parameters.fb_sig_session_key)
				{
					// Verifying FB session
					session.verifySession();
				}
				else
				{
					// This application cannot run as external FB app
					Alert.show("You cannot run this application outside Facebook!");
				}
			}
 
			protected function onConnect(event:FacebookEvent):void
			{
				var uid:String;
 
				// Checking if connection was successful
				if (event.success)
				{
					// Conditional block that sets fbook variable after connection
					CONFIG::AIR
					{
						// Creating instance of Facebook class
						fbook = new Facebook();
						// Starting new FB session with apiKey and session secret 
						// received after connection in session variable
						fbook.startSession(new DesktopSession(
							session.apiKey, session.sessionData.secret, 
							session.sessionData.session_key));
 
						uid = session.sessionData.uid;
					}
 
					CONFIG::FLEX
					{
						uid = fbook.uid;
					}
 
					// Creating batch to make two data request at one FB call
					var batchRun:BatchRun;
					var batch:BatchCollection = new BatchCollection();
 
					// Batch item GetInfo returning info about current user
					batch.addItem(new GetInfo([uid], [GetInfoFieldValues.ALL_VALUES]));
					// Batch item GetFriends returning friends list of current user
					batch.addItem(new GetFriends(null, uid));
 
					// Posting batch to FB
					batchRun = fbook.post(new BatchRun(batch)) as BatchRun;
					// Registering batch run results handler
					batchRun.addEventListener(FacebookEvent.COMPLETE, onBatchRunResult);					
				}
				else
				{
					// In case of not successful connection
					Alert.show(event.error.errorMsg);
				}
			}
 
			/**
			 * Handler for batch run results
			 */
			protected function onBatchRunResult(event:FacebookEvent):void
			{
				// Setting results variable from event object
				var batchResult:BatchResult = event.data as BatchResult;
 
				// Getting data from first batch result item
				var userInfo:GetInfoData = batchResult.results[0] as GetInfoData;
				// Setting current user object
				user = userInfo.userCollection.source[0] as FacebookUser;
 
				// Getting data from second batch result item
				var friendsInfo:GetFriendsData = batchResult.results[1] 
					as GetFriendsData;
 
				// Building array of returned friends ID's
				var friendsUids:Array = new Array();
				for each(var friend:FacebookUser in friendsInfo.friends.source)
				{
					friendsUids.push(friend.uid);
				}
 
				// Doing another call to FB to get friends detailed info
				var call:FacebookCall = fbook.post(new GetInfo(friendsUids, 
					[GetInfoFieldValues.ALL_VALUES]));
				// Registering handler
				call.addEventListener(FacebookEvent.COMPLETE, onGetFriendsInfo);
 
				// Changing state to connected
				currentState = "CONNECTED";
			}
 
			/**
			 * Friends details request handler
			 */
			protected function onGetFriendsInfo(event:FacebookEvent):void
			{
				userFriends = new ArrayCollection((event.data as GetInfoData)
					.userCollection.source);
			}
 
		]]>
	</fx:Script>
 
	<s:states>
		<s:State name="CONNECTING"/>
		<s:State name="CONNECTED" />
	</s:states>
 
	<mx:ProgressBar includeIn="CONNECTING" label="Connecting..." 
					indeterminate="true" labelPlacement="center" 
					horizontalCenter="0" verticalCenter="0"/>
 
	<s:Label text="Hello {user.first_name}!" horizontalCenter="0" 
			 verticalCenter="-100" fontSize="29" includeIn="CONNECTED"/>
 
	<mx:AdvancedDataGrid id="adgFriends" dataProvider="{userFriends}" 
						 designViewDataType="flat" horizontalCenter="0" 
						 verticalCenter="19" includeIn="CONNECTED">
		<mx:columns>
			<mx:AdvancedDataGridColumn headerText="Name" 
									   dataField="first_name"/>
			<mx:AdvancedDataGridColumn headerText="Last Name" 
									   dataField="last_name"/>
		</mx:columns>
	</mx:AdvancedDataGrid>
 
	<mx:LinkButton label="Get AIR (desktop) version..." horizontalCenter="0" 
				   verticalCenter="150" color="#ABA5A5" fontWeight="bold" 
				   textDecoration="underline" fontSize="14"
				   click="navigateToURL(new URLRequest('http://www.riaspace.net/examples/fb-as3demo/air/'))"/>
 
</s:Group>

Written by Piotr Walczyszyn

September 29th, 2009 at 6:58 pm

Posted in Examples

Tagged with , ,

AS3 Facebook API – zdalna prezentacja dla AUG Trójmiasto

with 4 comments

facebook-logo W dniu dzisiejszym (godz. 18:00) w ramach spotkania grupy AUG Trójmiasto poprowadzę zdalną prezentację odnośnie tworzenia aplikacji dla Facebook’a z wykorzystaniem technologii Flex i AIR. Dodatkowym tematem prezentacji będzie tworzenie aplikacji działających w przeglądarce i na desktop’ie z wykorzystaniem tego samego kodu. Do tego posłużę się metodą kompilacji warunkowej oraz odpowiednią konfiguracją projektów we Flash Builder’ze.

Wszystkich zapraszam do obejrzenia mojej prezentacji przez Adobe Connect dostępnej pod tym adresem.

Written by Piotr Walczyszyn

September 29th, 2009 at 11:37 am

Posted in Events

Tagged with , ,

Switch to our mobile site