2012年2月10日 星期五

Facebook應用程式開發資料

 Facebook Flash Application開發心得(1) -FB Connect-how to start

使用Facebook的api來開發的應用程式基本上有很多種,Adobe這邊有大概的說明:
http://www.adobe.com/devnet/facebook/


其實說穿了就大概可以分成四大種,
1. 在Facebook裡的應用程式
2. 在Facebook裡的iframe應用程式
3. 不在Facebook裡的應用程式 (例如你自己的website)
4. 桌面應用程式 (就AIR囉)

為什麼要分種類呢? 因為四種的api寫法都有一點點不同,需要注意的地方也不一樣,不過就我玩了這一段時間,如果是要專心於用Flash當主題來開發的話,也許有些事情會簡單一點(雖然還是很麻煩!)。
Adobe官網也有一些簡單的入門教學,可以大概看一下,不過好像都是針對第1、2種的方式在做入門就是了,但是不無小補。

一、下載Facebook flash api:
OK,首先要做的當然是去下載Facebook flash api。
http://code.google.com/p/facebook-actionscript-api/


二、申請Facebook應用程式:
接著就是到Facebook登記一個自己的應用程式,取得API金鑰及Application Secret code。
http://www.facebook.com/developers/

登記好應用程式後就要先進行一些設定:
1. 基本資料的部份 -> 應用程式名稱 -> 就是填你的應用程式名稱…
2. 驗證、個人檔案、Widgets以及進階的部份先不用管沒關係,不影響開發。
3. 如果是要開發在Facebook裡的應用程式的話,就要去填「畫布(Canvas)」裡的資料,如果是要開發不在Facebook裡的應用程式,那就要去填「Connect」裡的資料。
4. 畫布(Canvas) -> 畫布頁面網址 -> 使用者打這個網址就會連到你的應用程式
5. 畫布(Canvas) -> Canvas Callback URL -> 你的應用程式「實際上」的網址。
6. 畫布(Canvas) -> 呈現方法 -> 選iframe或是FBML (就是最上面第一種跟第二種的差別)
7. Connect -> Connect URL -> 你應用程式「實際上」的網址。
8. 先填選Connect吧,從Connect入手我覺得比較快,而且一但Connect的部份上手了之後,再轉成iframe應該很多部份會很快。

基 本上由於目前我只試過用iframe及connect的方法開發,為什麼我不用FBML? 因為我不太會php…,所以我為了怕以後需要用asp或asp.NET整合時會發生的問題,因此我一開始玩Facebook api的時候就是先玩iframe,之後才試著玩connect。
所以我之後會記錄在這裡的一些經驗大多都會是以這iframe及connect為主。
這 一篇則會是以Connect做為開始,因為如果開發iframe application話,關於畫布(Canvas)裡的很多設定就要去處理,也要瞭解每個設定為什麼要這麼設(為了try這些設定的不同真的很花時 間),而Connect的大部份api寫法都跟在iframe裡的差別不會很大,所以我才會想說先從Connect application下手應該會是比較好的方法。


三、建立一個crossdomain policy:
由於facebook的api需要許多的認證,因此他們有他們自己的crossdomain檔,不像flash一樣都是用crossdomain.xml。這個facebook的crossdomain檔我通常都沒去改它的名字 - xd_receiver.htm。
把xd_receiver.htm它放在你application「實際存在」的空間裡,當facebook需要時自然會來讀它,例如:如果你的Application是位於http://iamjason.com/demo/,那麼你就可以把它丟在這兒就好。
xd_receiver.htm會長成像這個樣子:
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">  
  2. <html xmlns="http://www.w3.org/1999/xhtml">  
  3. <body><script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/XdCommReceiver.js" type="text/javascript"></script>  
  4. </body>  
  5. </html>  

你可以自己寫一個,或者是乾脆到這裡下載,裡面什麼東西都不用改。


四、來個Hello World:
請注意,這個Hello World是使用Connect的方式,因此請注意如果在application裡的設定沒有填寫Connect URL的話會有點問題。

1. 建立一個index.htm,使用Connect的話,html的宣告需要依照facebook的標準,如下:
  1. <html xmlns="http://www.w3.org/1999/xhtml" xmlns:fb="http://www.facebook.com/2008/fbml">  


2. 即使我們要用Flash來開發,但是Facebook的一些限制,我發現很多時候需要借用Facebook的javascript api才能達到一些功能(例如邀請朋友以及獲得某些授權...等等),所以我們要引用需要的javascript檔進來:
  1. <script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php" type="text/javascript"></script>  

