2010年1月4日 星期一

Facebook Flash Application開發心得(5) - 新版的streamPublish


Facebook的api在之前偷偷的有更新過了一次,但是flash的swc似乎仍然沒有變動,基本上影響不大。
其中發佈到個人塗鴉牆的部份,Facebook打算捨棄原本的template,從原本FB.Connect.showFeedDialog改成FB.Connect.streamPublish,這樣也好,不然每次要弄一個新的format就要去註冊一個新的template,這樣真的很麻煩。由於舊方法目前還可以繼續使用,但是為了將來著想,最好還是將舊有的程式改寫成新方法會比較好。
說是對flash影響不大的原因,因為雖然flash api裡原本就有com.facebook.commands.feed.PublishTemplatizedAction這個類別來處理發佈到塗鴉牆的工作,但是如果使用者沒有去允許這個app擁有完整publish_stream的權限的話(一般來說使用者很少主動允許這個權限),從flash發佈出去的東西是不會主動呈現在使用者的塗鴉牆上的,需要使用者回到自己的塗鴉牆再去點選一次才會真的出現,因此實用性並不大,我也是通常都使用javascript來處理發佈的動作。

因此在這裡記錄一下streamPublish該怎麼處理好了。
新版的發佈動作是藉由javascript api裡的FB.Connect.streamPublish來進行的。
streamPublish(String user_message, Object attachment, Object action_links, String target_id, String user_message_prompt, Function callback, Boolean auto_publish, String actor_id)
這些參數的意義分別為:
1. user_message:要講的話,通常是空的,由使用者自己填寫。
2. attachment:這是一個Object,就是原本的template,用來制定塗鴉牆上顯示的格式,attachment的寫法是重點,待會再提。
3. action_links:塗鴉牆上的連結,一樣是Object型態,通常是[{ "text": "點這邊!!", "href": "http://www.yourdomain.com/xxx.html"}];
4. target_id:要發佈到誰的塗鴉牆上,如果是要發佈到使用者自己的塗鴉牆的話,這個值就要帶空值。
5. user_message_prompt:會出現在user_message之前的一個開頭語,例如『正在想』、『覺得』…etc這些東西。
6. callback:對話窗關閉後會回call的function,如果不打算接受這個事件就不用管。
7. auto_publish:如果使用者已經同意publish_stream的權限且auto_publish是帶true的話,那麼使用者將不會看到有對話窗跳出來,訊息會直接出現在塗鴉牆上。(個人十分討厭這種作法)
8. actor_id:這好像是粉絲頁面用的,可以選擇直接發佈到粉絲頁,但前提是這個使用者是該粉絲頁的管理者。


看起來是很簡單明瞭了。
所以主要的重點還是在attachment。其實attachment跟以前的template差別不大,分別只在於以前的template先制定好了『格式』,現在的attachment則是隨時可以帶入不同的Object,比較活。
官方wiki對於attachment的解說請參考這個網址
http://wiki.developers.facebook.com/index.php/Attachment_%28Streams%29

通常attachment會具有以下幾個properties:
1. name:就是主旨。
2. href:主旨點下去會連結的網址,通常是app或是某活動、官網的網址。
3. caption:跟name不一樣,也跟下面的description不一樣,這個caption通常會寫出誰誰誰做了什麼事,在caption裡加上{*actor*}的話這一串字串就會自動被取代成使用者的名稱,例如:『{*actor*}剛剛做了心理測驗』,出來的結果就會是『Jason剛剛做了心理測驗』
4. description:嗯,這個就是一大堆文字了,可以當成作文去寫,通常facebook裡那些心理測驗在解釋測驗結果的那一大堆話就是塞在這個屬性裡。
5. properties:這屬性我還沒實作過,功能還不明,跳過。
6. media:除了description以外最多人用也最有興趣的就是這個屬性了,這是一個陣列,定義了所有會出現的圖或flash或聲音,全都塞在這個陣列裡,陣列裡放的是Object,每一個Object會有三個屬性:type,src,href。type定義是什麼媒體,有image、flash及mp3三種,src則是這個媒體所在的網址,href就是點了之後會連到哪。所以media應該會是類似這樣的型態:[{'type': 'image', 'src': 'http://icanhascheezburger.files.wordpress.com/2009/03/funny-pictures-kitten-finished-his-milk-and-wants-a-cookie.jpg', 'href': 'http://icanhascheezburger.com/2009/03/30/funny-pictures-awlll-gone-cookie-now/'}, {'type': 'image', 'src': 'http://photos.icanhascheezburger.com/completestore/2009/1/18/128768048603560273.jpg', 'href': 'http://ihasahotdog.com/upcoming/?pid=20869'}]
7. 剩下的像comments_xid及自定義屬性,好像都是要用再更深入的機制上才會用到的,目前我也沒實作過,因此一樣跳過。
基本上attachment最常被使用到的就是這幾個屬性了,差不多瞭解了之後就可以很快的發佈屬於自己的塗鴉牆。


接下來,如何從Flash去呼叫FB.Connect.streamPublish,不用說一定是透過ExternalInterface,需要注意的是,因為attachment是一個Object,我試過直接用Flash丟Object出來給js,結果是失敗的,雖然js也是收到一個Object,但是其實這個Object已經不是原本的Object了,所以要嘛就是把要發佈的attachment先在js裡寫好,但是這麼一來整個code又變得很不活,也無法類別化,所以我都會改採另外一種方式:JSON。
在Flash裡,先產生相對映的Object,然後藉由Adobe as3corelib裡面com.adobe.serialization.json的package,JSONEncoder類別將Object轉換成JSON的字串後,用字串的方式傳遞給js,js裡再還原成Object就可以了,js裡字串還原成JSON的方法可以直接用eval,或是使用JSON.js來做parsing的動作(JSON.js可在此下載http://www.json.org/js.html)。
這樣做的好處是可以在flash裡動態的隨時產生不同的attachment,視不同的狀況發佈不同的塗鴉牆,比較靈活,js也不需要因為每個專案而再重新編寫。