Using SDK 3.22.0.
if (FBSession.activeSession.isOpen) {
[FBSession.activeSession
requestNewPublishPermissions:#[#"publish_actions"]
defaultAudience:FBSessionDefaultAudienceFriends
completionHandler:^(FBSession *session, NSError *error) {
NSLog(#"error = %#", error);
NSLog(#"session open = %d", session.isOpen);
NSLog(#"session.permissions = %#", session.permissions);
NSLog(#"session.accessTokenData.declinedPermissions = %#", session.accessTokenData.declinedPermissions);
}];
}
else {
[FBSession
openActiveSessionWithPublishPermissions:#[#"publish_actions"]
defaultAudience:FBSessionDefaultAudienceFriends
allowLoginUI:YES
completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
NSLog(#"error = %#", error);
NSLog(#"session open = %d", session.isOpen);
NSLog(#"status = %lu", status);
NSLog(#"session.permissions = %#", session.permissions);
NSLog(#"session.accessTokenData.declinedPermissions = %#", session.accessTokenData.declinedPermissions);
}];
}
I'm testing with a user that doesn't have yet publish permissions and never declined it either. On FB Apps Settings on this account, the App Visibility is set to "Friends" and publishing permissions are not even on the settings list as they are for other users/apps.
In both cases of the code, the FB app opens and returns to my app immediately, without asking permissions. Response of declinedPermissions is an array with publish_actions.
My expectation is that FB app will ask the user to approve publishing.
I got reports from multiple users that experienced the same issue - not being able to add publish permissions, but some are able to get the permission.
One thing to add is that I had the same issue before submitting the app for FB approval with users outside of the test group, but when app got approved it started working for those users. Now it seems like the problem persists even when the app is approved, just for random users.
Am I doing anything wrong with the way I'm asking for permissions?
Looks like this worked:
- (BOOL)hasWritePermissions {
if (!FBSession.activeSession.isOpen) return NO;
return [FBSession.activeSession.permissions indexOfObject:#[#"publish_actions"]] != NSNotFound;
}
- (void)requestWritePermissions:(void(^)(BOOL status, NSError *error))callback {
if (self.hasWritePermissions) {
callback(YES, nil);
return;
}
if (FBSession.activeSession.isOpen) {
[FBSession.activeSession
requestNewPublishPermissions:#[#"publish_actions"]
defaultAudience:FBSessionDefaultAudienceFriends
completionHandler:^(FBSession *session, NSError *error) {
NSLog(#"error = %#", error);
NSLog(#"session open = %d", session.isOpen);
NSLog(#"session.permissions = %#", session.permissions);
NSLog(#"session.accessTokenData.declinedPermissions = %#", session.accessTokenData.declinedPermissions);
if (self.hasWritePermissions) {
callback(YES, nil);
}
else {
callback(NO, error);
}
}];
}
else {
[FBSession
openActiveSessionWithPublishPermissions:#[#"publish_actions"]
defaultAudience:FBSessionDefaultAudienceFriends
allowLoginUI:YES
completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
NSLog(#"error = %#", error);
NSLog(#"session open = %d", session.isOpen);
NSLog(#"status = %u", status);
NSLog(#"session.permissions = %#", session.permissions);
NSLog(#"session.accessTokenData.declinedPermissions = %#", session.accessTokenData.declinedPermissions);
[self requestWritePermissions:callback]; // this time, with an open session
}];
}
}
If there's no session, I run openActiveSessionWithPublishPermissions and then run again requestNewPublishPermissions.
Issue is that openActiveSessionWithPublishPermissions was firing the callback without even going to Facebook app for more permissions (looks like FB bug, will report), but this approach seems to solve it.
Another issue I found is that session.permissions are not always reflecting the permissions on Facebook. The only way I found to ensure I have the latest permissions is to issue an API request:
[FBRequestConnection startWithGraphPath:#"/me/permissions" completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
and check the result.data array for granted/declined permissions.
I had a similar issue with this method. I ended up opening the session with a full set of permissions (read & write ) and it solved my problem.
-(void)requestPublishPermissionsWithCompletion:(FBHandlerComp)completion{
if (self.session.isOpen && [self.session.permissions containsObject:#"publish_actions"]){
//we have an open session and all neceassarry pemissions
completion(true,nil);
}else{
//something in missing, to account to all diffrent scenarios (missing persmission, expired tokens, changes in user sessting etc..), we reinisilise the session and request permissions
//for publish permissions we need to ask for the whole set( read& publish)
NSMutableArray *permissions = [NSMutableArray arrayWithArray:self.writePersmissions];
[permissions addObjectsFromArray:self.readPersmissions];
self.session = [[FBSession activeSession]initWithAppID:nil permissions:permissions defaultAudience:FBSessionDefaultAudienceFriends urlSchemeSuffix:nil tokenCacheStrategy:nil];
[self openFacebookSessionWithCompleteion:^(BOOL result, NSError *error) {
if (result) {
completion(true,nil);
}else{
if (LOGGING_IS_ON) DebugLog(#"could not get publish permissions- could not open session %#",error);
completion(false,nil);
}
}];
}
}
Related
I am having a problem with requestNewPublishPermissions (I'm using SDK version 3.17). The Facebook docs say to log in with just read permission, and then later ask for write permission, so that's what I'm trying to do. I can get the user to log in just fine with code like this:
[FBSession openActiveSessionWithReadPermissions:#[#"public_profile"]
allowLoginUI:YES
completionHandler:^(FBSession *session, FBSessionState state, NSError *error)
{
// Handler for session state changes
// This method will be called EACH time the session state changes,
// also for intermediate states and NOT just when the session open
[self sessionStateChanged:session state:state error:error];
}];
Then when I want to post to the timeline, I ask to expand the permissions using the code below. The app kicks out to Safari with a Facebook web page. But instead of asking for write permission, that web page just says that the app was already given permission. And then when I hit okay, and control returns to the app, I do NOT have publish permission. See "this is where it ends up!" below.
I have tried going to facebook.com and deleting the permissions already given under "Apps". That didn't make any difference. I've also tried doing a publish anyway, but that gives me an error that says I don't have the correct permissions.
Any ideas?
- (void) requestPublishPermission:(void (^)(void)) action
{
// Request publish_actions
[FBSession.activeSession requestNewPublishPermissions:[NSArray arrayWithObject:#"publish_actions"]
defaultAudience:FBSessionDefaultAudienceFriends
completionHandler:^(FBSession *session, NSError *error)
{
if (!error)
{
if ( [FBSession.activeSession.permissions indexOfObject:#"publish_actions"] == NSNotFound )
{
// this is where it ends up!
}
else
{
// Permission granted, publish the story
action();
}
}
else
{
// permission denied, alert user
}
}];
}
You need to add the user you are logging in as as a Developer/Tester. Or you need to submit your app to Facebook for review.
I have the same issue and it is happening only when the user is not using the FB App and everything is happening via the Web. This is what I did to resolve the problem:
typedef void(^facebookPostCompBlock)(FBSession *session, NSError* err, BOOL publishActionPermissions);
- (void) obtainPostPermissionsWithComplition:(facebookPostCompBlock) comp {
if ([[FBSession activeSession] isOpen]) {
if ([[[FBSession activeSession] permissions]indexOfObject:#"publish_actions"] == NSNotFound) {
[FBSession.activeSession requestNewPublishPermissions:#[#"publish_actions"]
defaultAudience:FBSessionDefaultAudienceFriends
completionHandler:^(FBSession *session, NSError *error)
{
BOOL gotPublishActionPermissions = TRUE;
if ([[[FBSession activeSession] permissions]indexOfObject:#"publish_actions"] == NSNotFound) {
gotPublishActionPermissions = FALSE;
}
if (comp) {
comp(session,error,gotPublishActionPermissions);
}
}];
} else {
if (comp) {
comp([FBSession activeSession],nil,TRUE);
}
}
} else {
BOOL openedSynchronously = [FBSession openActiveSessionWithPublishPermissions:#[#"publish_actions"]
defaultAudience:FBSessionDefaultAudienceFriends
allowLoginUI:YES
completionHandler:^(FBSession *session, FBSessionState status, NSError *error)
{
if (!error && status == FBSessionStateOpen) {
[self obtainPostPermissionsWithComplition:comp];
} else {
BOOL gotPublishActionPermissions = TRUE;
if ([[session permissions]indexOfObject:#"publish_actions"] == NSNotFound) {
gotPublishActionPermissions = FALSE;
BLog(#"+ NOT FOUND +");
} else {
if (comp) {
comp(session,error,gotPublishActionPermissions);
}
}
}
}];
}
}
The only concern in the following (need a fail safe) is the that the session will switch from open to close over an over and you'll end up with a loop.
I am not able to get the permissions for user_birthday and user_hometown.
I tried it with this code before but it only asks for the public profile and ignores others.
[FBSession openActiveSessionWithReadPermissions:#[#"public_profile",#"user_birthday",#"user_hometown"]
allowLoginUI:YES completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
if (error) {
NBAppDelegate* appDel = (NBAppDelegate*)`[UIApplication sharedApplication].delegate;
[appDel sessionStateChanged:session state:status error:error];
}
if ([session isOpen]) {
[self loginWithFBToken:session name:sender];
}
}];
Then someone suggested to ask for additional permissions after getting the public profile, so i even tried that to no good.
Here is the code for that
- (void)loadFbDetails
{
NSArray *permissionsNeeded = #[#"user_hometown", #"user_birthday"];
// Request the permissions the user currently has
[FBRequestConnection startWithGraphPath:#"/me/permissions"
completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error){
// These are the current permissions the user has:
NSDictionary *currentPermissions= [(NSArray *)[result data] objectAtIndex:0];
// We will store here the missing permissions that we will have to request
NSMutableArray *requestPermissions = [[NSMutableArray alloc] initWithArray:#[]];
// Check if all the permissions we need are present in the user's current permissions
// If they are not present add them to the permissions to be requested
for (NSString *permission in permissionsNeeded){
if (![currentPermissions objectForKey:permission]){
[requestPermissions addObject:permission];
}
}
// If we have permissions to request
if ([requestPermissions count] > 0){
// Ask for the missing permissions
[FBSession.activeSession
requestNewReadPermissions:requestPermissions
completionHandler:^(FBSession *session, NSError *error) {
if (!error) {
// Permission granted
NSLog(#"new permissions %#", [FBSession.activeSession permissions]);
// We can request the user information
[self makeRequestForUserData];
} else {
// An error occurred, we need to handle the error
// See: https://developers.facebook.com/docs/ios/errors
}
}];
} else {
// Permissions are present
// We can request the user information
[self makeRequestForUserData];
}
} else {
// An error occurred, we need to handle the error
// See: https://developers.facebook.com/docs/ios/errors
}
}];
}
-(void)makeRequestForUserData
{
[FBRequestConnection startWithGraphPath:#"me?fields=birthday,hometown"
completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error) {
// Sucess! Include your code to handle the results here
NSLog(#"user events: %#", result);
} else {
NSLog(#"error: %#" , error);
}
}];
}
All it does is recursively go between my ios app and the fb native app, returning only with the public_profile in the permissions array.
Looks like i am missing something?
It should work if you're using an admin user of the app. Once you want to use the extended permissions with other users, you have to get your app reviewed by Facebook first.
See my answer here: facebook extended permission
Facebook does not allow apps to access that information by default. You have to ask permission to Facebook for you to be able to use that information. Add a video and instructions for a Facebook employee review how you're using birthday and hometown intel.
I am fetching a facebook token from my server (where it was stored from a previous login on another device). I am using that to open a session and then I am making a relatively simple call with
[FBWebDialogs presentRequestsDialogModallyWithSession:[FBSession activeSession]
message:#"Message"
title:#"Title"
parameters:params
handler:^(FBWebDialogResult result,
NSURL *resultURL, NSError *error) {}}];
The web window that pops up has a message saying "An Error occured. Please try again later.". I click OK and I trigger the callback (which I omitted above). When I trace the resultURL I get
fbconnect://success?error_code=110&error_msg=Missing+user+cookie+%28to+validate+session+user%29
I can use the session to post on my wall just fine. What am I missing?
I found that the token retuned by Facebook contains additional metadata such as the c_user cookie which is used by all web views subsequently. When setting up a remote caching system you must store expiry date and refresh date on the remote server and return them for use in the TokenData object. If this is not done correctly them the correct metadata is not set.
Make sure you have "publish_actions" permission on your active Facebook session.
bool hasPublishPermission = NO;
for( NSString* permission in [FBSession.activeSession permissions] )
{
if( [permission isEqualToString:#"publish_actions"] )
{
hasPublishPermission = YES;
break;
}
}
if( !hasPublishPermission )
{
[FBSession openActiveSessionWithPublishPermissions:#[#"publish_actions"]
defaultAudience:FBSessionDefaultAudienceFriends
allowLoginUI:YES
completionHandler:^(FBSession *session,
FBSessionState status,
NSError *error) {
if( status==FBSessionStateOpen )
{
//Present dialog
}
}];
}
else
{
//Present dialog
}
Also, make sure you have added your "FacebookAppID" to your project's plist. (See the tab, "Configure a new Xcode Project", at https://developers.facebook.com/docs/getting-started/facebook-sdk-for-ios/ ) This may cause the error you are describing.
Hope this helps
I have integrated Embedded webview in my app with Facebook sdk 3.5.3
I hope my code will give some idea to you...
-(IBAction)fblogin:(id)sender{
NSArray * arr=[NSArray arrayWithObjects:#"publish_actions",#"email",#"basic_info",#"user_location",#"user_birthday",#"user_likes", nil];
Interest_Status=[NSString stringWithFormat:#"%#",txt_interest.text];
[FBSession setActiveSession:session];
if (FBSession.activeSession.isOpen) {
if ([btn_Login.titleLabel.text isEqualToString:#"Logout"]) {
[btn_Login setTitle:#"Login" forState:UIControlStateNormal];
[btn_Login setImage:[UIImage imageNamed:#"FBLogin.png"] forState:UIControlStateNormal];
FBSessionTokenCachingStrategy *tokenCachingStrategy = [[FBSessionTokenCachingStrategy alloc]
initWithUserDefaultTokenInformationKeyName:nil];
tokenCachingStrategy=nil;
FBSession *seession=[FBSession activeSession];
[seession closeAndClearTokenInformation];
[session close];
[FBSession setActiveSession:nil];
session=nil;
session=[[FBSession alloc]initWithPermissions:arr];
self.ProfileLale.hidden=YES;
}
/*else if ([btn_Login.titleLabel.text isEqualToString:#"Login"]) {
[self updateForSessionChangeForSlot:1];
}*/
}else{
[session openWithBehavior:FBSessionLoginBehaviorForcingWebView
completionHandler:^(FBSession *session,
FBSessionState status,
NSError *error) {
// this handler is called back whether the login succeeds or fails; in the
// success case it will also be called back upon each state transition between
// session-open and session-close
if (error)
{
NSLog(#"error=%# \n\n description=%# \n\n,",error,error.description);
[self switchToNoActiveUser];
}else{
[self updateForSessionChangeForSlot:1];
}
}];
}
}
- (void)updateForSessionChangeForSlot:(int)slot {
if (session.isOpen) {
// fetch profile info such as name, id, etc. for the open session
// Fetch user data
FBRequest *me = [[FBRequest alloc] initWithSession:session
graphPath:#"me"];
[me startWithCompletionHandler:^(FBRequestConnection *connection,
NSDictionary<FBGraphUser> *user,
NSError *error) {
// because we have a cached copy of the connection, we can check
// to see if this is the connection we care about; a prematurely
// cancelled connection will short-circuit here
// if (me != self.pendingRequest) {
// return;
// }
NSLog(#"user=%#",user);
// self.pendingRequest = nil;
// self.pendingLoginForSlot = -1;
// we interpret an error in the initial fetch as a reason to
// fail the user switch, and leave the application without an
// active user (similar to initial state)
if (error) {
NSLog(#"error=%#",error);
NSLog(#"Couldn't switch user: %#", error.localizedDescription);
[self switchToNoActiveUser];
return;
}else{
NSLog(#"user=%#",user);
[btn_Login setTitle:#"Logout" forState:UIControlStateNormal];
[btn_Login setImage:[UIImage imageNamed:#"FBLogout.png"] forState:UIControlStateNormal];
}
}];
} else {
// in the closed case, we check to see if we picked up a cached token that we
// expect to be valid and ready for use; if so then we open the session on the spot
if (session.state == FBSessionStateCreatedTokenLoaded) {
// even though we had a cached token, we need to login to make the session usable
[session openWithCompletionHandler:^(FBSession *session,
FBSessionState status,
NSError *error) {
[self updateForSessionChangeForSlot:slot];
}];
}
}
}
- (void)switchToNoActiveUser {
/*UIAlertView *alter=[[UIAlertView alloc]initWithTitle:#"Message" message:#"No Internet connecton" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alter show];
*/
NSArray * arr=[NSArray arrayWithObjects:#"publish_actions",#"email",#"basic_info",#"user_location",#"user_birthday",#"user_likes", nil];
session = nil;
session=[[FBSession alloc]initWithPermissions:arr];
[btn_Login setTitle:#"Login" forState:UIControlStateNormal];
self.ProfileLale.hidden=YES;
[btn_Login setImage:[UIImage imageNamed:#"FBLogin.png"] forState:UIControlStateNormal];
}
I'm following this tutorial
to implement the view preview post on Facebook SDK 3.1, but when I call this method
...
// Ask for publish_actions permissions in context
if ([FBSession.activeSession.permissions
indexOfObject:#"publish_actions"] == NSNotFound) {
// No permissions found in session, ask for it
[FBSession.activeSession
reauthorizeWithPublishPermissions:
[NSArray arrayWithObject:#"publish_actions"]
defaultAudience:FBSessionDefaultAudienceFriends
completionHandler:^(FBSession *session, NSError *error) {
if (!error) {
// If permissions granted, publish the story
[self publishStory];
}
}];
} else {
// If permissions present, publish the story
[self publishStory];
}
...
returns the following error:
* Terminating app due to uncaught exception 'com.facebook.sdk: InvalidOperationException', reason: 'FBSession: an attempt was made
reauthorize permissions on an unopened session'
What is happening can? Thank you!
EDIT:
Ran my friend, thank you very much, but still have a detail ...When'll post the first time he asks to authorize the application I authorize this block of fall
/*
* open a new session with publish permission
*/
[FBSession openActiveSessionWithPublishPermissions:[NSArray arrayWithObject:#"publish_actions"]
defaultAudience:FBSessionDefaultAudienceOnlyMe
allowLoginUI:YES
completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
if (!error && status == FBSessionStateOpen) {
[self publishStory];
}else{
NSLog(#"error");
//Here I get the error mentioned below
}
}];
}
with the error: error:
domain = com.facebook.sdk, code = 5
The error says that the FBSession is not opened. so you should check if the session is opened before trying to reauthorize.
if ([[FBSession activeSession] isOpen]) {
/*
* if the current session has no publish permission we need to reauthorize
*/
if ([[[FBSession activeSession] permissions]indexOfObject:#"publish_actions"] == NSNotFound) {
[[FBSession activeSession] requestNewPublishPermissions:[NSArray arrayWithObject:#"publish_actions"] defaultAudience:FBSessionDefaultAudienceFriends
completionHandler:^(FBSession *session,NSError *error){
[self postPhoto];
}];
}else{
[self publishStory];
}
}else{
/*
* open a new session with publish permission
*/
[FBSession openActiveSessionWithPublishPermissions:[NSArray arrayWithObject:#"publish_actions"]
defaultAudience:FBSessionDefaultAudienceOnlyMe
allowLoginUI:YES
completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
if (!error && status == FBSessionStateOpen) {
[self publishStory];
}else{
NSLog(#"error");
}
}];
}
Make sure to consistently request for the same permissions which should be publish_actions (mind the plural).
You also need another method in AppDelegate:
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
// attempt to extract a token from the url
return [FBAppCall handleOpenURL:url
sourceApplication:sourceApplication
fallbackHandler:^(FBAppCall *call) {
NSLog(#"In fallback handler");
}];
}
This will handle the url callback if the authentication is done in safari. After that the FBSession will be open.
I'm using die Facebook SDK 3.1.1 to implement FB Connect in my iOS application. This works fine in the simple case with either the new FB integration (logged in on iOS) or falling back to the normal authorization via web view (I do not have the native Facebook application installed in both cases).
The problem occurs when I switch the account on iOS level. Logging out and logging in with a different FB user account.
To log in/authorize I perform:
[FBSession openActiveSessionWithReadPermissions:nil allowLoginUI:allowLoginUI
completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
[self sessionStateChanged:session state:state error:error];
}];
If then get a FBSessionStateClosedLoginFailed every time even though I perform a closeAndClearTokenInformation when that state is reached:
- (void)sessionStateChanged:(FBSession *)session
state:(FBSessionState) state
error:(NSError *)error
{
NSLog(#"Session State Changed: %u", [[FBSession activeSession] state]);
switch (state) {
case FBSessionStateOpen:
break;
case FBSessionStateClosed:
case FBSessionStateClosedLoginFailed:
NSLog(#"FBSessionStateClosedLoginFailed ERROR: %#", [error description]);
[[FBSession activeSession] closeAndClearTokenInformation];
break;
default:
break;
}
However, I receive the same state on every retry. My log says the following:
FBSDKLog: FBSession **INVALID** transition from FBSessionStateCreated to FBSessionStateClosed
FBSDKLog: FBSession transition from FBSessionStateCreated to FBSessionStateCreatedOpening
FBSDKLog: FBSession transition from FBSessionStateCreatedOpening to FBSessionStateClosedLoginFailed Session State Changed: 257
FBSessionStateClosedLoginFailed TOKEN: (null)
FBSessionStateClosedLoginFailed ERROR: Error Domain=com.facebook.sdk Code=2 "The operation couldn’t be completed. (com.facebook.sdk error 2.)" UserInfo=0xb24cc20 {com.facebook.sdk:ErrorLoginFailedReason=com.facebook.sdk:ErrorLoginFailedReason}
Can anyone reproduce this or has any idea where the problem might lie?
Another answer gives a way to manually resync the device with the server. I defined a method called fbRsync to call this code. Make sure to #import <Accounts/Accounts.h> in your implementation file and then define this method:
-(void)fbResync
{
ACAccountStore *accountStore;
ACAccountType *accountTypeFB;
if ((accountStore = [[ACAccountStore alloc] init]) && (accountTypeFB = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook] ) ){
NSArray *fbAccounts = [accountStore accountsWithAccountType:accountTypeFB];
id account;
if (fbAccounts && [fbAccounts count] > 0 && (account = [fbAccounts objectAtIndex:0])){
[accountStore renewCredentialsForAccount:account completion:^(ACAccountCredentialRenewResult renewResult, NSError *error) {
//we don't actually need to inspect renewResult or error.
if (error){
}
}];
}
}
I then call fbResync if openActiveSessionWithReadPermissions yields an error:
[FBSession openActiveSessionWithReadPermissions:permissions
allowLoginUI:YES
completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
if(error)
{
NSLog(#"Session error");
[self fbResync];
[NSThread sleepForTimeInterval:0.5]; //half a second
[FBSession openActiveSessionWithReadPermissions:permissions
allowLoginUI:YES
completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
[self sessionStateChanged:session state:state error:error];
}];
}
else
[self sessionStateChanged:session state:state error:error];
}];
The half a second delay is likely unnecessary, but it currently gives me piece of mind.
This seems to solve the problem for me. I can now switch between Facebook accounts and am able to log in. Yay!
I had the same problem. Check that your FB App is enabled in Settings -> Facebook.
Mine was disabled (even though I don't remember disabling it) and once I enabled it, it was fixed.
In my test process, I've added and removed my FB App several times from my FB Account, which is linked with my iPhone. It may explain why, magically, my app was disabled.
In ios 6 with fb sdk 3.1.1. Please pass permissions param as "nil or email" in "[FBSessio openActiveSessionWithReadPermissions..." method. Here my code it was works great.
#define IOS_NEWER_OR_EQUAL_TO_6 ( [ [ [ UIDevice currentDevice ] systemVersion ] floatValue ] >= 6.0 )
-(void)showFBLogin
{
[FBSession.activeSession closeAndClearTokenInformation];
NSArray *permissions = [NSArray arrayWithObjects:#"email, publish_actions, publish_stream", nil];
#ifdef IOS_NEWER_OR_EQUAL_TO_6
permissions = nil; or NSArray *permissions = [NSArray arrayWithObjects:#"email",nil];
#endif
NSLog(#"\npermissions = %#", permissions);
[FBSession openActiveSessionWithReadPermissions:permissions
allowLoginUI:YES
completionHandler:
^(FBSession *session,
FBSessionState state, NSError *error) {
NSLog(#"\nfb sdk error = %#", error);
switch (state) {
case FBSessionStateOpen:
[[FBRequest requestForMe] startWithCompletionHandler:
^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
if (!error) {
//success
}
}];
break;
case FBSessionStateClosed:
//need to handle
break;
case FBSessionStateClosedLoginFailed:
//need to handle
break;
default:
break;
}
}];
}
I have the same problem on 3.1.3 FB SDK with iOS7.1. And I find a solution here. Hope it help!!
I have tried all answers here.
#loganathan nil permissions, #ill_always_be_a_warriors fbResync.
All of those don't work for me.
But I found it will works well when I launch the same code in iPhone 7.1 simulator
(without SSO"Single Sign On")
The same code works well on old version iOS FB SDK(not sure which version, but not 3.13)
(but no SSO will show when try to login)
So, I try to re-write a sample problem. I found several different here.
1. https://developers.facebook.com/docs/ios/getting-started Add new FacebookDisplayName
2. I modify my BundleID for iTune connect but I am not update it back to Faceboook App Dev
After modify those setting, it works on my iOS app with SSO feature.
Hope it help!!
Did you Try the RenewSystemCredential Methods? Take a look at this post:
Facebook iOS SDK extendAccessToken not Working - fbDidExtendToken not being called
I got the same error. But i used #ill_always_be_a_warriors method: -(void)fbResync but not work for me.
I finally found it's my permissions issue, i removed offline_access permission, it works, hope it helps some one.