【教學】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]/feedHTTP Method:
POSTArguments:
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
感謝你!