3. 編寫需要的javascript,初始化facebook connect,並判斷登入狀態:
  1. <script type="text/javascript">  
  2. //Api金鑰  
  3. var api_key = "cdXXXXXXXXXXXXXXXX";  
  4.   
  5. //初始化facebook connect  
  6. //後面的參數分別是  
  7. //第一個參數 : Api金鑰  
  8. //第二個參數 : xd_receiver.htm的位置,如果沒更動就照著填  
  9. //最後一個物件參數是optional的,我自己覺得實作這一部份會比較有趣,  
  10. //對於整個user的登入狀態也比較好控制  
  11. //我選擇實作兩個function :  
  12. //ifUserConnected : 當登入後要觸發的function  
  13. //ifUserNotConnect : 如果沒登入的話要觸發的function  
  14. FB.init(api_key, "xd_receiver.htm", {"ifUserConnected":onConnected,"ifUserNotConnected":onNotConnected});   
  15.   
  16. function onConnected() {  
  17.  alert("connected");  
  18. }  
  19. function onNotConnected() {  
  20.  alert("not connected");  
  21. }  
  22. </script>  

這邊寫完大概就可以放上去測試一下了,如果你的Connect URL填寫的是
http://iamjason.com/demo/
那麼就把這個htm放到這裡去,然後打開瀏覽器輸入這個網址,理論上你就會得到一個”not connected”的alert。

4. 加入一個登入的鈕:
Facebook允許它的javascript去render一些需要的視覺控制元件,這邊我們使用登入鈕來做測試。
在<body>裡加上一個div,裡面塞入登入鈕:
  1. <div id="loginBtn" style="display:block">  
  2. <fb:login-button></fb:login-button>  
  3. </div>  


然後改寫一下剛剛的javascript裡onConnected及onNotConnected的function,讓還沒登入時出現登入鈕,登入後就把登入鈕隱藏起來:
  1. function onConnected() {  
  2.  //alert("connected");  
  3.  document.getElementById("loginBtn").style.display = "none";  
  4. }  
  5. function onNotConnected() {  
  6.  //alert("not connected");  
  7.  document.getElementById("loginBtn").style.display = "block";  
  8. }  

完成了,這樣基本上就可以測試一下了。
會看到一個facebook的制式藍色登入鈕,點了它之後會跳出一個小視窗,登入後就會把登入鈕隱藏起來。
由 於Facebook是用session的方式來驗證登入狀態,因此一但登入後,只要這個瀏覽器的session沒有改變,重新整理畫面的話仍然會被視為是 登入狀態。不過我遇到一個狀況,如果重新整理畫面,onNotConnected會先被觸發,過一陣子才會觸發onConnected,不過我想這很正 常,應該是連到Facebook去驗證的時間差,所以順道提一下,之後在開發時盡量避免被這問題卡到。

另外,要初始化Facebook api的方法其實很多,大部份看到的都是用new一個FB.ApiClient來處理,但是當FB.ApiClient被new出來的時 候,Facebook如果判斷使用者的狀況是尚未登入的話就會馬上將使用者導去登入,可是如果我們使用Connect來建立application時,常 常的情況是要將Facebook的api用在自己的網站上,又不想使用者一來就馬上就先被要求登入,所以我才會選擇使用FB.init的方式進行初始化, 然後在真的需要使用者登入的時候再進行登入的動作。
這兩種作法要採用哪一種方法,我想就是看當時要開發的需求而定了,之後在進行iframe的application開發的時候,將會採用new FB.ApiClient的方式。(因為一定要先登入)

現在我們有了Hello World,下一篇就是準備把Flash給帶進來了。




 Facebook Flash Application開發心得(2) - FB Connect - 接上Flash

 使用FB.init初始化Facebook之後,除了要藉由javascript的api來應用Facebook的一些功能以外,其實最重要的就是要取得Facebook的登入session資訊。
由於Facebook的判別登入權限是由很多參數所記錄及驗證的,flash的api也需要這些參數來進行資料的傳遞,因此取得這些參數是很必要的。
這 些參數裡有兩個值是最重要的,分別是session_key及secret,前者是此次使用者登入的session值,後者則是facebook動態產生 的secret值,這個secret值跟Application設定時所看到的secret不太一樣,基本上Facebook官方建議我們不要將 Application設定畫面上的secret值直接寫在程式裡,因為很容易被有心人破解取得,所以Facebook的javascript api在進行驗證時會自己從Server取得一組由Facebook動態產生的secret來使用,但是Flash api就辦不到,必需要將secret寫死在flash或是flashvars裡,這也就是要使用javascript api來進行登入動作的原因之一。
另一個使用javascript api的原因就是session的取得,雖然官方的flash api的文件裡建議我們使用com.facebook.utils.FacebookSessionUtil類別來統一處理session,文件裡說 FacebookSessionUtil會自己判斷是該使用DesktopSession、JSSession或是WebSession,但是我發現 FacebookSessionUtil是有bug的,即使在網頁上跑flash,它仍然會使用DesktopSession來做為session的處理 類別,但是這麼一來一但當頁面被refresh時,flash將會失去session的相關處理能力,需要再次重新登入一次,對使用者來說這會變得非常的 不友善。
雖然說FacebookSessionUtil有這種缺點,但是它在iframe架構的application裡卻可以運作正常且很好 用,因此關於FacebookSessionUtil的部份就留到iframe的時候再講,目前為止在FB connect的部份我將會直接使用WebSession。

