Twitter/Facebookのアカウントで認証して、アプリからタイムライン/フィードに投稿する[#8]〜Facebookのフィード投稿〜
メッセージの投稿
これが投稿の基本パターンになります。
//例によって以下の項目をインポートする #import <Parse/Parse.h> #import <FacebookSDK/FacebookSDK.h> #import <AFNetworking/AFNetworking.h> -(void)fbpost:(NSString *)message{ //プライバシー(公開範囲)の設定 NSDictionary* privacy = @{@"value":@"CUSTOM", @"friends":@"ALL_FRIENDS"}; NSMutableDictionary* params = @{@"message":message, @"privacy":[dictionary_to_JSON dictionaryToJSON:privacy], }.mutableCopy; //FBリクエストの作成 FBRequest *request = [FBRequest requestWithGraphPath:@"me/feed" parameters:params HTTPMethod:@"POST"]; //コネクションをセットしてすぐキャンセル→NSMutableURLRequestを生成するため??? //ここはStack Overflowの受け売り FBRequestConnection *requestConnection = [request startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) { }]; [requestConnection cancel]; //リクエストの作成 NSMutableURLRequest *urlRequest = requestConnection.urlRequest; //送信! AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:urlRequest]; [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { // Do your success callback. NSLog(@"success!"); } failure:^(AFHTTPRequestOperation *operation, NSError *error) { // Do your failure callback. NSLog(@"fail!"); NSLog(@"operation=%@",operation); NSLog(@"error=%@",error); }]; //進捗状況の確認 [operation setUploadProgressBlock:^(NSUInteger bytesWritten, long totalBytesWritten, long totalBytesExpectedToWrite) { NSLog(@"Sent %ld of %ld bytes", totalBytesWritten, totalBytesExpectedToWrite); }]; [[NSOperationQueue mainQueue] addOperation:operation]; }
プライバシーの設定はJSON形式で埋め込む必要があるため何らかの方法でNSDictionary→JSONの変換をする必要があります。
ここではdictionaryToJSONというクラスメソッドで変換をするという想定で記述しています。
NSMutableURLRequestの設定部分はStack Overflowを参考にしました。
テキストだけじゃなくて画像を添付する場合は以下のように書き換えます。
画像添付の場合
NSMutableDictionary* params = @{@"message":message, @"privacy":[dictionary_to_JSON dictionaryToJSON:privacy], @"picture":data, }.mutableCopy; //FBリクエストの作成 FBRequest *request = [FBRequest requestWithGraphPath:@"me/photos" parameters:params HTTPMethod:@"POST"];
paramsのところにpicture
を追加し、NSData形式の画像データを指定します。
また、requestのme/feed
がme/photos
にかわります。
動画の添付の場合
NSMutableDictionary* params = @{@"message":message, @"privacy":[dictionary_to_JSON dictionaryToJSON:privacy], @"movie.mp4":data, @"title":@"タイトル", }.mutableCopy; //FBリクエストの作成 FBRequest *request = [FBRequest requestWithGraphPath:@"me/videos" parameters:params HTTPMethod:@"POST"];
動画の場合は同じくNSData形式でデータを渡すことには変わりないのですが、keyが動画のファイル名になるようです。
あとは、動画のタイトルが付加できます。
一方、requestの方はme/videos
となります。
facebookの資料としては本家のドキュメントのほか、こちらのサイトは日本語での解説なので分かりやすかったです。
Twitter/Facebookのアカウントで認証して、アプリからタイムライン/フィードに投稿する[#7]〜Facebookアカウントでの認証〜
基本的な設定
ここはすでに前回のTwitterアカウントでの認証で行っているので省略
Facebook認証
-(void)facebook{ // パーミッション // タイムラインにユーザーに代わって書き込むにはpublish_streamが必要 NSArray *permissionsArray = @[ @"user_about_me", @"user_relationships", @"user_birthday", @"user_location",@"publish_stream"]; // Facebook アカウントを使ってログイン [PFFacebookUtils logInWithPermissions:permissionsArray block:^(PFUser *user, NSError *error) { if (!user) { if (!error) { NSLog(@"Facebook ログインをユーザーがキャンセル"); } else { NSLog(@"Facebook ログイン中にエラーが発生: %@", error); } } else if (user.isNew) { NSLog(@"Facebook サインアップ & ログイン完了!"); } else { NSLog(@"Facebook ログイン完了!"); } NSLog(@"sessionToken=%@",user.sessionToken); NSLog(@"isNew=%d",user.isNew); NSLog(@"username=%@",user.username); }]; }
メソッド名がちょっと違うくらいで、Twitterの時とよく似ていますが、
Facebookの場合はNSArray形式でパーミッション設定があります。
ここに列挙している項目に対してユーザーにお伺いを立て、ユーザーが許可するとアクセスが可能になります。
パーミッション設定の詳細はこちら。
続いて、基本的なパラメータを取得してみます。
//facebookの各種データ取得 -(void)info{ FBRequest *request = [FBRequest requestForMe]; // Send request to Facebook [request startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) { if (!error) { // result is a dictionary with the user's Facebook data NSDictionary *userData = (NSDictionary *)result; NSString *facebookID = userData[@"id"]; NSString *name = userData[@"name"]; NSString *location = userData[@"location"][@"name"]; NSString *gender = userData[@"gender"]; NSString *birthday = userData[@"birthday"]; NSString *relationship = userData[@"relationship_status"]; NSURL *pictureURL = [NSURL URLWithString:[NSString stringWithFormat:@"https://graph.facebook.com/%@/picture?type=large&return_ssl_resources=1", facebookID]]; // Now add the data to the UI elements // ... NSLog(@"name=%@",name); NSLog(@"location=%@",location); NSLog(@"gender=%@",gender); NSLog(@"birthday=%@",birthday); NSLog(@"relation=%@",relationship); NSLog(@"pict=%@",pictureURL); } }]; }
これはParseのドキュメントからそのまま拝借したソースなんですが、これで基本的な項目が取得できます。
これで、TwitterとFacebookの認証と情報取得ができました。
次回以降では実際にユーザーに代わってアプリから投稿を行う部分に入って行きます。
Twitter/Facebookのアカウントで認証して、アプリからタイムライン/フィードに投稿する[#6]〜Twitterのタイムライン投稿〜
メッセージのみを投稿
//以下の項目をインポートしておく #import <Parse/Parse.h> #import <FacebookSDK/FacebookSDK.h> #import <AFNetworking/AFNetworking.h> //twitter 文章のみ投稿 -(void)tweet:(NSString *)message { //URLとパラメータを生成 NSString* url = @"https://api.twitter.com/1.1/statuses/update.json"; NSMutableDictionary* param = @{@"status":message}.mutableCopy; //リクエストにメソッド(POST)、URL、パラメータを設定 NSMutableURLRequest *tweetRequest = [[AFHTTPRequestSerializer serializer] requestWithMethod:@"POST" URLString:url parameters:param error:nil]; //認証 [[PFTwitterUtils twitter] signRequest:tweetRequest]; //operationの定義 AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:tweetRequest]; //実行 [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject){ NSLog(@"success!"); }failure:^(AFHTTPRequestOperation *operation, NSError *error){ NSLog(@"fail!"); NSLog(@"operation=%@",operation); NSLog(@"error=%@",error); }]; [[NSOperationQueue mainQueue] addOperation:operation]; }
メッセージのみの投稿はこんな感じです。
簡単ですね。
画像とメッセージを投稿
//以下の項目をインポートしておく #import <Parse/Parse.h> #import <FacebookSDK/FacebookSDK.h> #import <AFNetworking/AFNetworking.h> //twitter 画像添付バージョン -(void)tweetWithImage:(NSString *)message image:(UIImage *)image{ //受け取ったUIImageをNSData形式に変換 NSData* data = UIImageJPEGRepresentation(image, 1.0); // AFHTTPRequestOperationManagerの定義 AFHTTPRequestOperationManager* manager = [AFHTTPRequestOperationManager manager]; manager.responseSerializer = [AFHTTPResponseSerializer serializer]; //URLとパラメータを生成 NSString* url = @"https://api.twitter.com/1.1/statuses/update_with_media.json"; NSMutableDictionary* param = @{@"status":message}.mutableCopy; //リクエストにメソッド(POST)、URL、パラメータ、添付画像を設定 NSMutableURLRequest *tweetRequest = [manager.requestSerializer multipartFormRequestWithMethod:@"POST" URLString:url parameters:param constructingBodyWithBlock:^(id<AFMultipartFormData> formData){ [formData appendPartWithFormData:data name:@"media[]"]; } error:NULL]; //認証! [[PFTwitterUtils twitter] signRequest:tweetRequest]; //送信! AFHTTPRequestOperation *operation = [manager HTTPRequestOperationWithRequest:tweetRequest success:^(AFHTTPRequestOperation* operation, id responseObject){ NSLog(@"success!"); }failure:^(AFHTTPRequestOperation* operation, NSError* error){ NSLog(@"operation=%@",operation); NSLog(@"eror=%@",error); }]; // データを送信する度に実行される処理を設定する //プログレスバーなど [operation setUploadProgressBlock:^(NSUInteger bytesWritten, long totalBytesWritten, long totalBytesExpectedToWrite) { // アップロード中の進捗状況をコンソールに表示する NSLog(@"bytesWritten: %@, totalBytesWritten: %@, totalBytesExpectedToWrite: %@, progress: %@", @(bytesWritten), @(totalBytesWritten), @(totalBytesExpectedToWrite), @((float)totalBytesWritten / totalBytesExpectedToWrite)); }]; [manager.operationQueue addOperation:operation]; }
画像添付の場合も基本的なパターンは同じです。
リクエストの設定で画像を設定しているところと、画像送信で少し待たされることを想定して進捗を取得できるようにしています。
あと、ビルドの環境によってはlongがlong longになるかもしれません。
TwitterのAPIに関しては本家のドキュメントを参考にするか、 最終的には本家にリンクされているのですが、こちらのサイトがよくまとまっていてわかりやすかったです。
Twitter/Facebookのアカウントで認証して、アプリからタイムライン/フィードに投稿する[#5]〜Twitterアカウントでの認証〜
基本的な設定
//ParseとFacebookのSDKをimport #import <Parse/Parse.h> #import <FacebookSDK/FacebookSDK.h> //アプリ起動時の設定 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ //Parse初期設定 [Parse setApplicationId:@"ParseのアプリケーションID" clientKey:@"Parseのクライアントキー"]; [PFUser enableAutomaticUser]; PFACL *defaultACL = [PFACL ACL]; [PFACL setDefaultACL:defaultACL withAccessForCurrentUser:YES]; // Facebook [PFFacebookUtils initializeFacebook]; //Twitter [PFTwitterUtils initializeWithConsumerKey:@"twitterのConsumerKey" consumerSecret:@"twitterのconsumerSecret"]; return YES; } - (void)applicationDidBecomeActive:(UIApplication *)application { //この行を追加 [FBAppCall handleDidBecomeActiveWithSession:[PFFacebookUtils session]]; } //このメソッドを追加 - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { return [FBAppCall handleOpenURL:url sourceApplication:sourceApplication withSession:[PFFacebookUtils session]]; }
基本的な設定をAppDelegateで行います。
Facebookの固有情報はここではなくてinfo.plistで設定します。
FacebookAppID
という項目を作成し、ここにFacebookのアプリケーションIDを設定。
FacebookDisplayName
という項目を作成し、ここにDisplay Nameを設定。
あとはURLスキームの項目を作成し上記のアプリケーションIDの先頭にfbをつけたモノを設定します。(例:アプリケーションIDが1234567890の場合fb1234567890をセット)
Twitter認証
//認証を行うviewControllerで以下をインポート #import <Parse/Parse.h> #import <FacebookSDK/FacebookSDK.h> #import <AFNetworking/AFNetworking.h> -(void)twitter{ [PFTwitterUtils logInWithBlock:^(PFUser *user, NSError *error) { if (!user) { if (!error) { NSLog(@"Twitter ログインをユーザーがキャンセル"); } else { NSLog(@"Twitter ログイン中にエラーが発生: %@", error); } } else if (user.isNew) { NSLog(@"Twitter サインアップ & ログイン完了!"); } else { NSLog(@"Twitter ログイン完了!"); } NSLog(@"sessionToken=%@",user.sessionToken); NSLog(@"isNew=%d",user.isNew); NSLog(@"username=%@",user.username); }]; }
サインアップおよびログインは上記のような形で行います。
user.isNew
の値が1なら新規登録扱いになっています。
user.sessionToken
でトークンが取得できます。
Twitter各種情報取得
認証が完了したので、APIを叩いて(APIにアクセスして)各種情報を取得してみましょう。
//スクリーンネーム取得用 -(void)info{ // AFHTTPRequestOperationManagerの定義 AFHTTPRequestOperationManager* manager = [AFHTTPRequestOperationManager manager]; manager.responseSerializer = [AFHTTPResponseSerializer serializer]; NSString* url = @"https://api.twitter.com/1.1/account/settings.json"; //NSMutableURLRequestにメソッド(GET)、URLを設定 NSMutableURLRequest *infoRequest = [manager.requestSerializer requestWithMethod:@"GET" URLString:url parameters:nil error:nil]; //認証 [[PFTwitterUtils twitter] signRequest:infoRequest]; //送信! AFHTTPRequestOperation *operation = [manager HTTPRequestOperationWithRequest:infoRequest success:^(AFHTTPRequestOperation* operation, id responseObject){ NSLog(@"success!"); //いろいろな値が取れているのでここで確認してみる NSDictionary* dict = [NSJSONSerialization JSONObjectWithData:responseObject options:0 error:nil]; NSLog(@"dict=%@",dict); //いま、ほしい値はscreen_name NSLog(@"screenName=%@",dict[@"screen_name"]); }failure:^(AFHTTPRequestOperation* operation, NSError* error){ NSLog(@"operation=%@",operation); NSLog(@"eror=%@",error); }]; [manager.operationQueue addOperation:operation]; }
ここで得られたscreen nameを使って、以下のAPIを叩いてみましょう。
//ユーザーネームとかアイコンURLとか取得 -(void)lookup{ // AFHTTPRequestOperationManagerの定義 AFHTTPRequestOperationManager* manager = [AFHTTPRequestOperationManager manager]; manager.responseSerializer = [AFHTTPResponseSerializer serializer]; NSString* url = @"https://api.twitter.com/1.1/users/lookup.json"; //SCREEN_NAMEにはhttps://api.twitter.com/1.1/account/settings.jsonで取得したscreen nameを代入する NSMutableDictionary* param = @{@"screen_name":SCREEN_NAME}.mutableCopy; //NSMutableURLRequestにメソッド(POST)、URL、パラメータを設定 NSMutableURLRequest *lookupRequest = [manager.requestSerializer requestWithMethod:@"POST" URLString:url parameters:param error:nil]; //認証 [[PFTwitterUtils twitter] signRequest:lookupRequest]; //送信! AFHTTPRequestOperation *operation = [manager HTTPRequestOperationWithRequest:lookupRequest success:^(AFHTTPRequestOperation* operation, id responseObject){ NSLog(@"success!"); //いろいろな値が取れているのでここで確認してみる NSArray* array = [NSJSONSerialization JSONObjectWithData:responseObject options:0 error:nil]; NSLog(@"array=%@",array); //ユーザーネーム NSLog(@"name=%@",array[0][@"name"]); //アイコン(小)URL NSLog(@"imageURL=%@",array[0][@"profile_image_url"]); //アイコン(大)URL NSLog(@"imageURL=%@",[array[0][@"profile_image_url"] stringByReplacingOccurrencesOfString:@"_normal" withString:@""]); }failure:^(AFHTTPRequestOperation* operation, NSError* error){ NSLog(@"operation=%@",operation); NSLog(@"eror=%@",error); }]; [manager.operationQueue addOperation:operation]; }
この出力はarray形式になっていますが、これはscreen name
をコンマ区切りで100個まで指定できるため、このようなかたちになっていると思います。
次回はfacebookアカウントでの認証。
Twitter/Facebookのアカウントで認証して、アプリからタイムライン/フィードに投稿する[#4]〜Parseの登録と設定〜
Parseは最近話題のmBaaSのひとつで、プッシュ通知、ユーザー管理機能、データストアなどのサーバー側の機能を提供してくれます。
ここではユーザー管理機能のみを使いTwitterとFacebookアカウントによる認証を行います。
登録
ParseのURLはこちら
アクセスしたら右上のSignup
から登録画面に入り、name
,address
,password
を登録。GitHubかFacebookのアカウントを使えばお手軽ですね。
続いてアプリ名、所属先、役職などの設定を行います。
Application ID と Client Key の取得
登録が完了したらApplication ID と Client Keyをメモっておきましょう。
次に、Settings
> User authentication
で
先ほどメモったFacebookのアプリケーションID
、シークレットキー
TwitterのAPIキー(Twitter Consumer Keys)
を入力します。
SDKの入手
同じくParseのDownload画面でiOSのSDKをダウンロード。
続いてFacebookのSDKを入手。
これら二つをプロジェクトにまるっとコピーします。
Flamework/Libraryのインポート
以下のFlamework/Libraryをプロジェクトに設定します。
- CoreLocation.framework
- StoreKit
- QuartzCore
- libz.1.1.3.dylib
- Security
- AudioToolbox
- MobileCoreServices
- SystemConfiguration
- CFNetwork
下準備はこんな感じです。
次はいよいよコードを書いていきます。
Twitter/Facebookのアカウントで認証して、アプリからタイムライン/フィードに投稿する[#3]〜Facebookのアプリ登録〜
登録
Facebookの開発者ページに入り、右上の+Create New App
をクリック
Display Name
,Namespace(optional)
を入力し、カテゴリ
を選択します。
設定
次に各種設定を行います。
アプリケーションID
とアプリのシークレットキー
をメモっておきます。
連絡先メールアドレス
を入力するまでは開発モードからリリースモードにならないようです。
あとは、+Add Platform
でiOS
を選択しアプリに設定するものと同じバンドルID
を入力します。(例:com.yourcompany.appname)
store ID
はアプリ申請後、ストアIDを入手したら設定しましょう。
Facebookの登録も難しくありませんね。 次はいよいよParseの登録と設定を行いましょう。
Twitter/Facebookのアカウントで認証して、アプリからタイムライン/フィードに投稿する[#2]〜Twitterのアプリ登録〜
登録
Twitterの開発者ページに入り右上のSigninからサインインします。
サインイン後、右上のボタンからMy Applications
を選択します。
Create New App
からName
, Description
, Website
, CallbackURL
を設定します。
Name
,Website
は認証画面の表示に反映、CallbackURL
は有効なURLを設定する必要があるみたいです。
あとは利用規約の同意にチェックを入れてポチッとやれば完了です。
設定
アプリの登録ができたら、API key
、 API Secret
をメモっておき、Access level
をRead only
からRead and write
に変更します。
私はここでハマってしまい、読み出しのみのAPIは叩けるけど、投稿系が一切受け付けてくれないという事態に陥りました。
あとは、お好みでアイコン画像の変更をしてください。
Twitter側の設定はこれで完了です。 簡単ですね! 次はFacebookアプリの登録です。