I am trying to upload a video from my iPhone to Facebook. I have logged in using FBLoginView and created a FBSession. I have used the following code to initiate a FBRequest of upload the video.
- (void)buttonRequestClickHandler:(id)sender {
if (FBSession.activeSession.isOpen) {
[FBSession.activeSession requestNewPublishPermissions:permissions
defaultAudience:FBSessionDefaultAudienceOnlyMe
completionHandler:nil];
NSString *audioName = [pictureDictionary4 objectForKey:#"photoVideokey"];
NSArray *pathsa = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectorya = [pathsa objectAtIndex:0];
NSString *moviePath = [documentsDirectorya stringByAppendingPathComponent:#"/Movie"];
NSString *fullPatha = [moviePath stringByAppendingPathComponent:audioName];
NSURL *pathURL = [[NSURL alloc]initFileURLWithPath:fullPatha isDirectory:NO];
NSData *videoData = [NSData dataWithContentsOfFile:fullPatha];
NSString *titleString = self.videotitle.text;
NSString *descripString = self.descrp.text;
NSDictionary *videoObject = #{
#"title":titleString,
#"description": descripString,
[pathURL absoluteString]: videoData
};
FBRequest *uploadRequest = [FBRequest requestWithGraphPath:#"me/videos"
parameters:videoObject
HTTPMethod:#"POST"];
[uploadRequest startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error)
NSLog(#"Done: %#", result);
else
NSLog(#"Error: %#", error.localizedDescription);
}];
}
I get an error
Error: The operation couldn’t be completed. (com.facebook.sdk error 5.)
I'm not sure what the error pertains to:
I know I'm logged in
I don't know if I am getting connected but I am on internet with iPhone
Are my parameters incorrect?
I have been messing with this for HOURS with no results
Any help from anyone/everyone would be greatly appreciated.
Finally got this working by going into my iPhone settings-facebook and deleting my account. Then when I tapped to upload the video in my app it loaded a view that asked if Facebook could use my app and I said yes then bam it uploaded. Also had to change my permissions to just publish_actions and get rid of publish_streams since that is a read permission. Anyway it is working now. Next to get defaultAudience to load from a string picked by user and not hard coded. Another post.
I guess its something to do with stream publishing permission. Try this way. It worked for me. I was using Facebook SDK 3.8.0
[self performPublishAction:^{
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"faisal" ofType:#"mov"];
NSURL *pathURL = [[NSURL alloc]initFileURLWithPath:filePath isDirectory:NO];
NSData *videoData = [NSData dataWithContentsOfFile:filePath];
NSDictionary *videoObject = #{
#"title": #"This is my title",
#"description": #"This is my description",
[pathURL absoluteString]: videoData
};
FBRequest *uploadRequest = [FBRequest requestWithGraphPath:#"me/videos"
parameters:videoObject
HTTPMethod:#"POST"];
[uploadRequest startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error)
NSLog(#"Done: %#", result);
else
NSLog(#"Error: %#", error.localizedDescription);
}];
}];
and
- (void) performPublishAction:(void (^)(void)) action {
if ([FBSession.activeSession.permissions indexOfObject:#"publish_stream"] == NSNotFound) {
[FBSession.activeSession requestNewPublishPermissions:#[#"publish_stream"]
defaultAudience:FBSessionDefaultAudienceFriends
completionHandler:^(FBSession *session, NSError *error) {
if (!error) {
action();
} else if (error.fberrorCategory != FBErrorCategoryUserCancelled){
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Permission denied"
message:#"Unable to get permission to post"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
}];
} else {
action();
}
}
This Code is Tested successfully On FaceBook SDK 3.14.1
Recommendation: 3 properties in .plist file
set FacebookAppID,FacebookDisplayName,
URL types->Item 0->URL Schemes set to facebookappId prefix with fb See
-(void)shareOnFaceBook
{
//sample_video.mov is the name of file
NSString *filePathOfVideo = [[NSBundle mainBundle] pathForResource:#"sample_video" ofType:#"mov"];
NSLog(#"Path Of Video is %#", filePathOfVideo);
NSData *videoData = [NSData dataWithContentsOfFile:filePathOfVideo];
//you can use dataWithContentsOfURL if you have a Url of video file
//NSData *videoData = [NSData dataWithContentsOfURL:shareURL];
//NSLog(#"data is :%#",videoData);
NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
videoData, #"video.mov",
#"video/quicktime", #"contentType",
#"Video name ", #"name",
#"description of Video", #"description",
nil];
if (FBSession.activeSession.isOpen)
{
[FBRequestConnection startWithGraphPath:#"me/videos"
parameters:params
HTTPMethod:#"POST"
completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if(!error)
{
NSLog(#"RESULT: %#", result);
[self throwAlertWithTitle:#"Success" message:#"Video uploaded"];
}
else
{
NSLog(#"ERROR: %#", error.localizedDescription);
[self throwAlertWithTitle:#"Denied" message:#"Try Again"];
}
}];
}
else
{
NSArray *permissions = [[NSArray alloc] initWithObjects:
#"publish_actions",
nil];
// OPEN Session!
[FBSession openActiveSessionWithPublishPermissions:permissions defaultAudience:FBSessionDefaultAudienceEveryone allowLoginUI:YES
completionHandler:^(FBSession *session,
FBSessionState status,
NSError *error) {
if (error)
{
NSLog(#"Login fail :%#",error);
}
else if (FB_ISSESSIONOPENWITHSTATE(status))
{
[FBRequestConnection startWithGraphPath:#"me/videos"
parameters:params
HTTPMethod:#"POST"
completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if(!error)
{
[self throwAlertWithTitle:#"Success" message:#"Video uploaded"];
NSLog(#"RESULT: %#", result);
}
else
{
[self throwAlertWithTitle:#"Denied" message:#"Try Again"];
NSLog(#"ERROR: %#", error.localizedDescription);
}
}];
}
}];
}
}
And I GOT Error:
The operation couldn’t be completed. (com.facebook.sdk error 5.)
It happens when facebook is being inited. Next time i open my app, it works fine, its always the first time. Tried everything in app, but it seems to be on the Facebook SDK side.
Few causes for seeing com.facebook.sdk error 5:
Session is is not open. Validate.
Facebook has detected that you're spamming the system. Change video name.
Facebook has a defined limit using the SDK. Try a different app.
Wrong publish permission. Give publish_actions a spin.
Related
I am simply trying to integrate Facebook sharing into my app, my app's end product is a video hence uploading and sharing the final compilation with friends is what i have in mind, I am using native social framework with ACAccount Framework, for my app to work there seems to be weird logic from Facebook that i need to ask for read permission before i ask for publish_stream permission and that they cant be immediately after(read somewhere), my question is where and how should i implement this logic in my code, heres my code
ACAccountStore* accountStore = [[ACAccountStore alloc] init];
NSDictionary *options = #{
ACFacebookAppIdKey: #"My app ID",
ACFacebookPermissionsKey: #[#"user_birthday"],
ACFacebookAudienceKey: ACFacebookAudienceOnlyMe
};
ACAccountType *facebookAccountType = [accountStore
accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
[accountStore requestAccessToAccountsWithType:facebookAccountType options:options completion:^(BOOL granted, NSError *error) {
if (granted) {
NSArray *accounts = [accountStore
accountsWithAccountType:facebookAccountType];
ACAccount * facebookAccount = [accounts lastObject];
NSLog(#"access to facebook account ok %#", facebookAccount.username);
NSData *videoData = [NSData dataWithContentsOfFile:[_fURL absoluteString]];
NSLog(#"%#",[_fURL absoluteString]);
NSLog(#"video size = %d", [videoData length]);
NSDictionary *params = #{
#"title": #"Me being silly",
#"description": #"Me testing the video upload to Facebook with the new system."
};
NSURL *requestURL = [NSURL URLWithString:#"https://graph.facebook.com/me/videos"];
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook
requestMethod:SLRequestMethodPOST
URL:requestURL
parameters:params];
[request addMultipartData:videoData
withName:#"source"
type:#"video/quicktime"
filename:[_fURL absoluteString]];
request.account = facebookAccount;
[request performRequestWithHandler:^(NSData *data, NSHTTPURLResponse *response,NSError * error){
NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"response = %#", responseString);
}];
Yes I am missing publish stream permission but i cant seem to figure out where should i put it, this whole code is under one method which is called when user presses a button
It is very simple. That is my implementation of it:
- (void)requestAccessToFacebookAccountWithCompletionHandler:(QCFacebookCommunicatorCompletionHandler)completionHandler {
[[self accountStore] requestAccessToAccountsWithType:[self accountType] options:[self facebookAccountAccessRequestOptionsForReadStreamPermission] completion:^(BOOL accessForReadingGranted, NSError *error) {
if (accessForReadingGranted) {
[[self accountStore] requestAccessToAccountsWithType:[self accountType] options:[self facebookAccountAccessRequestOptionsForPublishStreamPermission] completion:^(BOOL accessForWrittingGranted, NSError *error) {
if (accessForWrittingGranted) {
completionHandler(YES, nil);
} else {
completionHandler(NO, [error userInfo]);
}
}];
} else {
completionHandler(NO, [error userInfo]);
}
}];
}
I just use a helper methods to return dictionaries with options, other stuff is similar to yours.
Then, you can paste your code that is responsible for video uploading instead of the completionHandler calls, or you can use this implementation, and upload video only if the success == YES in completionHandler.
Hope it helps!
I have used following tutorial to use the new 6.0 Facebook integration for signing in.
iOS 6 Tutorial: Integrating Facebook into Your Applications
Here I dont need the Facebook SDK just new social framework from apple and it works well.
My question is how do I structure this single sign on in a storyboard?
My log in view should, after successful validation, redirect the user to next view and never really appear again.
I've been looking at a prepare for seque solution but not sure how I capture the users log in status and how that is also checked next time the user opens the application.
When log in button is pressed following function is triggered:
- (IBAction)advancedButtonPressed:(id)sender {
self.accountStore = [[ACAccountStore alloc]init];
ACAccountType *FBaccountType= [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
NSString *key = #"270430619733847";
NSDictionary *dictFB = [NSDictionary dictionaryWithObjectsAndKeys:key,ACFacebookAppIdKey,#[#"email"],ACFacebookPermissionsKey, nil];
[self.accountStore requestAccessToAccountsWithType:FBaccountType options:dictFB completion:
^(BOOL granted, NSError *e) {
if (granted) {
NSArray *accounts = [self.accountStore accountsWithAccountType:FBaccountType];
//it will always be the last object with single sign on
self.facebookAccount = [accounts lastObject];
NSLog(#"facebook account =%#",self.facebookAccount);
[self get];
} else {
//Fail gracefully...
NSLog(#"error getting permission %#",e);
}
}];
The get method is:
-(void)get
{
NSURL *requestURL = [NSURL URLWithString:#"https://graph.facebook.com/me"];
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook
requestMethod:SLRequestMethodGET
URL:requestURL
parameters:nil];
request.account = self.facebookAccount;
[request performRequestWithHandler:^(NSData *data,
NSHTTPURLResponse *response,
NSError *error) {
if(!error)
{
list =[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSLog(#"Dictionary contains: %#", list );
if([list objectForKey:#"error"]!=nil)
{
[self attemptRenewCredentials];
}
dispatch_async(dispatch_get_main_queue(),^{
nameLabel.text = [list objectForKey:#"username"];
});
}
else{
//handle error gracefully
NSLog(#"error from get%#",error);
//attempt to revalidate credentials
}
}];
I am integrating facebook through Accounts Framework, I searched and got some ways to do it. It was working first time but later it showing below log and not giving any information.
Log:
Dictionary contains: {
error = {
code = 2500;
message = "An active access token must be used to query information about the current user.";
type = OAuthException;
};
}
Code i used
ACAccountStore *_accountStore=[[ACAccountStore alloc] init];;
ACAccountType *facebookAccountType = [_accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
// We will pass this dictionary in the next method. It should contain your Facebook App ID key,
// permissions and (optionally) the ACFacebookAudienceKey
NSArray * permissions = #[#"email"];
NSDictionary *options = #{ACFacebookAppIdKey :#"my app id",
ACFacebookPermissionsKey :permissions,
ACFacebookAudienceKey:ACFacebookAudienceFriends};
// Request access to the Facebook account.
// The user will see an alert view when you perform this method.
[_accountStore requestAccessToAccountsWithType:facebookAccountType
options:options
completion:^(BOOL granted, NSError *error) {
if (granted)
{
// At this point we can assume that we have access to the Facebook account
NSArray *accounts = [_accountStore accountsWithAccountType:facebookAccountType];
// Optionally save the account
[_accountStore saveAccount:[accounts lastObject] withCompletionHandler:nil];
//NSString *uid = [NSString stringWithFormat:#"%#", [[_accountStore valueForKey:#"properties"] valueForKey:#"uid"]] ;
NSURL *requestURL = [NSURL URLWithString:[#"https://graph.facebook.com" stringByAppendingPathComponent:#"me"]];
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook
requestMethod:SLRequestMethodGET
URL:requestURL
parameters:nil];
request.account = [accounts lastObject];
[request performRequestWithHandler:^(NSData *data,
NSHTTPURLResponse *response,
NSError *error) {
if(!error){
NSDictionary *list =[NSJSONSerialization JSONObjectWithData:data
options:kNilOptions error:&error];
NSLog(#"Dictionary contains: %#", list );
userName=[list objectForKey:#"name"];
NSLog(#"username %#",userName);
userEmailID=[list objectForKey:#"email"];
NSLog(#"userEmailID %#",userEmailID);
userBirthday=[list objectForKey:#"birthday"];
NSLog(#"userBirthday %#",userBirthday);
userLocation=[[list objectForKey:#"location"] objectForKey:#"name"];
NSLog(#"userLocation %#",userLocation);
}
else{
//handle error gracefully
}
}];
}
else
{
NSLog(#"Failed to grant access\n%#", error);
}
}];
any clues friends what is going wrong...Thanks.
The problem was that when I changed my facebook setting inside device the access token got timed out . so if you listen for an ACAccountStoreDidChangeNotification you can then call renewCredentialsForAccount: to prompt the user for permission.
The below code is working and getting user info in a dictionary.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(accountChanged) name:ACAccountStoreDidChangeNotification object:nil];
}
-(void)getUserInfo
{
self.accountStore = [[ACAccountStore alloc]init];
ACAccountType *FBaccountType= [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
NSString *key = #"your_app_id";
NSDictionary *dictFB = [NSDictionary dictionaryWithObjectsAndKeys:key,ACFacebookAppIdKey,#[#"email"],ACFacebookPermissionsKey, nil];
[self.accountStore requestAccessToAccountsWithType:FBaccountType options:dictFB completion:
^(BOOL granted, NSError *e) {
if (granted) {
NSArray *accounts = [self.accountStore accountsWithAccountType:FBaccountType];
//it will always be the last object with single sign on
self.facebookAccount = [accounts lastObject];
NSLog(#"facebook account =%#",self.facebookAccount);
[self get];
} else {
//Fail gracefully...
NSLog(#"error getting permission %#",e);
}
}];
}
-(void)accountChanged:(NSNotification *)notif//no user info associated with this notif
{
[self attemptRenewCredentials];
}
-(void)attemptRenewCredentials{
[self.accountStore renewCredentialsForAccount:(ACAccount *)self.facebookAccount completion:^(ACAccountCredentialRenewResult renewResult, NSError *error){
if(!error)
{
switch (renewResult) {
case ACAccountCredentialRenewResultRenewed:
NSLog(#"Good to go");
[self get];
break;
case ACAccountCredentialRenewResultRejected:
NSLog(#"User declined permission");
break;
case ACAccountCredentialRenewResultFailed:
NSLog(#"non-user-initiated cancel, you may attempt to retry");
break;
default:
break;
}
}
else{
//handle error gracefully
NSLog(#"error from renew credentials%#",error);
}
}];
}
-(void)get
{
NSURL *requestURL = [NSURL URLWithString:#"https://graph.facebook.com/me"];
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook
requestMethod:SLRequestMethodGET
URL:requestURL
parameters:nil];
request.account = self.facebookAccount;
[request performRequestWithHandler:^(NSData *data,
NSHTTPURLResponse *response,
NSError *error) {
if(!error)
{
NSDictionary *list =[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSLog(#"Dictionary contains: %#", list );
}
else{
//handle error gracefully
NSLog(#"error from get%#",error);
//attempt to revalidate credentials
}
}];
self.accountStore = [[ACAccountStore alloc]init];
ACAccountType *FBaccountType= [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
NSString *key = #"your_app_id";
NSDictionary *dictFB = [NSDictionary dictionaryWithObjectsAndKeys:key,ACFacebookAppIdKey,#[#"friends_videos"],ACFacebookPermissionsKey, nil];
[self.accountStore requestAccessToAccountsWithType:FBaccountType options:dictFB completion:
^(BOOL granted, NSError *e) {}];
}
This one helped me a lot.
you need create session
[FBSession openActiveSessionWithReadPermissions:permissions
allowLoginUI:YES
completionHandler:^(FBSession *session, FBSessionState status, NSError *error){
if (session.isOpen) {
switch (status) {
case FBSessionStateOpen:
// here you get the token
NSLog(#"%#", session.accessToken);
break;
case FBSessionStateClosed:
case FBSessionStateClosedLoginFailed:
[[FBSession activeSession] closeAndClearTokenInformation];
break;
default:
break;
} // switch
}];
Please give the more details of your code...your code seems to be not having session..you must have a valid session..and the accessToken is unique for each user id..in your case i think session is not there..how it can know your access token..So, you are getting this error...If you want to know more about access token..check facebook demo projects which is with sdk..you can also go through this..http://developers.facebook.com/docs/concepts/login/access-tokens-and-types/
I have successfully prompted users to grant facebook permission, using the method below via SocialFramework, but can't seem to be able to retrieve and then display basic profile info (name, email, id, etc...) I imagine there are simple methods for this, but can't find them. Can anyone provide some help here? Thanks
-(IBAction)getInfo:(id)sender{
NSLog(#"FIRING");
ACAccountStore *_accountStore = [[ACAccountStore alloc] init];
ACAccountType *facebookAccountType = [_accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
// We will pass this dictionary in the next method. It should contain your Facebook App ID key,
// permissions and (optionally) the ACFacebookAudienceKey
NSDictionary *options = #{ACFacebookAppIdKey : #"284395038337404",
ACFacebookPermissionsKey : #[#"email"],
ACFacebookAudienceKey:ACFacebookAudienceOnlyMe};
// Request access to the Facebook account.
// The user will see an alert view when you perform this method.
[_accountStore requestAccessToAccountsWithType:facebookAccountType
options:options
completion:^(BOOL granted, NSError *error) {
if (granted)
{
NSLog(#"GRANTED");
// At this point we can assume that we have access to the Facebook account
NSArray *accounts = [_accountStore accountsWithAccountType:facebookAccountType];
// Optionally save the account
[_accountStore saveAccount:[accounts lastObject] withCompletionHandler:nil];
}
else
{
NSLog(#"Failed to grant access\n%#", error);
}
}];
}
With the code you have posted you can access only to very basic info of the account you are getting, as screen name or description which is facebook in this case...
An example:
ACAccount *account = [accounts lastObject];
NSString *username = account.username;
In order to get more complete information as real name, email, etc. you need to make a SLRequest using the /me function of the graph facebook api.
NSURL *requestURL = [NSURL URLWithString:#"https://graph.facebook.com/me"];
NSString *serviceType = SLServiceTypeFacebook;
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue setName:#"Perform request"];
[queue addOperationWithBlock:^{
SLRequest *request = [SLRequest requestForServiceType:serviceType requestMethod:SLRequestMethodGET URL:requestURL parameters:nil];
[request setAccount:account];
NSLog(#"Token: %#", account.credential.oauthToken);
[request performRequestWithHandler:^(NSData *data, NSHTTPURLResponse *response, NSError *error) {
// Handle the response...
if (error) {
NSLog(#"Error: %#", error);
//Handle error
}
else {
NSDictionary* jsonResults = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
if (error) {
NSLog(#"Error: Error serializating object");
//Handle error
}
else {
NSDictionary *errorDictionary = [jsonResults valueForKey:#"error"];
if (errorDictionary) {
NSNumber *errorCode = [errorDictionary valueForKey:#"code"];
//If we get a 190 code error, renew credentials
if ([errorCode isEqualToNumber:[NSNumber numberWithInt:190]]) {
NSLog(#"Renewing credenciales...");
[self.accountStore renewCredentialsForAccount:account completion:^(ACAccountCredentialRenewResult renewResult, NSError *error){
if (error) {
NSLog(#"Error: %#", error);
//Handle error
}
else {
if (renewResult == ACAccountCredentialRenewResultRenewed) {
//Try it again
}
else {
NSLog(#"Error renewing credenciales...");
NSError *errorRenewengCredential = [[NSError alloc] initWithDomain:#"Error reneweng facebook credentials" code:[errorCode intValue] userInfo:nil];
if (renewResult == ACAccountCredentialRenewResultFailed) {
//Handle error
}
else if (renewResult == ACAccountCredentialRenewResultRejected) {
//Handle error
}
}
}
}];
}
}
else {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
NSLog(#"jsonResults: %#", jsonResults);
}];
}
}
}
}
}];
}];
This code also checks the possibility of errors, some handling if the token has expired and running the network processes in background in order to not blocking the interface.
You will find all the info at the jsonResults dictionary, and you can access as follows:
NSString *name = [jsonResults objectForKey:#"first_name"];
NSString *lastName = [jsonResults objectForKey:#"last_name"];
NSString *email = [jsonResults objectForKey:#"email"];
Check facebook documentation for more information at:
https://developers.facebook.com/docs/reference/api/user/
Hope it helps!
I am trying to query information about a user using iOS 6's new Facebook integration API. This is the code I'm using, which is basically identical to what they demoed at WWDC:
{
NSDictionary *parameters = #{};
NSURL *url = [NSURL URLWithString:#"https://graph.facebook.com/me"];
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook
requestMethod:SLRequestMethodGET
URL:url
parameters:parameters];
request.account = self.account;
[request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
NSLog(#"Facebook request received, status code %d", urlResponse.statusCode);
NSString *response = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(#"Response data: %#", response);
dispatch_async(dispatch_get_main_queue(), ^{
});
}];
}
Problem is I am getting error code 2500 from Facebook: "An active access token must be used to query information about the current user." If I change the query to https://graph.facebook.com/[facebook id] then it works fine. I am assuming the problem is that iOS is passing the access token of the app instead of the user's access token when sending the request via requestForServiceType. I just don't know how to fix it. Obviously anticipating and hardcoding the Facebook IDs of my users is not an option. Any suggestions?
add your active access token in paramete like
NSDictionary *parameters = [NSDictionary dictionaryWithObject:#"PUT_ACCESS_TOKEN_HERE" forKey:#"access_token"];
I faced with the same issue and found the workaround:
NSString *uid = [NSString stringWithFormat:#"%#", [[self.account valueForKey:#"properties"] valueForKey:#"uid"]] ;
NSURL *url = [NSURL URLWithString:[#"https://graph.facebook.com" stringByAppendingPathComponent:uid]];
OK here is how I do this integration with iOS 6 and get what I want from Facebook:
In AppDelegate I do this:
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
return [FBSession.activeSession handleOpenURL:url];
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
[FBSession.activeSession handleDidBecomeActive];
}
- (void)applicationWillTerminate:(UIApplication *)application
{
[FBSession.activeSession close];
}
and in my ViewController where I want to retrieve information about myself or my friends I do this (NOTE: this is a test, so it is a lot of permissions!):
NSArray *permissions =
[NSArray arrayWithObjects:#"email", #"user_location",
#"user_birthday",
#"user_likes", #"user_interests",#"friends_interests",#"friends_birthday",#"friends_location",#"friends_hometown",#"friends_photos",#"friends_status",
#"friends_about_me", #"friends_birthday", #"friends_hometown", #"friends_interests", #"friends_likes", #"friends_location", nil];
[FBSession openActiveSessionWithReadPermissions:permissions
allowLoginUI:YES
completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
/* handle success + failure in block */
if (status) {
NSLog(#"Facebook Read Permission is successful!");
[self presentPostOptions];
// [self presentPostOptions];
}
}];
Then in "presentPostOptions" I do this (in this example I try to retrieve something from my friend):
- (void)presentPostOptions
{
[[FBRequest requestForMyFriends] startWithCompletionHandler:^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error)
{
if (!error) {
NSArray *data = [user objectForKey:#"data"];
NSLog(#"%d", [data count]);
for (FBGraphObject<FBGraphUser> *friend in data) {
NSLog(#"%#", [friend first_name]);
NSLog(#"%#", [friend last_name]);
NSLog(#"%#", [friend id]);
//make sure you have FBProfilePictureView outlet in your view
//otherwise skip the profile picture!
self.fbProfilePic.profileID = #"you'r friend's profile.id";
}
}
else
{
NSLog(#"error");
// [self didFailWithError:error];
}
}];
I don't know what else you want to do because in your question you just tried to make a connection but this way you can do what ever you want while you are integrated in iOS 6.
One more thing, make sure about your App Settings over Facebook and the configs over there like enable your app for iOS and the ID for iPhone/iPad. Also the FacebookAppID in your plist.
Let me know if it works out for you,
EDIT: btw my Facebook SDK is 3.1.1.
I had the same error message, I fixed it by saving my account after renewing the credential.
Make sure your (ACAccount *)facebookAccount (or in your case self.account)
object is strong and you set it correctly while getting permissions.
The answer is simple
in viewDidLoad() use:
accountStore= [[ACAccountStore alloc]init];
facebookAccountType= [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
NSDictionary *options= #{
ACFacebookAudienceKey: ACFacebookAudienceEveryone,
ACFacebookAppIdKey: #"<YOUR FACEBOOK APP ID>",
ACFacebookPermissionsKey: #[#"public_profile"]
};
[accountStore requestAccessToAccountsWithType:facebookAccountType options:options completion:^(BOOL granted, NSError *error) {
if (granted) {
NSLog(#"Permission has been granted to the app");
NSArray *accounts= [accountStore accountsWithAccountType:facebookAccountType];
facebookAccount= [accounts firstObject];
[self performSelectorOnMainThread:#selector(facebookProfile) withObject:nil waitUntilDone:NO];
} else {
NSLog(#"Permission denied to the app");
}
}];
And the function-(void)facebookProfile
NSURL *url = [NSURL URLWithString:#"https://graph.facebook.com/me"];
Notice the params you need are added as dictionary
Refer below for complete list
https://developers.facebook.com/docs/graph-api/reference/user
NSDictionary *param=[NSDictionary dictionaryWithObjectsAndKeys:#"picture,id,name",#"fields", nil];
SLRequest *profileInfoRequest= [SLRequest requestForServiceType:SLServiceTypeFacebook requestMethod:SLRequestMethodGET URL:url parameters:param];
profileInfoRequest.account= facebookAccount;
[profileInfoRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
NSLog(#"Facebook status code is : %ld", (long)[urlResponse statusCode]);
if ([urlResponse statusCode]==200) {
NSDictionary *dictionaryData= [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableLeaves error:&error];
} else {
}
}];
}