現在要將flash放入到FB connect的application裡,會延用到上一篇的東西,但稍作改寫,由於我假設我們是要開發全Flash的application,因此我也將登入Facebook的按鈕從html裡搬到flash裡。

整個主要程式的運作流程會是:
1. 載入swf。
2. Swf呼叫javascript進行FB.init。
3. Javascript去跟Facebook驗證使用者是否已經登入。
4. 若是已經登入,javascript取得必要的session_key及secret,並將這兩個值傳給swf。
5. Swf依照這兩個參數進行WebSession的初始化。

一、 HTML上javascript的改寫:
  1. < script type="text/javascript" src="Scripts/swfobject.js"> < /script>  
  2. < script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php" type="text/javascript"> < /script>  
  3. < div id="flashContent"> < /div>  
  4. < script type="text/javascript">  
  5. //Application Key  
  6. var api_key = "cdxxxxxxxxxxxxxxxxxxxxxxxxx";  
  7.   
  8. //將Application Key藉由FlashVars傳給flash  
  9. var flashVars = new Object();  
  10. flashVars.api_key = api_key;  
  11. swfobject.embedSWF("FBStep2.swf","flashContent","550","400","9.0.47","Scripts/expressInstall.swf",flashVars, {}, {id:"fbSwf",name:"fbSwf"});  
  12.   
  13. //當Flash被載入後flash會呼叫這個function進行FB.init的初始化  
  14. function initFB() {  
  15.  FB.init(api_key, "xd_receiver.htm", {"ifUserConnected":onConnected,"ifUserNotConnected":onNotConnected});  
  16. }  
  17.   
  18. //判斷當User登入後,取得secret及session_key並傳給Flash。  
  19. //由於WebSession好像無法直接取得登入者的uid,  
  20. //因此這邊我順便將uid也傳入給flash  
  21. function onConnected() {  
  22.  //alert("onConnected");  
  23.  var apiClient = new FB.ApiClient(api_key);  
  24.  document.getElementById("fbSwf").fbConnected(apiClient.get_session().uid, apiClient.get_session().secret, apiClient.get_session().session_key);  
  25. }  
  26.   
  27. //如果沒登入,暫時不做任何事情  
  28. function onNotConnected() {  
  29.  //alert("not connected");  
  30. }  
  31. < /script>  

應該很直覺,不用再多做解釋。

二、 Flash裡的處理:
因為code不算多,直接全部po出來,加上註解。
  1. package {  
  2.  import flash.display.MovieClip;  
  3.  import flash.events.Event;  
  4.  import flash.events.MouseEvent;  
  5.  import flash.external.ExternalInterface;  
  6.  import com.facebook.Facebook;  
  7.  import com.facebook.session.WebSession;  
  8.  import com.facebook.events.FacebookEvent;  
  9.    
  10.  public class FBStep2 extends MovieClip {  
  11.   private var _facebook:Facebook;  
  12.   private var _websession:WebSession;  
  13.   private var _uid:String;  
  14.   public var connect_mc:MovieClip; //這是登入鈕  
  15.     
  16.   public function FBStep2():void {  
  17.    //呼叫javascript進行FB.ini,  
  18.    //並且註冊一個讓javascript callback的function  
  19.    ExternalInterface.call("initFB");  
  20.    ExternalInterface.addCallback("fbConnected", fbConnected);  
  21.      
  22.    //給予登入鈕Click事件  
  23.    connect_mc.addEventListener(MouseEvent.CLICK, connectClickHandler);  
  24.   }  
  25.     
  26.   //當登入後,會被javascript呼叫的function  
  27.   private function fbConnected(pUid:String, pSecret:String, pSessionKey:String):void {  
  28.    //隱藏登入鈕  
  29.    connect_mc.visible = false;   
  30.      
  31.    _uid = pUid; //儲存uid  
  32.    //取得api_key  
  33.    var _apiKey:String = loaderInfo.parameters.api_key;  
  34.    //產生一個WebSession的instance  
  35.    //並且將api_key、secret及session_key帶入  
  36.    _websession = new WebSession(_apiKey, pSecret, pSessionKey);  
  37.    //監聽WebSession連線成功後的事件  
  38.    _websession.addEventListener(FacebookEvent.CONNECT, connectHandler);  
  39.    //產生一個Facebook instance並且指定使用的session  
  40.    _facebook = new Facebook();  
  41.    _facebook.startSession(_websession);  
  42.   
  43.    //與Facebook進行session的驗證  
  44.    _websession.verifySession();  
  45.   }  
  46.     
  47.   //登入鈕按下之後,呼叫javascript跳出登入視窗  
  48.   private function connectClickHandler(e:MouseEvent):void {  
  49.    ExternalInterface.call("FB.Connect.requireSession",null,true);  
  50.   }  
  51.   
  52.   private function connectHandler(e:FacebookEvent):void {  
  53.    trace(e);  
  54.    if (e.success) {  
  55.     trace(“驗證成功”);  
  56.    }  
  57.   }  
  58.  }  
  59. }  


