I have successfully logged user to Facebook using Facebook Graph API and now i need to fetch the user's Facebook page list (page status is already changed to Published).
My code looks like :
(void)checkLoginWithFacebook {
// If the session state is any of the two "open" states when the button is clicked
if (FBSession.activeSession.state == FBSessionStateOpen
|| FBSession.activeSession.state == FBSessionStateOpenTokenExtended) {
// Close the session and remove the access token from the cache
// The session state handler (in the app delegate) will be called automatically
// If the session state is not any of the two "open" states when the button is clicked
[self getListOfPages];
}
else
{
// Open a session showing the user the login UI
// You must ALWAYS ask for basic_info permissions when opening a session
// This will bypass the ios6 integration since it does not allow for a session to be opened
// with publish only permissions!
FBSession* sess = [[FBSession alloc] initWithPermissions:[NSArray arrayWithObjects:#"publish_actions",nil]];
[FBSession setActiveSession:sess];
[sess openWithBehavior:(FBSessionLoginBehaviorForcingWebView) completionHandler:^(FBSession *session, FBSessionState state, NSError *error)
{
[[AppDelegate appDel] sessionStateChanged:session state:state error:error];
if (state == FBSessionStateClosed || state == FBSessionStateClosedLoginFailed)
{
NSLog(#"session closed");
return ;
}
[self getListOfPages];
}];
}
}
(void)getListOfPages {
[FBRequestConnection startWithGraphPath:#"/me/accounts"
completionHandler:^(
FBRequestConnection *connection,
id result,
NSError *error
) {
/* handle the result */
NSLog(#"pages result: %# ",result);
}];
}
Response:
pages result: {
data = ();
}
Please Advice. Thanks.
Have you requested the manage_pages permission from the respective user through the login dialog? The code you posted look ok IMHO, I think you see an empty result because of the missing permission.
Related
Note: I am following the native login advice from Native Facebook Login stopped working after SDK update to 3.14.
The error is as follows:
2014-10-13 20:03:27.378 Registration[1916:407643] Error
Domain=com.facebook.sdk Code=9 "Access has not been granted to the
Facebook account. Verify device settings." UserInfo=0x1753c630
{NSLocalizedDescription=Access has not been granted to the Facebook
account. Verify device settings., NSLocalizedFailureReason=Access has
not been granted to the Facebook account. Verify device settings.}
This is the code below:
// RegistrationManager.m
- (void)setupFacebook
{
FBSessionStateHandler completionHandler = ^(FBSession *session, FBSessionState status, NSError *error) {
[self sessionStateChanged:session state:status error:error];
};
if ([FBSession activeSession].state == FBSessionStateCreatedTokenLoaded)
{
// we have a cached token, so open the session
[[FBSession activeSession] openWithBehavior:FBSessionLoginBehaviorUseSystemAccountIfPresent
completionHandler:completionHandler];
}
else
{
[self clearAllUserInformation];
// create a new facebook session
FBSession *fbSession = [[FBSession alloc] initWithPermissions:#[#"public_profile"]];
[FBSession setActiveSession:fbSession];
[fbSession openWithBehavior:FBSessionLoginBehaviorUseSystemAccountIfPresent completionHandler:completionHandler];
}
}
- (void)clearAllUserInformation
{
[FBSession.activeSession closeAndClearTokenInformation];
[FBSession renewSystemCredentials:^(ACAccountCredentialRenewResult result, NSError *error) {
NSLog(#"%#", error);
}];
[FBSession setActiveSession:nil];
}
// RegistrationViewController.m
- (IBAction)loginButtonPressed:(id)sender
{
// If the session state is any of the two "open" states when the button is clicked
if (FBSession.activeSession.state == FBSessionStateOpen
|| FBSession.activeSession.state == FBSessionStateOpenTokenExtended)
{
// Close the session and remove the access token from the cache
// The session state handler (in the app delegate) will be called automatically
[FBSession.activeSession closeAndClearTokenInformation];
// If the session state is not any of the two "open" states when the button is clicked
} else
{
FBSessionStateHandler completionHandler = ^(FBSession *session, FBSessionState status, NSError *error) {
[registrationManager sessionStateChanged:session state:status error:error];
};
// create a new facebook session
FBSession *fbSession = [[FBSession alloc] initWithPermissions:#[#"public_profile"]];
[FBSession setActiveSession:fbSession];
[fbSession openWithBehavior:FBSessionLoginBehaviorUseSystemAccountIfPresent completionHandler:completionHandler];
}
}
When I click on the button, it simply says
2014-10-13 20:03:29.560 Registration[1916:407643] Session closed
2014-10-13 20:03:29.561 Registration[1916:407643] User logs out.
2014-10-13 20:03:29.573 Registration[1916:407643] User logs out.
It means that the user once selected "Didn't allow" in the pop-up that asks for permission. If he has his Facebook account linked in Settings, from now on, every time he'll try to login it'll show this error. It won't fallback to Safari or anything, just show this error. The user needs to got into Settings -> Facebook and set the slider for your app to ON.
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 followed a little 'guides online, but I can not figure out how to get the username of the user such as Facebook.
The login and session work properly.
But I can not just take the values of the current user.
This is the working code
if (!appDelegate.session.isOpen) {
// create a fresh session object
appDelegate.session = [[FBSession alloc] init];
// if we don't have a cached token, a call to open here would cause UX for login to
// occur; we don't want that to happen unless the user clicks the login button, and so
// we check here to make sure we have a token before calling open
if (appDelegate.session.state == FBSessionStateCreatedTokenLoaded) {
// even though we had a cached token, we need to login to make the session usable
[appDelegate.session openWithCompletionHandler:^(FBSession *session,
FBSessionState status,
NSError *error) {
NSLog(#"SESSION FACEBOOK OK");
// how i get username ?
Thanks in advance
Learn how to use the Facebook Graph API.
To request the user info:
[FBRequestConnection startForMeWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error) {
// Success! Include your code to handle the results here
NSLog(#"user info: %#", result);
} else {
// An error occurred, we need to handle the error
// See: https://developers.facebook.com/docs/ios/errors
}
}];
I have a VC with a button hooked up to do a facebook share of some text and an image url.
I use the FB api which opens the FB webview - for the user to login. It then presents the share window with a "Skip" or "Share" button as shown...
I have in my app the following code to take care of the login and button actions ....
For some reason the "Skip" also posts as if the "OK" was hit. I tried cheking thr error code returned using the Error Utility but that does not work (app never gets into that section of code and "CANCELLED OUT" is never logged in NSLog, even when I hit the Skip button)
Any help with this will be most appreciated. Perhaps some way to recheck permissions?
(void)postStatusUpdate:(id)status
{
if (FBSession.activeSession.state != FBSessionStateCreatedTokenLoaded || [FBSession.activeSession.permissions
indexOfObject:#"publish_actions"] == NSNotFound) {
// Permission hasn't been granted, so ask for publish_actions
[FBSessionopenActiveSessionWithPublishPermissions:#[#"publish_actions"]
defaultAudience:FBSessionDefaultAudienceFriends
allowLoginUI:YES
completionHandler:^(FBSession *session, FBSessionState state,
NSError *error) {
[selfsessionStateChanged:session state:state error:error];
if([FBErrorUtilityerrorCategoryForError:error] ==
FBErrorCategoryUserCancelled)
{
NSLog(#"SNFacebookClient: CANCELLED OUT!!");
}
if (FBSession.activeSession.isOpen && !error) {
// Publish the story if permission was granted
[selfpublishStory:status];
}
}];
} else {
// If permissions present, publish the story
[selfpublishStory:status];
}
}
code here
I even tried in lldb to check the permissions array after "Skip" was pressed ...
po [FBSession activeSession].permissions
And find that even when skip is pressed the array contains the entry "publish_actions"
You need to check the session status, if the status is FBSessionStateOpen or FBSessionStateCreatedTokenLoaded, you can fetch user's data.
Otherwise, something wrong happen or user skipped it.
This approach is different of you, check my short comments to you understand the steps.
// Suppose my FBSession is stored in a property called session
#property (nonatomic, strong) FBSession *session;
// The session getter can be implemented like this
- (FBSession *)session
{
if(!_session)
{
_session = [[FBSession alloc] initWithPermissions:readPermissions];
[FBSession setActiveSession:_session];
}
return _session;
}
// Opening a new session
[self.session openWithCompletionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
[self session:session stateChanged:status error:error];
}];
- (void)session:(FBSession *)session stateChanged:(FBSessionState)state error:(NSError *)error
{
switch(state)
{
case FBSessionStateOpen:
{
// Connection accepted
}
break;
case FBSessionStateCreatedTokenLoaded:
{
// Connection restored
}
break;
case FBSessionStateClosed:
// Connection closed
break;
case FBSessionStateClosedLoginFailed:
{
// Connection failed and closed
}
break;
case FBSessionStateCreated:
{
// Session created (not opened yet)
}
break;
case FBSessionStateCreatedOpening:
// Handler it if you need to do something while connection is opening
break;
case FBSessionStateOpenTokenExtended:
// Session token extended
break;
}
}
I'm using facebook-ios-sdk-3.10, Using this SDK I'll login and fetch user details from FB Its working fine for me.
This is the code I'm uisng
- (IBAction)fbLogin_click:(id)sender
{
if (AppDelegate.fbsession.state != FBSessionStateCreated) {
// Create a new, logged out session.
NSArray *permissions = [NSArray arrayWithObjects:#"offline_access", #"email", #"publish_stream", #"read_stream",#"read_friendlists",#"manage_friendlists",#"friends_about_me",#"publish_actions", nil];
// create a session object, with defaults accross the board, except that we provide a custom
// instance of FBSessionTokenCachingStrategy
AppDelegate.fbsession = [[FBSession alloc] initWithAppID:nil
permissions:permissions
urlSchemeSuffix:nil
tokenCacheStrategy:nil];
}
FBSessionLoginBehavior behavior = FBSessionLoginBehaviorForcingWebView;
if (AppDelegate.fbsession.state != FBSessionStateCreatedTokenLoaded) {
// even though we had a cached token, we need to login to make the session usable
[AppDelegate.fbsession openWithBehavior:behavior completionHandler:^(FBSession *session,
FBSessionState status,
NSError *error) {
if (error)
{
NSLog(#"Error");
}
[self GetFBUserDetails];
}];
}
}
-(void) GetFBUserDetails
{
if (AppDelegate.fbsession.isOpen)
{
[HUD show:YES];
// fetch profile info such as name, id, etc. for the open session
FBRequest *me = [[FBRequest alloc] initWithSession:AppDelegate.fbsession graphPath:#"me"];
self.pendingRequest= 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;
}
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) {
return;
}
[AppDelegate.fbsession closeAndClearTokenInformation];
[FBSession.activeSession close];
[FBSession.activeSession closeAndClearTokenInformation];
FBSession.activeSession=nil;
[self FacebookCustomerRegister:user];
}];
}
}
In such case some user create Facebook account and not very his account through email, when he try to login via my app it shows empty screen after click login button, there is no action further. how can I notify the user "You not yet verify your FB account" and it not return to my app. how can I fetch the response from there ?
can anyone help me for this ?
The email address you get from Facebook using the Graph API or a FQL query is a verified email. If an account hasn't verified it's email yet it's not possible to get it.
so when you fetch user info and if you are not getting the email when you have the permission to get then user is no verified and you can show an alert or any info to user about verifying the email and information
check more detail here Is it possible to check if an email is confirmed on Facebook?