2011年1月5日 星期三

Facebook ActionScript Graph API ( 4 ) Dialogs

這一篇簡直是在考驗debug與找solution的功力!Dialog是用來彈出對話框,讓user與其互動,例如發布post到塗鴉牆,或是彈出extended permissions讓user同意等。因為user必須與其互動(按下同意按鈕之類)才會有反應,所以不需要特別的permission。例如不需要publish_stream權限也可以使用Feed Dialog去發post。目前文件裡面列出三種Dialog可用:Feed DialogFriends Dialog以及OAuth Dialog。而在這個API是使用Facebook.ui()來呼叫。很不幸的,這個method雖然可以正常呼叫,不過有點小bug,就是callback function無法正常呼叫,詳情見這篇

修正Source Code與SWC
幸好,上面那篇也有提到修正方法,使用Source Code的人,只要修正兩個地方:第一,打開com.facebook.graph.Facebook.as,在第612行那邊加入一行:
data.method = method;
data.funName = method;//只要加這行
if (callback != null) {
第二,打開com.facebook.graph.core.FacebookJSBridge.as,將第118行最後面的obj.method改為obj.funName,改完後變成:
obj = FB.JSON.parse( params );
cb = function( response ) { FBAS.getSwf().uiResponse( FB.JSON.stringify( response ), obj.funName ); }//改這行最後的obj.funName
FB.ui( obj, cb );
這樣Source Code就改完了。如果使用SWC的,就把它轉成SWC吧。如果嫌麻煩,可以下載我改過的

Facebook.ui():
接著就來看這個method。它有四個參數,第一個就是要呼叫的dialog名稱,例如feed。第二個參數就是呼叫時要傳送的data,就丟入一個Object,第三個就是callback function,第四個是顯示的方式,web版可以用page、iframe或popup。page是整頁轉過去,通常不會用;iframe就是在頁面上疊一個lightbox,我發現現在即使flash的wmode設為window它也可以正常疊在flash上面,不確定是新版flash player才可以還是怎樣;比較保險的做法就用popup彈出視窗來了。接著我們就來試一下Feed Dialog與OAuth Dialog,Friends Dialog我不知道用在哪種情況比較好,就先不管它了。

Feed Dialog
寫到這我已經沒耐性加太多介面了,就加個btnFeed Button,Click後執行固定的程式:
var data:Object = new Object();
data.link = "http://developers.facebook.com/docs/reference/dialogs/";
data.picture="http://fbrell.com/f8.jpg"
data.name = "這是name";
data.caption = "這是caption";
data.description = "這是description";
data.message = "這是message";
Facebook.ui("feed", data, requestHandler, "popup");
data可以指定哪些參數可以參考Feed Dialog的文件。另外callback function只會回傳一個Object參數,因此我們小改一下requestHandler:
private function requestHandler(result:Object, fail:Object = null):void 
讓第二個參數預設為null,這樣就可以通用了。這是我這邊偷懶,實際上我們當然會另外寫個function去處理。測試一下,如果點選"發佈"的話,可以看到result會回傳post_id;如果點選取消就不會有反應。

OAuth Dialog
這個Dialog的用處是登入時我們先要求幾個基本的extended permissions,等到有需要時,我們再跟user進一步去要求更多的permission,這樣可以避免user一開始看到一長串的permission要允許就卻步了。依照OAuth Dialog的文件,只要Facebook.ui()的第一個參數設為oauth,第二個參數data給他個屬性scope,值就是我們想要user與許的permission,以逗號隔開。但實測之後這樣完全沒用!即使不透過as,直接呼叫那網址也沒用。後來看到文件裡面有個Click here,有個測試頁,從那測試頁的網址發現,第一個參數必須傳permissions.request,第二個參數data必須設定perms屬性,這樣就可以了!!這個不知道以後Facebook會不會更正,請小心使用。我們就直接加個btnOAuth,Click後執行:
var data:Object = new Object();
data.perms = "email, read_friendlists, read_mailbox";
Facebook.ui("permissions.request", data, requestHandler, "popup");
這裡我們隨便設定幾個login時沒有允許的permission來測試。當彈出Dialog時點選同意或不允許,都會回傳session的資訊,差別我們可以從result.perms來查看,裡面會有我們要求的permission裡面,user有允許的permission。在實際應用上,我們可能希望先知道user有沒有與許過某個權限,如果有,就直接執行某功能,否則就先彈出OAuth Dialog,user同意後再進行該功能。雖然FacebookSession有個availablePermissions疑似可以用,不過實測之後一直都是null。我們可以自己來做這個功能,呼叫FQL查詢:
SELECT publish_stream,email FROM permissions WHERE uid = me()
欄位就把我們App.裡所有可能有的permission丟進去。回傳時那些欄位值等於1的就是有允許過的permission,把這些資訊儲存下來。每次要允許權限前就先查這個儲存下來的內容,而每次允許了新權限後再去更新這個內容,就可以了!

以上,應該已經把這套API重要的功能介紹完了,其他大概只有在使用IFrame App.時,可以使用Facebook.setCanvasAutoResize()與Facebook.setCanvasSize()可以設定IFrame的大小,對App.內容比較長時就可以試著用看看囉。結束!

上一篇文章:Facebook ActionScript Graph API ( 3 ) FQL、Old REST API以及picture

23 則留言:

  1. 我試出來了...你的用法是對的,跟我之前查到的不大一樣,感謝分享

    回覆刪除
  2. 嗯 ... 我依照大大文章調整那兩個Source code .. 還是不能用。

    大大可以提供改過的Source code嗎?

    回覆刪除
  3. 而且,連login的callback 似乎也不會發動!好詭異。

    回覆刪除
  4. To EastMoon:
    既然連該正常運作的login callback都有問題,那就不要急著去碰有bug的部分。請再回去看看第1篇,是不是每個該加的html部分都加了?官方的example裡有個FlashWebExample,也可以參考看看。把login部分解決,也許ui的部分就跟著解決了

    回覆刪除
  5. = =|| ... JS的實驗部分正常,FLASH部分都檢查過了,基本上沒加的話,連init都過不了。

    回覆刪除
  6. 其次,flash發login會出現兩次登入視窗。
    這在JS部分是因為,在FB.getLoginStatus(checkLoginStatus, false);

    第二參數設定為TRUE會強制出現兩次登入視窗。
    這部分在FLASH內部無法用參數控制。

    不知道大大會不會有同樣狀況。

    回覆刪除
  7. To EastMoon:
    不會耶.....login功能很正常

    回覆刪除
  8. = X = ... 哦!(暈倒)

    這段先跳過吧!感覺有很多人品問題,先做後面的。

    回覆刪除
  9. = x = ... 找出問題了!

    只能說很詭異,有空大大可以實驗看看。
    情況是,咱的init callback function中,在判斷無登入狀態後會直接呼叫

    Facebook.login(EventInitialFacebook);

    但是如果這樣寫,會造成連續發動兩次EventInitialFacebook,這函數同樣是init會呼叫。

    在經過檢查和分析後,假設了如果JS速度比FLASH慢,或因為不明原因,導致重複命令或命令過快發送。
    然後將原公式改成

    setTimeout( Facebook.login, 0, this.EventInitialFacebook );

    這樣就可以正常了 ... Orz ... 這算是人品問題了。

    回覆刪除
  10. To EastMoon:
    Facebook.login()其實不應該在init的callback function裡自動呼叫喔,應該先放個button,user click的時後才執行login,一方面也是確保popup window不會被瀏覽器擋下來

    回覆刪除
  11. 第二個問題,傳入值不對等。
    Orz ... 咱眼殘沒看到大大文章後面那句。

    回覆刪除
  12. 嗯!Popup阻擋問題是想過。
    只能說,也許有需要這樣用。

    至少個人看法,自動跳出登入和等待使用者登入是沒什麼差別的。

    雖然,可能會被SEO判斷成異常網站!!

    回覆刪除
  13. 版主你好,我想請問,用Facebook.ui popup出來的視窗樣式為何不是facebook的樣式,而是那個瀏覽器的樣式,而使用javascrip sdk 呼叫出來的樣式卻可以是facebook的樣式?
    麻煩指教..感恩!!

    回覆刪除
  14. To childnoah:
    文章裡面有提到了
    "第四個是顯示的方式,web版可以用page、iframe或popup。page是整頁轉過去,通常不會用;iframe就是在頁面上疊一個lightbox,我發現現在即使flash的wmode設為window它也可以正常疊在flash上面,不確定是新版flash player才可以還是怎樣;比較保險的做法就用popup彈出視窗來了。"

    回覆刪除
  15. 作者已經移除這則留言。

    回覆刪除
  16. 謝謝版主的回答..不好意思我沒看清楚,不過我還有個問題想請教,就是下載您提供的swc之後(感謝),雖然解決了Facebook.ui()的callback function問題, 但是卻發現在chrome底下,執行Facebook.init時,callback funcion不論成功失敗都不會執行(原本的swc可以),但在ie底下卻是正常的!不曉得是怎麼了..版大有這個狀況嗎?

    回覆刪除
  17. To childnoah:
    我使用都正常耶,目前也沒有其他人跟我說有問題,所以不是很清楚你發生的狀況

    回覆刪除
  18. 我後來又到adobe的官網看了一下,發現他有一行
    requires a name attribute passed in to support Chrome/Mozilla browsers
    並且他是用swfobject.embedSWF的方式,我原本是用embedSWF(似乎沒辦法指定attr),改成用wfobject.embedSWF加上name attribute就好了><

    回覆刪除
  19. 這個方法1.5.1是有效的

    不過1.6.1不知甚麼事依然不行.......

    回覆刪除
  20. To littleshell:
    請問你是指dialog的callback不會正常呼叫嗎?
    1.6.1我用的結果是已經可以正常呼叫了,不用像1.5版去改source code了

    回覆刪除
  21. permissions.request 无法成功 callback 是怎么回事 无论在as里还是js里都不行

    回覆刪除
  22. 可以請問一下
    那粉絲團的讚,當粉絲團讚掛在該網頁或flash裡時
    當點了讚的時候有辦法回傳訊息嗎?

    感謝!

    回覆刪除
    回覆
    1. To NoahLue:
      你需要的是Like Button:
      http://developers.facebook.com/docs/reference/plugins/like/
      然後使用Javascript事件:
      http://developers.facebook.com/docs/reference/javascript/FB.Event.subscribe/

      刪除