【教學】Facebook SDK 三部曲(上):點一下,分享到Facebook(這一定有什麼誤會!)
讓使用者可以PO上Facebook的功能怎麼做?
你可以:
1. 利用iOS6.0 up的social framework,或是iOS6.0 up 的UIActivityViewController。
2. 利用Facebook SDK。
3. 利用Facebook Graph API。
這主題比較長,所以我們分上下篇來介紹,下篇介紹使用官方做好的UI界面來完成分享功能。
這篇先介紹自己用手工的方式來完成:
為了簡化流程,我們先使用Facebook SDK,Token取得也較容易。(因為偷懶不想用Objective C 寫OAuth2.0認證流程)。
我們需要準備:
1. 稍微瞭解一下Facebook Graph API,可以參考這篇:【教學】Facebook SDK 二部曲:從Facebook抓取資料。
2. 做好登入功能的iOS專案,可以從這篇開始做:【教學】Facebook SDK 前傳:準備Social一下。
3. 多個Facebook帳號,Facebook App審核通過後,對每個帳號的分享功能有次數限制,要多PO要收費,換個帳號不花錢,如果在SandBox Mode就不用擔心。
先爬一下Graph API文件,你可以在Publishing項目中找到Publishing with the Graph API。
然後在項目Posts跟Other Objects找到我們所需要使用的:
API:
HTTP Method:
Arguments:
步驟:
1. 得到使用者授權"publish_actions"的權限,拿回Token 。
2. PO文。
我們使用Facebook SDK的FBSession Class:
+ openActiveSessionWithPublishPermissions:defaultAudience:allowLoginUI:completionHandler:
之後可得到有Publish Permission的Token,
再用FBRequestConnection Class:
+ startWithGraphPath:parameters:HTTPMethod:completionHandler:
或是
+ startForPostStatusUpdate:completionHandler:
設好參數,執行OK完成!!!
寫Code吧!
以下判斷考慮到目前Session是否可用(Session.isOpen)。
不論認證是否成功,Session一定會建立(Session.isOpen),但是卻沒Token可用,最常見就是使用者把認證是關掉了,Session建立但沒有Token,也可以改用檢查Session.state是否是FBSessionStateOpen來判定有沒有認證過。
建好一個UIViewController,View放上UIButton,連上Aciton,
寫上:
(這一定有什麼誤會...)
同樣的,你也可以建立FBSession的實體,來管理不同的Token。
Facebook SDK也是通過Facebook Graph API,如果有必要的話可以用HTTP Request 的方式來取代FBRequestConnection。
ViewController.h
ViewController.m
只不過要自己抓Token :p。
Note :
1. 如果使用FBSession靜態方法openActiveSessionWithPublishPermissions要求Read權限,但是裡面有屬於Publish權限的參數,如"email, publish_actions",在編譯的時候就會出現
2. 但是如果使用Facebook SDK要求Publish權限,參數裡面有屬於Read權限"email, publish_actions"一樣會有:
不過不會阻止你編譯,過程會先跳出要求Read權限的畫面,再跳出要求Publish權限的畫面。
如果不想讓使用者登入兩次,可以嘗試一下,建立FBSession實體的方法結果亦同。
3. 出現:
Error Domain=com.facebook.sdk Code=5 "The operation couldn’t be completed. (com.facebook.sdk error 5.)" UserInfo=0x9490550 {com.facebook.sdk:ParsedJSONResponseKey={
body = {
error = {
code = 2500;
message = "An active access token must be used to query information about the current user.";
type = OAuthException;
};
};
code = 400;
}, com.facebook.sdk:HTTPStatusCode=400}
請檢查Token是否為null。
4. 出現The page you requested connot be display right now.......,認證太頻繁了,暫時被擋掉,等會就可用了。
Graph API
Permissions
Errors
Feed Dialog
Public to Feed
你可以:
1. 利用iOS6.0 up的social framework,或是iOS6.0 up 的UIActivityViewController。
2. 利用Facebook SDK。
3. 利用Facebook Graph API。
這主題比較長,所以我們分上下篇來介紹,下篇介紹使用官方做好的UI界面來完成分享功能。
這篇先介紹自己用手工的方式來完成:
為了簡化流程,我們先使用Facebook SDK,Token取得也較容易。
我們需要準備:
1. 稍微瞭解一下Facebook Graph API,可以參考這篇:【教學】Facebook SDK 二部曲:從Facebook抓取資料。
2. 做好登入功能的iOS專案,可以從這篇開始做:【教學】Facebook SDK 前傳:準備Social一下。
3. 多個Facebook帳號,Facebook App審核通過後,對每個帳號的分享功能有次數限制,要多PO要收費,換個帳號不花錢,如果在SandBox Mode就不用擔心。
開始唄!
先爬一下Graph API文件,你可以在Publishing項目中找到Publishing with the Graph API。
然後在項目Posts跟Other Objects找到我們所需要使用的:
API:
https://graph.facebook.com/[user_id]/feed
HTTP Method:
POST
Arguments:
message
, picture
, link
, name
, caption
, description
, source
, place
, tags
我們就示範PO:按一下就發佈"我是帥哥!!!"到Facebook塗鴉牆上,您覺得如何?
步驟:
1. 得到使用者授權"publish_actions"的權限,拿回Token 。
2. PO文。
我們使用Facebook SDK的FBSession Class:
+ openActiveSessionWithPublishPermissions:defaultAudience:allowLoginUI:completionHandler:
之後可得到有Publish Permission的Token,
再用FBRequestConnection Class:
+ startWithGraphPath:parameters:HTTPMethod:completionHandler:
或是
+ startForPostStatusUpdate:completionHandler:
設好參數,執行OK完成!!!
寫Code吧!
以下判斷考慮到目前Session是否可用(Session.isOpen)。
不論認證是否成功,Session一定會建立(Session.isOpen),但是卻沒Token可用,最常見就是使用者把認證是關掉了,Session建立但沒有Token,也可以改用檢查Session.state是否是FBSessionStateOpen來判定有沒有認證過。
建好一個UIViewController,View放上UIButton,連上Aciton,
寫上:
- (IBAction)sayButtonAction:(id)sender { NSArray *publishPermissions = @[@"publish_actions"]; // Check if this session have publish permission. if ([FBSession.activeSession.permissions indexOfObject:@"publish_actions"] == NSNotFound || !FBSession.activeSession.accessTokenData) { [FBSession openActiveSessionWithPublishPermissions:publishPermissions defaultAudience:FBSessionDefaultAudienceEveryone allowLoginUI:YES completionHandler:^(FBSession *session, FBSessionState status, NSError *error) { if (session.isOpen && !error) { [self publishStory]; }else { NSLog(@"open publish permission error : %@", error); } }]; } else { [self publishStory]; } } - (void)publishStory { NSString *postWords = @"我是帥哥!!!"; NSString *httpMethod = @"POST"; NSString *endPoint = @"me/feed"; NSMutableDictionary *arguments = [[NSMutableDictionary alloc] init]; [arguments setValue:postWords forKey:@"message"]; [FBRequestConnection startWithGraphPath:endPoint parameters:arguments HTTPMethod:httpMethod completionHandler:^(FBRequestConnection *connection, id result, NSError *error) { if (error) { NSLog(@"Share Error : %@", error); } else { NSLog(@"Result : %@", result); NSLog(@"Token : %@", FBSession.activeSession.accessTokenData); } }]; ////You can use this method, too. // [FBRequestConnection startForPostStatusUpdate:postWords completionHandler:^(FBRequestConnection *connection, id result, NSError *error) { // if (error) { // NSLog(@"Share Error : %@", error); // // } else { // NSLog(@"Result : %@", result); // NSLog(@"Token : %@", FBSession.activeSession.accessTokenData); // } // }]; }
(這一定有什麼誤會...)
Coding完之後
同樣的,你也可以建立FBSession的實體,來管理不同的Token。
FBSession *withPublishSession = [[FBSession alloc] initWithPermissions:publishPermissions]; [withPublishSession openWithBehavior:FBSessionLoginBehaviorWithFallbackToWebView completionHandler:^(FBSession *session, FBSessionState status, NSError *error) { ... }];
Facebook SDK也是通過Facebook Graph API,如果有必要的話可以用HTTP Request 的方式來取代FBRequestConnection。
ViewController.h
#import <UIKit/UIKit.h> @interface ViewController : UIViewController <NSURLConnectionDataDelegate> { NSMutableData *receiveData; } - (IBAction)sayButtonAction:(id)sender; @end
ViewController.m
#import "ViewController.h" @interface ViewController () @end @implementation ViewController #pragma mark - View Life Cycle - (void)viewDidLoad { [super viewDidLoad]; [self initParameter]; } #pragma mark - initParameter - (void)initParameter { receiveData = [[NSMutableData alloc] init]; } #pragma mark - ShareFunction - (IBAction)sayButtonAction:(id)sender { // me = 目前登入Facebook的User ID NSString *shareEndPoint = @"https://graph.facebook.com/me/feed"; NSString *httpMethod = @"POST"; NSString *tokenWithPublishAcitonsPermission = @""; NSString *words = @"我很帥!!!"; // NSString *requestURL = [NSString stringWithFormat:@"%@%@", shareEndPoint, tokenWithPublishAcitonsPermission]; NSURL *url = [[NSURL alloc] initWithString:shareEndPoint]; NSMutableString *argument = [[NSMutableString alloc] init]; [argument appendString:@"access_token="]; [argument appendString:tokenWithPublishAcitonsPermission]; [argument appendString:@"message="]; [argument appendString:words]; NSData *body = [NSData dataWithBytes:[argument UTF8String] length:argument.length]; NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url]; [request setHTTPMethod:httpMethod]; [request setHTTPBody:body]; NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; [connection start]; } #pragma mark - NSURLConnection Data Delegate - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { NSLog(@"Got Response..."); NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; NSLog(@"Http Status Code : %d", httpResponse.statusCode); NSLog(@"Response Head : %@", httpResponse.allHeaderFields); [receiveData setLength:0]; } - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { NSLog(@"Receiving Data..."); [receiveData appendData:data]; } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { NSString *result = [[NSString alloc] initWithData:receiveData encoding:NSUTF8StringEncoding]; NSLog(@"Result : %@", result); } @end
只不過要自己抓Token :p。
Note :
1. 如果使用FBSession靜態方法openActiveSessionWithPublishPermissions要求Read權限,但是裡面有屬於Publish權限的參數,如"email, publish_actions",在編譯的時候就會出現
FBSDKLog: FBSession: a permission request for read permissions contains unexpected publish or manage permissions
2013-07-20 17:25:48.760 FBLogin[3791:c07] *** Terminating app due to uncaught exception 'com.facebook.sdk:InvalidOperationException', reason: 'FBSession: Publish or manage permissions are not permitted to to be requested with read permissions.
2. 但是如果使用Facebook SDK要求Publish權限,參數裡面有屬於Read權限"email, publish_actions"一樣會有:
FBSDKLog: FBSession: a permission request for publish or manage permissions contains unexpected read permissions
不過不會阻止你編譯,過程會先跳出要求Read權限的畫面,再跳出要求Publish權限的畫面。
如果不想讓使用者登入兩次,可以嘗試一下,建立FBSession實體的方法結果亦同。
3. 出現:
Error Domain=com.facebook.sdk Code=5 "The operation couldn’t be completed. (com.facebook.sdk error 5.)" UserInfo=0x9490550 {com.facebook.sdk:ParsedJSONResponseKey={
body = {
error = {
code = 2500;
message = "An active access token must be used to query information about the current user.";
type = OAuthException;
};
};
code = 400;
}, com.facebook.sdk:HTTPStatusCode=400}
請檢查Token是否為null。
4. 出現The page you requested connot be display right now.......,認證太頻繁了,暫時被擋掉,等會就可用了。
繼續前進:【教學】Facebook SDK 三部曲(下):點一下,分享到Facebook(這是懶人包...)
參考文件:
Graph API
Permissions
Errors
參考範例:
Feed Dialog
Public to Feed
請問要如何預設image再分享呢?就像分享文字那樣可以預設好要po的文字
回覆刪除如果需求不是很特殊的話,您可以用iOS6的Framework - SLComposeViewController
回覆刪除例:
// 建立
SLComposeViewController *shareView = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
// 設定初始的文字及圖片
[shareView setInitialText:describe];
[shareView addImage:photo];
// 設定完成後要執行的指令
[shareView setCompletionHandler:^(SLComposeViewControllerResult result) {
......
}];
// 讓使用者看見
[self presentViewController:shareView animated:YES completion:nil];
要注意的是,這是直接使用登入在iPhone->"設定"裡的Facebook帳號進行分享,
如果沒有設定過,SLComposeViewController在建立時會回傳nil,
如果要支援iOS6以下,或是要讓使用者登入其他帳號,請考慮用Facebook SDK
感謝你!