三、 其它解說:
在 Flash裡,我捨棄了使用Flash api裡的login method,而決定呼叫javascript來處理的原因,是因為如果沒有將application secret傳出的話,facebook.login()不知為何一直無法正常運作,但是如果我把application secret寫入,那就又失去了安全性,因此我才又將登入動作交還給javascript處理。
FB.Connect.requireSession 有兩個參數,第一個是登入後的callback function,由於我們已經實作了ifUserConnected,因此這個function可帶入null,第二個參數是決定是否要另開一個視窗當 登入窗口,通常這個參數可以忽略,在純html的狀況之下呼叫FB.Connect.requireSession一定會另開,不過如果這個動作是由 flash所觸發的話,預設值會是直接蓋在頁面上,可是flash的wmode沒有設成transparent的話flash反而會蓋在登入畫面之上,因 此我特別將第二個參數設成true來強迫它另開一個視窗出來。
更正:經過實驗,似乎只有在IE才會跳出新視窗,FireFox裡好像不管怎樣都是跳lightbox...

這 個程式的整個流程還沒有完全的完整,但是已經有考量到使用者是先登入再到這頁面或是來到這頁面才進行登入動作的兩種狀況,在一般自己的網頁上來處理應該是 足夠了,但是還沒處理到使用者半途登出Facebook的情況,這一點可以事後再繼續補足,至少最麻煩的session取得已經解決。

接下來我也許會先介紹幾個從Facebook取得資料的類別,然後就可以再回過頭來介紹iframe的架構,其實iframe與FB connect最多最大的差別就只在於session的取得,其它的都大同小異。




 Facebook Flash Application開發心得(3) - 由Flash Api從Facebook取得資料
當最煩人的session問題解決之後,就該試著跟Facebook要點資料來瞧瞧了。
這一篇會大概解說一下Flash api如何跟Facebook索取資料的動作。
基本上Facebook Flash api在這方面的流程很簡單,其實就是先產生一個「命令」然後把這個命令丟給Facebook類別往外post出去就好,要做什麼動作就去產生相對應的命令類別就可以了。
所有的命令類別都繼承com.facebook.net.FacebookCall,有興趣的人可以直接去說明文件看這個類別,它就有列出所有它的子類了。
說明文件在這邊:
http://facebook-actionscript-api.googlecode.com/svn/release/current/docs/index.html
幾乎所有的命令類別都是在com.facebook.command的package裡。

相對於發出命令的簡易,Facebook Flash api在接收資料時的繁複卻是不可思議到讓人惱怒。有時一個命令發出後,收到的資料型別居然要層層解析,動輒用到四五個類別,再加上說明文件的陽春,所以往往需要不斷的一直trace,最後才能得到你想要的資料。
這個部份待會的code就會見識到…。

接下來,我們繼續接著上一篇的去修改,Html的部份就不用動了,這次沒動到javascript,所以只改ActionScript。
我們這次要從Facebook取得自己的個人資料,因此在上次的connectHandler裡驗證成功後馬上執行這個動作:
使用到的是com.facebook.commands.users.GetInfo;這個類別。

  1. //需要import這兩個類別  
  2.   
  3. import com.facebook.commands.users.GetInfo;  
  4.   
  5. import com.facebook.data.users.GetInfoFieldValues;  
  6.   
  7.   
  8.   
  9. private function connectHandler(e:FacebookEvent):void {  
  10.   
  11. trace(e);  
  12.   
  13. if (e.success) {  
  14.   
  15. trace("驗證成功");  
  16.   
  17. //加入這一行,進行取得資料的動作  
  18.   
  19. getMyInfo();  
  20.   
  21. }  
  22.   
  23. }  
  24.   
  25.   
  26.   
  27. private function getMyInfo():void {  
  28.   
  29. //產生一個命令的instance  
  30.   
  31. //GetInfo是取得某人(可多人)的某些欄位資料(可指定欄位)  
  32.   
  33. //我這裡是取得自己的所有欄位資料  
  34.   
  35. var _call:GetInfo = new GetInfo([_uid], GetInfoFieldValues.ALL_VALUES);  
  36.   
  37. //監聽FacebookEvent.COMPLETE事件  
  38.   
  39. _call.addEventListener(FacebookEvent.COMPLETE, infoCompleteHandler);  
  40.   
  41. //把instance交給Facebook類別往外丟出去  
  42.   
  43. _facebook.post(_call);  
  44.   
  45. }  


