2012年5月10日木曜日

Chatter APIにまつわる愚痴

会社で作業していると目的のAPIがなかなか出てこない。自宅で作業していると同じGoogle先生を使っているのに「FeedItem」でサクッとREST APIが出てくる。

何ででしょう? 昨日30分ぐらい「あれ、Chatterのメッセージにコメントがいくつついているかを返すメンバーって何だっけ? Comments?」ってGoogle先生をお供にさまよっていたんですが…今検索したら一発でFeedItemのCommentCountが出てきました。

見つかれば文句ないんですけどねぇ…。

それにしても個人で提出したiPhoneアプリ。今までの経験から「審査待ちまですくなくとも1週間」ってのはわかっているんですが、それにしても待ち遠しい。

2012年5月6日日曜日

Native iOSアプリをChatterの「いいね!」に対応

■FourChatter絶賛改良中■

Chatter上の文言をサクっと検索する倉橋屋謹製アプリFourChatterを改良してます。今更ですが。主な改良のポイントは以下の2点:
  1. iPad対応
  2. 「いいね!」の実装
iPad対応は、同じGUIそのままならそんなに苦労はないけれど、このFourChatterは「iPhoneの向きを変えるだけでキーワードを切り替えて検索できる」ってのがウリです(電車の中ではちょっと恥ずかしいけどね)。が。iPadで向きを変えるのは結構ウザい。というよりも、五十肩の私にはしんどい。というわけで、Segmented Controlを導入しました。

…iPhone版もこれでいいんじゃね? Segmented Controlなら4つに限らなくても良いんじゃない??という声もありますが。


■「いいね!」の実装■

Chatterの「いいね!」はFeedLikeというオブジェクトを使ってます。NewsFeedまたはFeedCommentへのto one relationshipになっていて

  • CreatedByID - 「いいね!」をクリックしたユーザのID
  • FeedItemID - 「いいね!」の対象となるNews Feed ID
  • FeedEntityID - 「いいね!」の対象となるFeedまたはCommentのID
  • InsertedById - このオブジェクトを作ったユーザのID
もともとFeedEntityIDはなかったと思うけど、最近FeedCommentへの「いいね!」がサポートされたことにともなって追加された、ような気がします。


■まず「いいね!」はこんな感じ■

SFRestRequest *requestInsert;

NSString *fId = [feed objectForKey:@"Id"];

NSDictionary* dic = [NSDictionary 
    dictionaryWithObjectsAndKeys:fId, @"FeedItemId", nil];

requestInsert = [[SFRestAPI sharedInstance] 
    requestForCreateWithObjectType:@"FeedLike" fields:dic];
[[SFRestAPI sharedInstance] send:requestInsert delegate:self];

これでOK。実行結果は例によって以下が呼び出されます。

- (void)request:(SFRestRequest *)request didLoadResponse:(id)jsonResponse ;
- (void)request:(SFRestRequest*)request didFailLoadWithError:(NSError*)error ;
- (void)requestDidCancelLoad:(SFRestRequest *)request ;
- (void)requestDidTimeout:(SFRestRequest *)request ;

要するに「いいね!」をしたいfeedのidを"FeedItemId"にセットしたNSDictionaryを用意して、それをFeedLikeとしてinsertするだけです。


■いいね!を取り消すには■

上記で作ったFeedLikeを削除します。最初、SELECTで該当するFeedItemIDとCreatedByIDを持つFeedLikeを検索しようとしたのですが、FeedLikeは直接fetchできないというエラーが出ました。ので、NewsFeedをfetchする時に、一緒にFeedLikesもfetchしておきます。

NSString *strQuery = [NSString stringWithFormat:
     @"SELECT Id, (SELECT Id, CreatedById From FeedLikes) 
       From NewsFeed Where Id = '%@' Limit 1", fId];

で、FeedLikesの中から自分のUser IDと同じCreatedByIdを持つFeedLikeを探し出して消します。

fId = (NSString *)[feedLike objectForKey:@"Id"];
requestDeleteLike = [[SFRestAPI sharedInstance] 
    requestForDeleteWithObjectType:@"FeedLike" objectId:fId];
[[SFRestAPI sharedInstance] send:requestDeleteLike delegate:self];

とても簡単。なお、自分以外のユーザの「いいね!」を消せるかどうかは試してません。

2012年5月5日土曜日

Force.com SDK iOS - ログインUser IDの取得

小ネタですが。

Force.com mobile SDK for iOS Nativeアプリで、ログインしているユーザのIDを取得するには、

AppDelegate *app = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSString *userId = [[[app coordinator] credentials] userId];

てな感じで。SFOAuthCoordinatorSFOAuthCredentialsは、他にも使えるメンバーを持っているのでリファレンスをブックマークしておくと良です。

で。上記で取得したのは15文字のuser idなので、18文字のCreatedByIDと比較する場合は

if ([createdById hasPrefix:userId]) { ... }

と書かないとダメです。

--

余談ですが。

考え事をしながら引き出しから爪切りを取り出し、床に広げた新聞紙に座り込んでさて爪を切ろうかと思ったらUSBメモリだった。そんな経験をした人はこの世の中に何人ぐらいいらっしゃるのでしょうか。
色とサイズは似ているけど…