主要な処理と初期化
「LoginButton」クラスは、標準の「UIButton」を以下の内容でちょっとカスタマイズした、非常に単純なクラスです。
- 「UIButton」クラスを継承
- 「loggedIn」プロパティで、ログイン中か否かの状態を保持
- 「setLoginStatus」メソッドでログイン状態を変更し、それに応じたログイン/ログアウトボタンの画像をセット
主要な処理は「HelloFbViewController」で行っています。カスタムURLスキームによって起動されたときのURLの受け取りなどは「HelloFbAppDelegate」で行います。
Facebookオブジェクトは、ログインや「Extended Permissions」(OAuth APIで使う認証時の細かい権限設定)のリクエストからAPIの呼び出しまで、あらゆるFacebook連携を担当します。それらの処理の終了をハンドルする側のクラスは、処理の種類に応じたデリゲートプロトコルを実装する必要があります。
本稿で、「HelloFbViewController」は、「FBSessionDelegate」「FBRequestDelegate」の2つのプロトコルを実装しています。「FBSessionDelegate」はログイン処理に関するイベント通知(ログインの完了・失敗・中止)を受け取るデリゲート、「FBRequestDelegate」はAPIリクエストに関するイベント通知を受け取るデリゲートです。
「HelloFbViewController」は、初期化時、Facebookオブジェクトを生成し、自らをデリゲートとしてセットしています。
- (void)viewDidLoad { [super viewDidLoad]; facebook = [[Facebook alloc] initWithAppId: APPLICATION_ID]; [facebook setSessionDelegate:self]; }
Facebookへのログイン処理
ログイン/ログアウトボタンを押したときに呼ばれる「login」メソッドでは、ログイン状態(「loginButton.loggedIn」の値)によって分岐し、ログインしていなければログイン処理を、ログインしていればログアウト処理を行います。
ログイン処理を行う「Facebook.authorize」メソッドには、必要なExtended Permissionsの種類を配列で渡します。
-(IBAction) login: (id) sender { if (!loginButton.loggedIn) { NSArray *permissions = [[NSArray arrayWithObjects: @"read_stream",@"publish_stream",nil] retain]; [facebook authorize:permissions delegate:self]; } else { [facebook logout:self]; } }
「authorize」メソッドでは、認証用のURLを生成し、それをSafariで開く処理が行われます。これによって、いったんアプリケーションはバックグラウンドにまわります(iOS 4.0より古いOSの場合、アプリケーションは終了します)。
Safariで開かれたページで、ユーザーはログインを行います。それが終了すると、以下のようなURLにリダイレクトされます。
fb【アプリケーションID】://authorize/#access_token=【アクセストークン】&expires_in=0
このURLはSafariでは開かれず、アプリケーションのInfo.plistで定義した独自スキームによって、アプリケーションで開かれます。
カスタムURLスキーム(fb【アプリケーションID】)によってアプリケーションが起動したときに呼ばれるのが、「HelloFbAppDelegate」クラスの「handleOpenURL」メソッドです。このURLには、アプリケーションからFacebookのAPIを利用するのに必要なアクセストークンが入っています。
これを、Facebookオブジェクト(「HelloFbViewController」のプロパティ)に渡します。
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url { NSLog(@"HelloFbAppDelegate.handleOpenURL url=%@", url); return [[viewController facebook] handleOpenURL:url]; }
Facebookクラスの「handleOpenURL」メソッドにURLを渡すと、Facebookオブジェクトは、そのURLに含まれるアクセストークンを取得し、あらゆるAPIを呼び出す準備が完了します。そのときに呼ばれるのが、Facebookオブジェクト「sessionDelegate」として渡したインスタンスの「fbDidLogin」メソッドです。
なお、ログインに失敗した場合や、ユーザーが拒否した場合は、「fbDidNotLogin」メソッドが呼ばれます。
ログイン成功・ログイン失敗・ログアウトによってログイン状態が変わったときは、「LoginButton」インスタンスの「setLoginStatus」メソッドを呼び出し、ボタンの状態を変更します。次の個所で、その処理を行っています。
-(void) setLoginStatus: (BOOL) loginStatus { loggedIn = loginStatus; [self setImage:[UIImage imageNamed:(loggedIn)?@"LogoutNormal.png":@"LoginNormal.png"] forState:UIControlStateNormal]; }
ここまでが、ログイン処理です。
Graph APIを呼び出しユーザーのプロフィールを取得
次は、「Get my profile」ボタンを押したときにGraph APIを呼び出し、ユーザーのプロフィールを取得する個所です。
-(IBAction) getMyProfile: (id) sender{ [facebook requestWithGraphPath:@"me" andDelegate:self]; }
Facebookクラスの「requestWithGraphPath」メソッドは、Graph APIを利用するためのメソッドです。
ここでは、「me」というパスを指定してGETリクエストを送っています(実際には、「https://graph.facebook.com/me」をリクエストしています)。このメソッドには、パラメタ「andDelegate」として、「FBRequestDelegate」を実装したデリゲートを渡します。
「FBRequestDelegate」が実装すべきメソッドは3つ。「didReceiveResponse」「didLoad」「didFailWithError」です。
無事にGraph APIのレスポンスが返ってくると、「didLoad」メソッドが呼ばれます。「result」に入っているのは、「NSArray」型、もしくは「NSDictionary」型のオブジェクトです。
JSON形式のレスポンスはSDKによってパースされ、その内容が配列であれば「NSArray」に、そうでない場合には「NSDictionary」に変換されます。
- (void)request:(FBRequest *)request didLoad:(id)result { NSLog(@"HelloFbViewController.didLoad"); NSDictionary *myProfile = (NSDictionary *) result; [profileLabel setText: [myProfile objectForKey:@"name"]]; }
Safariではなくダイアログを使うOAuth認証
ログインやExtended Permissionsの許可を行うページは、Safariで開かず、アプリケーション内のポップアップダイアログとしても表示できます。
先ほど「Facebook.authorize」を使っていた部分を少し書き換えて、ダイアログ式のログインを実装してみましょう。アプリケーション内にダイアログを表示する場合、先ほどのSafariで必要だったカスタムスキームの設定はいりません。
「HelloFbViewController.m」の「login」メソッドを、次のように変更します。
NSArray *permissions = [[NSArray arrayWithObjects: @"read_stream",@"publish_stream",nil] retain]; [facebook authorize:permissions delegate:self];
NSMutableDictionary *params = [[NSMutableDictionary alloc] initWithObjectsAndKeys: APPLICATION_ID,@"client_id", @"touch", @"display", @"publish_stream,read_stream,offline_access", @"scope", nil]; [facebook dialog:@"oauth" andParams:params andDelegate:self];
「FB.dialog」メソッドを利用するときは、パラメタのKey-Valueのペアを「NSMutableDictionary」(「NSDictionary」ではないので注意)に入れて渡します。
ここで渡すパラメータについては、詳しくは「OAuth Dialog - Facebook開発者」をご覧ください。
「Facebook.dialog」メソッドは、アプリケーション内でダイアログをポップアップさせて処理を行うメソッドです。JavaScript SDKには「FB.ui」がありますが、そのiOS版のようなものです。
ダイアログに関するイベント通知を受け取るため、「FBDialogDelegate」プロトコルを実装したクラスのインスタンスを渡します。「HelloFbViewController」クラスの宣言部分を、次のように変更します。
@interface HelloFbViewController : UIViewController <FBSessionDelegate, FBRequestDelegate, FBDialogDelegate> {
ポップアップダイアログによってログインが終了したら、「FBDialogDelegate」に定義された各種メソッドが呼ばれる他、「FBSessionDelegate」の各種メソッド(「fbDidLogin」「fbDidNotLogin」「fbDidLogout」)も呼ばれます。
ポップアップダイアログを使う場合でも、ログイン処理の終了をハンドルするのは、Safariを使う場合と同様、「fbDidLogin」「fbDidNotLogin」「fbDidLogout」を使います。
これを実行すると、以下の画面のようなダイアログが出ます。
後編は、Wall投稿機能を作りLegacy REST APIを使う
前編では、Facebook SDK for iOS利用をするための準備を行い、OAuthのAPIを使ってログインし、ログインができたらGraph APIを使ってユーザーのプロフィールを取得するという簡単なアプリケーションを作ってみました。
次回後編では、Graph APIでPOSTを行う例として、自分のWallへの投稿を行います。また、「少し古いけど、これでしか使えない機能」がある「Legacy REST API(は「Old REST API」という呼称も使われている)」も利用します。
本企画は、アスキー・メディアワークス刊行の『facebookアプリケーション開発ガイド』のうち「第15章 iOSアプリケーションの開発」の一部を、同社の許可を得て転載するものです。
なお、 Web記事として転載するに当たり、@IT向けに編集し若干表現を変更している点があります。その点ご了承ください。
著者紹介
株式会社鳥人間
郷田まり子(ごうだまりこ)
1980年東京生まれ、プログラマ。建築製図から人工衛星観測まで、ユーザーに驚きをもたらす数々のWebサービスを実装してきたs。現在、創業二年社員二名の株式会社鳥人間にて、主にWeb開発案件を手掛ける。本業の傍ら、目新しくて面白そうな物にはとりあえず飛びついてハックしている
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
- OAuth 2.0でWebサービスの利用方法はどう変わるか
ソーシャルAPI活用に必須の“OAuth”の基礎知識 - 無料クラウドでできるFacebookアプリ開発入門
- これぞソーシャル?Android用Facebookの評価、5斬
女子部が斬る! Androidアプリ評価コメント(4) - 知らないと損するFacebookファンページの作り方
Facebookのプロモーション活用術“超”入門 - OAuth 2.0を使うソーシャルなAndroidアプリの作り方
ネイティブアプリで実践! mixi Graph API活用法 - OAuthでバーコード情報Twitter投稿iPhoneアプリ
Web技術でネイティブアプリを作れるTitanium(3)