GetInfo這個類別是用來跟Facebook索取會員資料用的,它可以允許一次索取很多人的,因此第一個參數是會員uid組成的Array。然後也可 以指定要索取哪一些欄位,這些欄位的定義都在GetInfoFieldValues這個類別裡的靜態屬性,一樣是Array的形式,如果你要索取所有的欄 位,那就直接帶入GetInfoFieldValues.ALL_VALUES就好,它本身就是一個Array型態。

接下來就是要處理事件回傳的結果:

  1. //需要import這三個類別  
  2.   
  3. import com.facebook.data.users.GetInfoData;  
  4.   
  5. import com.facebook.data.users.FacebookUserCollection;  
  6.   
  7. import com.facebook.data.users.FacebookUser;  
  8.   
  9.   
  10.   
  11. private function infoCompleteHandler(e:FacebookEvent):void {  
  12.   
  13. //可藉由trace(e)來觀察每個呼叫的回傳資料狀態  
  14.   
  15. trace(e);  
  16.   
  17. //如果e.success且e.data有值的話, 解析資料  
  18.   
  19. if (e.success && e.data != null) {  
  20.   
  21. //因為可以一次取得很多人的資料  
  22.   
  23. //所以資料可能是多筆  
  24.   
  25. //我這邊將它轉成Array  
  26.   
  27. var _userArray:Array = GetInfoData(e.data).userCollection.toArray();  
  28.   
  29. //in this case, 人數一定是1  
  30.   
  31. trace("人數 = " + _userArray.length);  
  32.   
  33. //將自己的資料取出  
  34.   
  35. var _my:FacebookUser = FacebookUser(_userArray[0]);  
  36.   
  37. //打上自己的名字  
  38.   
  39. name_txt.text = "Hello! " + _my.name;  
  40.   
  41.   
  42.   
  43. //把自己的大頭照load進來  
  44.   
  45. var _ldr:Loader = new Loader();  
  46.   
  47. _ldr.load(new URLRequest(_my.pic));  
  48.   
  49. _ldr.x = 5;  
  50.   
  51. _ldr.y = 30;  
  52.   
  53. this.addChild(_ldr);  
  54.   
  55. }  
  56.   
  57. }  


開發Facebook application時,一直trace回傳的FacebookEvent會是一個好習慣…。FacebookEvent的形態基本上會是這樣:
[FacebookEvent type="complete" success=true data=[object GetInfoData] error=null]
type就不用講了,要注意的是success及data。
success就只有true或false,通常都是true,除非你跟Facebook之間的connection斷了,那success就會是false然後error會有東西。
data則是主要的資料,data會依照你命令的種類不同而有不同的資料型態,理論上命令的類別都是在 com.facebook.command.xxxx的package裡,相對應的資料型態類別則會放在com.facebook.data.xxxx的 package裡。
也就是送出命令時是去command裡找,接收到事件時就回來data這邊找。

這次的命令是com.facebook.command.users.GetInfo,收到的資料是com.facebook.data.users.GetInfoData。
但是其實討人厭的就在這邊,光一個GetInfoData還不夠,真的資料是存在GetInfoData類別裡的userCollection屬性 (com.facebook.data.users.FacebookUserCollection類別),所以只好不斷的轉型別把它轉成陣列,最後陣列 裡儲存的是一個一個的com.facebook.data.users.FacebookUser型別的資料…。
因此光解析個人資料就要動用三個型別… 加上發出命令的類別的話一共是五個,老實說,說明文件夠好的話這都還ok,偏偏不是,所以開發Facebook application的話一直trace會是一個好習慣。
當熟悉它的運作方式後,十分建議自己寫一些類別來整合簡化這些步驟。


如果沒意外的話,當登入後就可以看到自己的名字跟照片顯示在畫面上了。

 Facebook Flash Application開發心得(4) – Iframe的架構下取得Session
 相對於FB Connect在取得Facebook登入Session值的複雜度,Iframe架構下的Application在這方面反而方便許多。
