------------------------------------------------------
※ 注意
現在配布されているFacebook iOS SDKは認証に原則としてSingle Sign-On方式を採用しているため、この記事で記述されている手順とは必要な手順が異なります。
くわしくはFacebookのiOS Tutorialをご覧下さい。
------------------------------------------------------
ただ、認証やデリゲートまわりでややこしいところがあるので簡単にまとめておきます。
個人的な理由で画像のアップロードの流れを書いてみます。
画像のアップロード以外でも
認証 & パーミッション付与 > Graph API呼び出し
という流れは基本的に一緒です。
GitHub - facebook/facebook-ios-sdk
https://github.com/facebook/facebook-ios-sdk
iOS SDKのセットアップなどは上のGitHubのページに詳しく説明されているのでそちらをどうぞ。
FacebookのアプリページでAPI KeyとSecret Keyを確認しておきます。
static NSString *kFacebookAPIKey = @"API KEY";
static NSString *kFacebookSecretKey = @"SECRETI KEY";とりあえずヘッダーファイルはこんな感じです。
@interface FacebookViewController : UIViewController
<FBRequestDelegate, FBSessionDelegate, FBDialogDelegate>
{
FBSession *facebookSession;
FBRequest *facebookUploadRequest;
}
@property (nonatomic, retain) FBSession *facebookSession;
@property (nonatomic, retain) FBRequest *facebookUploadRequest;
- (void)upload:(NSData *)uploadImageData;
@endまずはFBSession を初期化して認証をします。FBSessionを認証やAPIの呼び出しで使い回します。
@implementation FacebookViewController
- (id)init {
self = [super init];
if (self != nil)
{
self.facebookSession = [FBSession sessionForApplication:kFacebookAPIKey
secret:kFacebookSecretKey
delegate:self];
// 認証済みかどうか確認
// 認証済の場合 FBSessionDelegate の session:didLogin: が呼ばれる。
[facebookSession resume];
}
return self;
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if (![facebookSession isConnected])
{
// 未ログインの場合はログインダイアログを表示する
// ダイアログ内のアクションは FBSessionDelegate でハンドリングする。
FBLoginDialog *dialog = [[FBLoginDialog alloc] initWithSession:facebookSession];
[dialog show];
[dialog release];
}
}
@endログイン/ログアウト時の処理はFBSessionDelegateでハンドリングします。
#pragma mark -
#pragma mark FBSessionDelegate
- (void)session:(FBSession*)session didLogin:(FBUID)uid {
// ログイン成功時に呼ばれる。
if (![[NSUserDefaults standardUserDefaults] boolForKey:@"has_facebook_photo_upload_perm"])
{
// 画像アップロードには「写真」のパーミッションが必要。
// もしパーミッションが与えられていない場合はパーミッションを確認するダイアログを開く。
FBPermissionDialog * dialog;
dialog = [[[FBPermissionDialog alloc] initWithSession:facebookSession] autorelease];
dialog.delegate = self;
dialog.permission = @"photo_upload,user_photos"; // 「写真」関連のパーミッションを指定
[dialog show];
}
}
- (void)sessionDidNotLogin:(FBSession*)session {
// ログインせずにダイアログを閉じた場合に呼ばれる。
}
- (void)session:(FBSession*)session willLogout:(FBUID)uid {
// ログアウトする前に呼ばれる
}
- (void)sessionDidLogout:(FBSession*)session {
// ログアウト後に呼ばれる
}パーミッションの処理はFBDialogDelegateでハンドリングします。
#pragma mark -
#pragma mark FBDialogDelegate
- (void)dialogDidSucceed:(FBDialog*)dialog
{
// パーミッション与えられた場合
[[NSUserDefaults standardUserDefaults] setBool:YES
forKey:@"has_facebook_photo_upload_perm"];
}認証が通ってパーミッション(写真)があれば画像のアップロードができます。
- (void)upload:(NSData *)uploadImageData
{
self.facebookUploadRequest = [FBRequest requestWithDelegate:self];
[facebookUploadRequest call:@"facebook.photos.upload"
params:params
dataParam:uploadImageData];
}アップロード処理のハンドリングはFBRequestDelegateでおこないます。
#pragma mark -
#pragma mark FBRequestDelegate
- (void)requestLoading:(FBRequest*)request {
// リクエスト送信直前に呼ばれる
}
- (void)request:(FBRequest*)request didReceiveResponse:(NSURLResponse*)response {
// サーバーがレスポンスデータを返し始める時に呼ばれる
}
- (void)request:(FBRequest*)request didLoad:(id)result {
// サーバーがレスポンスを返し、レスポンスデータがオブジェクトにパースされた時に呼ばれる
}
- (void)request:(FBRequest*)request didFailWithError:(NSError*)error {
// エラー時に呼ばれる
}
- (void)requestWasCancelled:(FBRequest*)request {
// キャンセル時に呼ばれる
}これで画像がFacebookに送信されます。
ただ、FBRequestDelegateにはアップロードの進捗度を通知してくれるものがないので、このままではプログレスバーを表示することができません。
ちょっと小細工してアップロードの進捗度をチェックできるようにしてみます。
FBRequestは内部的にNSURLConnectionを利用してサーバーと通信しています。
NSURLConnectionには connection:didSendBodyData:totalBytesWritten:totalBytesExpectedToWrite: というデリゲートメソッドがあって、こいつを利用できればアップロードの進捗度が確認できます。
FBRequestのサブクラスを作ったり、ライブラリのコードを直接改変したり(!!)、方法はいくつかあると思うのですが
ここではObjective-Cのカテゴリを使って FBRequest に connection:didSendBodyData:totalBytesWritten:totalBytesExpectedToWrite: メソッドを追加してみます。
@interface FBRequest (Upload)
@end
@implementation FBRequest (Upload)
- (void)connection:(NSURLConnection *)connection
didSendBodyData:(NSInteger)bytesWritten
totalBytesWritten:(NSInteger)totalBytesWritten
totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite
{
FacebookViewController *vc = (FacebookViewController *)_delegate;
[vc didSendBodyData:bytesWritten
totalBytesWritten:totalBytesWritten
totalBytesExpectedToWrite:totalBytesExpectedToWrite];
}
@end@implementation FacebookViewController
- (void)didSendBodyData:(NSInteger)bytesWritten
totalBytesWritten:(NSInteger)totalBytesWritten
totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite
{
NSLog(@"bytesWritten : %d, totalBytesWritten : %d, totalBytesExpectedToWrite: %d",
bytesWritten , totalBytesWritten, totalBytesExpectedToWrite);
}
@end






0 comments:
コメントを投稿