前一篇已經有說到Flash api裡的FacebookSessionUtil在FB Connect的情況下會有bug,但是在iframe之下卻可以運作得非常順利。其中很大的原因,是因為iframe的架構原本就是附屬在 Facebook裡的,登入的狀況都由Facebook先處理掉了,Facebook才會開始載入iframe,也就是說user很少會在還沒登入的狀況 之下就接觸到你的iframe application,因此我們可以少掉一部份處理尚未登入的情況,但如果user真的有辦法在未登入的情況下進入我們的iframe application(會有,在某些情況下會發生),我們只要直接把頁面導回給Facebook處理就好,等登入後Facebook會自動再幫我們導回 來(很方便吧!)。這個利用Facebook來做導向的機制也會發生在user第一次進入應用程式的時候的那個授權頁。
另一個很重要的原因,正由於iframe架構是由Facebook所載入的,因此Facebook「很貼心」的順便帶了一些十分有用的資訊放在url後面的變數裡給iframe,這一大堆的資訊裡面就包括了Session值。

既然知道了這很重要的兩點,就來實作吧。
首先當然是針對javascript下手。

依照剛剛所說的兩個重點,一開始先要取得的就是Facebook帶給iframe的所有必要參數。
  1. < script type="text/javascript">  
  2.   
  3. var api_key = “XXXXXXXXXXXXXXXXX”; //api key  
  4.   
  5. //取得網址列後面的所有參數字串  
  6.   
  7. var queryString = window.location.search;  
  8.   
  9. queryString = queryString.substring(1);  
  10.   
  11. var fields = queryString.split('&');  
  12.   
  13. //fb_sig_added這個值很重要,它指出了user有沒有認證使用你的application  
  14.   
  15. var fb_sig_added = 0;  
  16.   
  17.   
  18.   
  19. //將所有網址後的參數都原封不動帶入flashVars  
  20.   
  21. var flashVars ={};  
  22.   
  23. for (var i = 0; i < fields.length; i++) {  
  24.   var index = fields[i].indexOf('=');  
  25.   var key = fields[i].substring(0, index);  
  26.   var value = fields[i].substring(index + 1);  
  27.           
  28.   if (key.toLowerCase() == "fb_sig_added"){  
  29.     fb_sig_added = value;  
  30.   }  
  31.   flashVars[key] = value;  
  32. }  
  33. flashVars.api_key = api_key;  
  34.     
  35. if (fb_sig_added == 0) { //如果還沒登入或還沒授權就導向  
  36.   window.parent.location = "http://www.facebook.com/login.php?api_key=" + api_key + "&next=index.htm&v=1.0&canvas=1";  
  37. else { //如果已經ok就進行facebook javascript api初始化  
  38.   initFB();  
  39. }  
  40. < /script>  

上面這段code最重要的部份就在於取得所有網址列後面的變數並放在flashVars裡。
另一個重點就是fb_sig_added變數的取得,它代表了user是否已經授權使用你的application,如果是0(尚未登入的情況下好像也會 是0),我們就把整個頁面導向到http://www.facebook.com/login.php?api_key=" + api_key + "&next=index.htm&v=1.0&canvas=1的這個網址,網址列後面的參數api_key就是你的 api_key,next指的是授權後要再導回來的頁面,我習慣是再導回index.htm。(有興趣的人可以觀察一下,事實上Facebook如果是在 你已經登入的情況但沒授權的時候是會導到另外一頁的,不過next也會跟著被帶過去,所以我們只要直接全交給login.php去處理就好)
當一切都就續時,我最後呼叫一個initFB的function,這個function裡我就開始初始化facebook javascript api。
  1. < script type="text/javascript">  
  2. function initFB() {  
  3. FB_RequireFeatures(["Api","XFBML","Connect"], function() {  
  4. FB.Facebook.init(api_key, "xd_receiver.htm");  
  5. FB.Facebook.apiClient.requireLogin(function(exception){   
  6. //facebook api初始化之後  
  7. //產生一個FB.ApiClient實體(以後有些功能會需要它)  
  8. apiClient = new FB.ApiClient(api_key);  
  9. //呼叫一個function來載入swf  
  10. initFlash();  
  11. })  
  12. })  
  13. }  
  14. < /script>  

初始化Facebook javascript api的部份,跟FB Connect不一樣,我這次採用FB_RequireFeatures來做為初始化的點,因為我很確定user已經是登入狀態,所以一開始就初始化所有該用到的東西。
而且如果我沒記錯的話(說真的印象有點久遠了),使用FB_RequireFeatures的話,Facebook會強制在你的appilication 外層加上它的外框(上面的header及下面的footer),所以如果你是直接輸入你application實際的網址的話,遇到 FB_RequireFeatures時還是會Facebook框起來。
因此之後有時候,我們將會遇到iframe及FB Connect同時應用在一個application的情況中,也就是說即使在iframe的情況之下,有時還是要用到FB Connect,這也是我先介紹FB Connect的原因之一。(如果我以後還會繼續寫下去的話)
至於FB_RequireFeatures裡所帶的一些值的意義,可以去官方的wiki上看,基本上我也沒有實際的去比較這幾個之間差多少,所以我就乾脆直接初始化三種我覺得可能會用到的。
通常這個function這樣應該就ok了,不需要改寫,直接拿去用就好。
等到一切都就緒後,就呼叫initFlash這個function來載入flash,這function我就不寫出來了,反正就是用swfObject載入就是了 (記得要將flashVars帶進去)

接下來就是Flash裡的code了。
既然已經說了FacebookSessionUtil在iframe裡很好用,就直接大方的用了吧。
  1. package {  
  2. //需要import以下類別  
  3. //因為我是用document class,所以多import了MovieClip  
  4. import flash.display.MovieClip;  
  5. import com.facebook.Facebook;  
  6. import com.facebook.utils.FacebookSessionUtil;  
  7. import com.facebook.events.FacebookEvent;  
  8.   
  9. public class FB_documentClass extends MovieClip {  
  10. private var _sessionUtil:FacebookSessionUtil;  
  11. private var _facebook:Facebook;  
  12. public function FB_documentClass() {  
  13. //取得api_key  
  14. var _apiKey:String = this.loaderInfo.parameters.api_key;  
  15. //初始化FacebookSessionUtil  
  16. //基於api secret的值不曝光,因此第二個值帶null  
  17. _sessionUtil = new FacebookSessionUtil(_apiKey, nullthis.loaderInfo);  
  18. //監聽FacebookSession跟Facebook之間連線的事件  
  19. _sessionUtil.addEventListener(FacebookEvent.CONNECT, fbConnectHandler);  
  20. //如果使用FacebookSessionUtil的話  
  21. //Facebook物件實體是由FacebookSessionUtil給的  
  22. _facebook = _sessionUtil.facebook;  
  23.   
  24. //如果fb_sig_session_key這個值有值的話  
  25. //直接請FacebookSessionUtil跟Facebook取得連線就可  
  26. if (this.loaderInfo.parameters.fb_sig_session_key) {  
  27. _sessionUtil.verifySession();  
  28. else {  
  29. _sessionUtil.login(true);  
  30. }  
  31. }  
  32.   
  33. //理論上都正常的話是連線成功的  
  34. //使用FacebookSessionUtil的話可以直接取得uid  
  35. private function fbConnectHandler(e:FacebookEvent):void {  
  36. trace("uid = " + _facebook.uid);  
  37. }  
  38. }  

基本上,user算是通過層層關卡才會到達flash這一層的驗證:Facebook本身一層,javascript有兩層驗證,第四層才會是 FacebookSessionUtil,所以基本上在上面的code裡使用FacebookSessionUtil.login()是用於開發時直接在 本機端跑的情況下,否則應該都是直接verifySession就可以取得登入uid了。
ps:如果是在開發的時候,api secret值需要寫入,否則無法登入,這就是Facebook建議我們不要把api secret值寫死在code裡的原因,因為一但被取得,其它cracker就可以利用本機端寫程式來破壞你的application,所以記得上線時要 把api secret值從code裡拿掉,FacebookSessionUtil自動會從loadInfo裡所有的flashVars取得它該使用的 secret值。
 
 
 
感謝i am Jason提供資訊

9 則留言:

匿名 提到...

Good day! This is kind of off topic but I need some help
from an established blog. Is it very hard to set up your own blog?
I'm not very techincal but I can figure things out pretty quick. I'm thinking about setting up my own
but I'm not sure where to start. Do you have any points or suggestions? Thank you

Feel free to surf to my webpage: onlineradio

匿名 提到...

What I didn't know was how I would get all of what I wanted in just six hours. Another thing you'll need
is ѕome stгength tο еnduгe, becausе there's a good chance you'll be yоur оωn produceг for the shoω or ρerhaps the best produсеr the ѕhow has.
Additionally, sοme new attributes mаκe it eѵen
еasier to make гaԁio buttons ԁo еxactly what you ωant them to do.



My website; http://alofokemusic.net
Also see my web site :: click the up coming article

匿名 提到...

Verу good article! Wе ωill be
linking tо this particulaгly great
post on ouг site. Keeρ up the good ωriting.


Mу ωeb pagе just click the next webpage
my web site :: http://24hei.nl/wiki/index.php?title=Considering_Realistic_internet_Methods

匿名 提到...

If you are using firewall software such as Outpost Firewall
Pro, the paid edition of Online Armor and Kaspersky Internet
Security or PURE, you can take advantage of using their Blocklist feature that will block
connections to known malicious URL and IP addresses.
B) SEO basics - Image 2: Select-'English' and 'All Countries and Territories'.
The tools include efficient internet marketing, proper usage of keywords, flawless content and creating
social media buttons. SEO (search engine optimization)
and keyword density are terms that scare many a writer who want to
write for the internet. NOW, I don't mean you should just put keyword spam in your footer. Search engines are getting smarter at detecting sites that are spamming keywords or made solely for the purpose of advertising. They make their strategy according to the audience their client is targeting. Second tool for power suite is website auditor. The businesses have understood the need to take SEO services for attaining good search engine placement. What are the advantages of article submission. Arrange the H1, H2 and H3 tags serially with proper hierarchy. Still hanging on. Their success is based on how many sales and customers you bring. An SEO strategy should combine a number of elements that work together to get results for you. Know how to get better rank. SEO companies may only offer this type of service. In fact, soon, not using RDFa could put a site at a disadvantage. You will not even get to a 1 or 2 until Google has fully crawled your website or blog enough to give it a ranking. And make the work flow smoothly, using good grammar at all times. If customers like what they see, they just might go on reading.

My web-site ... http://yetanotherchildrensbookblog.blogspot.ru/2010/02/alexander-and-wind-up-mouse.html

匿名 提到...

Few travellers on a Mashobra tour can resist the temptation of seeking blessings at the Mahasu Devta Temple.
Thus professional firms for web development in London are better got in touch with.
''. When it comes to bridging your skills gap in
gaming world then you can do anything to prove yourself. An analysis this change will
give us insight into the supposed benefits they entail.
This will also open the Backup and Restore Center,
which will warn you that "Windows Backup has not been set up" and "Windows could not find a backup for this computer. We relate to it like it's the truth. In an effort to counter the lack of support from Microsoft, an SVG plug-in for Internet Explorer was developed and supported by Adobe. a far cry: a long way from. A Whole Lot of Exciting Options to Choose from Advanced car wash equipment use low-flow technology that drastically reduces drying times for carpets and upholstery.

Feel free to surf to my blog :: northsydneydive.com.au
my webpage > More Material

匿名 提到...

The particular electronic cigarette ego basic starter kit is fantastic for new users.

Remove other nearby wireless devices, such as a cordless or cellular
telephone and make sure the mouse is at least eight inches
away from a wireless keyboard. Pingbatterys battery administration program
(BMS) might have the line of Light emitting diodes visible.


My webpage ... spiele spielen kostenlos

匿名 提到...

Along with cheese and cookware shops, the streets will be filled with a number of vendors
selling a diverse range of food items specially prepared for the festival.
However, the MP3 player doesn't have an impressive volume buttons and the quality of sound is also not good. The Zune application has been available for a couple of years now, and as well as being the ideal desktop media player that handles movies, music, TV and photos, it is also designed to sync with media players and Windows Phone while providing you with access to the Zune Marketplace to purchase music and video.

Look into my website: online radio

匿名 提到...

You could experience natural disasters like cyclone, tornadoes, earthquakes, and
fire. After deciding on the video games you want
to sell, search for websites that offer the facility.

Otherwise, choose the NES emulator you think will work best for you and your system.


Also visit my weblog ... Recommended Internet page

匿名 提到...

Usually, a brand new website takes about six months
to one year to appear in the SERPs of Google, assuming the service provider is worth
their salt. If you encourage your visitors to write
their original reviews about your products instead of coping reviews from competitive websites to show you have circulation and satisfied customers,
your website is more likely to earn higher ranking in the major search
engines. You can then take a hard look at the companies that come up
for that particular keyword. This will not only help you find the best service provider but will help you build an idea
about the recent SEO market. Thus, in minimum cost, you get
an opportunity to increase your site ranking on Search Engine Result Page (SERP).
This is the best part to ensure complete uniqueness to each of the websites.
Some SEO firms focus on content spinning and submitting articles.
Having realized that it is practically not possible to combat
with SEO Next in terms of services and offerings at this point of time, rivals have started thinking of
an easier alternative of being successful in their mission.
Moreover, some companies are not able to get the desired results and their techniques might even have bad
effects on the business's website. For those of us who are using the internet to make money, we all know that it is absolutely essential to get visitors out to our websites. Search engine optimization is necessary for online businesses because it lets your website get found. The growth management of small business can be accomplished with SEO as an integral part of your overall Internet marketing strategy. Advertise by Selling Branded Products. You can Google maps link for your website, which will be very helpful if any person search in images sections. Once you find the right and affordable SEO Company, it is essential to talk about your business objectives, target customers and future goals with the professionals to help them develop their strategies accordingly. The sooner a site is presented in the search result, or the higher it “ranks”, the more searchers will visit the site. The World Wide Web is an incredible source of customers and potential revenue for all types of businesses and companies in all niches. Keep in mind that Google doesn’t really like page rank manipulation, even if it’s internally on your site or externally by backlink spamming. What is the magic formula. Never post a half edited article, and never settle for less than your best.

My webpage pokeronmap.com