Facebook apprequests with 3.0 SDK - ios

I am using Facebook iOS SDK 3.1.1 and has been successfully integrated a lot of Facebook features. Adhering to 3.1.1, I am logging in using
[FBSession openActiveSessionWithPermissions:permission
allowLoginUI:bAllowLoginUI
completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
[self sessionStateChanged:session state:state error:error];
}];
Then I need to send "apprequests", and there is no new method to implement in SDK 3.1, so I've to fallback to the deprecated API using Facebook objects and FBDialog.
However, calling the deprecated dialog function:
[m_pFacebook dialog:#"apprequests"
andParams:params
andDelegate:delegate];
results in the FBDialog popping up and prompting the user to login again through the dialog. I need to go directly to the apprequests dialog without needing the user to input their credentials again and I am sure there's a way to do it as I've seen it implemented in Diamond Dash and other games.
I've tried setting the m_pFacebook.accessToken with FBSession.activeSession.accessToken, and I have also make sure that m_pFacebook.session is filled with the FBSession's logged in session
Anyone encountered this problem before?

After some debugging, figured out that the expirationDate of Facebook *m_pFacebook object has not been updated, therefore the _lastAccessTokenUpdate is still in [NSDate distantPast]. The solution is to call
[m_pFacebook fbDialogLogin:session.accessToken expirationDate:session.expirationDate];
when sessionStateChanged to FBSessionStateOpen
- (void) sessionStateChanged:(FBSession*)session state:(FBSessionState)state error:(NSError*)error {
switch ( state ) {
case FBSessionStateOpen:
[m_pFacebook fbDialogLogin:session.accessToken expirationDate:session.expirationDate];
break;
}
}

Related

Unable to login via Facebook (Parse): error code 251

I have an app in the App Store which is using Parse and automatically creates anonymous users (I set [PFUser enableAutomaticUser]). So now I have several thousands of users in a Parse users table.
Now I'm trying to implement full profiles and convert anonymous users to non-anonymous by calling:
[PFFacebookUtils linkUser:currentUser permissions:#[#"public_profile", #"email", #"user_friends"] block:^(BOOL succeeded, NSError *error) {
if (succeeded) {
//some logic
} else {
NSLog(#"Error: %#", error);
}
}];
BTW I've also tried:
[PFFacebookUtils logInWithPermissions:#[#"public_profile", #"email", #"user_friends"] block:^(PFUser *user, NSError *error) {
if (!user) {
NSLog(#"Uh oh. The user cancelled the Facebook login.");
} else if (user.isNew) {
NSLog(#"User signed up through Facebook!");
} else {
NSLog(#"User logged in through Facebook!");
}
}];
But in both cases I get an error: 251 - The supplied Facebook session token is expired or invalid.
What I've already tried:
Logout anonymous user
Refresh session
Close and re-auth session
Nothing here works for me. Does anyone know what to do in this case? How do I correctly convert anonymous user to non-anonymous?
I'm pretty sure the problem is your Facebook App configuration.
Please go to your Facebook App settings (Advanced section) https://developers.facebook.com/apps/YOUR_FB_APP_ID/settings/advanced/
You should have enabled the option "Native or desktop app?" When you do so, you'll have other option with the message "Is your App Secret embedded?" The error 251 on iOS only comes up when you enable this second option because your app secret is not embedded so the token is invalid.
Please go to your settings and make sure the option "Is your App Secret embedded?" is NOT enabled.
I hope it helps.
verify your fb dev account at "Approved Items" > "Login Permissions" must be the same as you requesting in your permissions array in your code. In my case I am using the new API 2.0.
Hope you help it.
Regards from Cancun
The problem for me was that i copied the App Secret when it was in dots, click on the show button in your Developer Settings and copy the string in there on to Parse.
Hope it helps.

FBSession.activeSession.permissions does not appear to accurately depict the valid granted permissions

I am observing the following....
I authenticate a user via the following (note that in the completion block I am nslogging the permissions)
NSArray *permissions = [[NSArray alloc] initWithObjects:
#"email", #"publish_actions",
nil];
[FBSession openActiveSessionWithPublishPermissions:permissions
defaultAudience:FBSessionDefaultAudienceFriends
allowLoginUI:allowLoginUI
completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
NSLog(#"permissions %#",FBSession.activeSession.permissions);
}];
As a user I start up the app and proceed to login w/ FB.
I am presented with a screen that reads "app would like to access your public profile, friend list and email address." and I select "ok"
I am presented with a screen that reads "app would like to post to your friends on your behalf" and I select "skip".
3) The completion block code spits out the permissions as the following
permissions (
email,
"publish_actions"
)
Why is publish_actions listed? If I try to post to FB now through the app it will error out and tell me that I don't have the right permissions......yet I cannot check for this case b/c FBSession.activeSession.permissions tells me that I have the "publish_actions" permission even when in reality I do not.
What am I missing here?
If you were using iOS SDK 3.0, then this was due to a bug in the SDK. See the bug report for more details.
Symptom summary:
After authorizing user with openActiveSessionWithPermissions method, the sessions variable in callback method contains extended permissions that were not allowed by a user.

Change or show privacy setting when using Feed Dialog

My app is posting to facebook with help of Feed Dialog, but unfortunately public audience of my post is only-me. When I'm trying to set privacy key in publish params for friends visibility:
NSMutableDictionary *params =
[NSMutableDictionary dictionaryWithObjectsAndKeys:
#"my app_id", #"app_id",
#"my app name", #"name",
#"some text.", #"caption",
#"some more text.", #"description",
#"web site link", #"link",
#"some picture link", #"picture",
#"ALL_FRIENDS", #"privacy",
nil];
So when adding #"ALL_FRIENDS", #"privacy", I receive an error in Dialog window when I try to publish: Error100 (I'm using incorrect privacy parameter).
So my question is how can I change this parameter or how can I let user to change it Feed dialog window (I'm using 3.5 facebook SDK).
Thanks in advance!
I'm not sure you'll be able to override the Only Me setting that the user has set in their privacy settings. In general, to get past the dialog error, you can try:
#"{'value': 'ALL_FRIENDS'}", #"privacy",
I know this setting works with Graph API posts (ex: me/feed) when I set the privacy level to something less than what the user has specified to be their ceiling. So if their ceiling is Only Me, the post will show up as Only Me. If their ceiling is Friends and I set the privacy to SELF then I get a post that's Only Me.
You can consider using the new Share Dialog (in 3.5.2). It allows the user to select their privacy. The Feed Dialog windows does not have a privacy selector.
For a comparison of the different share options, see https://developers.facebook.com/docs/howtos/share-dialogs-ios-sdk/
OK, so what have I done to solve the problem:
1.I'm closing any active session when my app launches:
FBSession* currentSession = [FBSession activeSession];
if(currentSession) {
[currentSession close];
}
2.Establishing new connection with friends as default audience
[FBSession openActiveSessionWithPublishPermissions:[NSArray arrayWithObject:#"publish_actions"]
defaultAudience:FBSessionDefaultAudienceFriends
allowLoginUI:YES
completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
if (!error && status == FBSessionStateOpen) {
[self publishWithWebDialog];
}else{
NSLog(#"error");
}
}];
3.Calling method for publishing with Feed Dialog:
[self publishWithWebDialog];
The fun part starts when application is launched for the second time :) There is no need to press all that OK buttons and application just opens Feed dialog, by the way this approach also fixes the problem with deleting application in Facebook from users Account Settings - > Apps.

Facebook iOS Select Friends Table Blank

I am trying to add the "select friends" to my iOS app. I set up the login view. Once I login I open the friend picker but it comes up blank. I see the table with the done and cancel buttons but there are no friends loaded into the table.
- (IBAction)selectFriendsButtonAction:(id)sender {
if (self.friendPickerController == nil) {
// Create friend picker, and get data loaded into it.
self.friendPickerController = [[FBFriendPickerViewController alloc] init];
self.friendPickerController.title = #"Select Friends";
self.friendPickerController.delegate = self;
}
[self.friendPickerController loadData];
[self.friendPickerController clearSelection];
[self presentViewController:self.friendPickerController animated:YES completion:nil];
}
Prior to opening the friend picker controller ensure your Facebook session is active by calling this:
if (!FBSession.activeSession.isOpen) {
// if the session is closed, then we open it here, and establish a handler for state changes
[FBSession.activeSession openWithCompletionHandler:^(FBSession *session,
FBSessionState state,
NSError *error) {
// Handle error
}];
}
There's two things you need to take care of that you may well not realize you need even if you understand the rest of the Facebook SDK pretty well.
The dialog will only show friends that have also installed the app.
You have to ask for the user_friends permission during your login flow.
For 1., create or use a test user you already have and run your app with that user in order to authorize the app for basic access ("install" it).
For 2, add that permission to your login flow, log out and back in with the sender you're testing (probably your own user), and if you don't get prompted to grant it even then, uninstall the app via https://www.facebook.com/settings/?tab=applications.
http://www.brianjcoleman.com/tutorial-get-facebook-friends-in-swift/ discusses some of this. The Facebook docs themselves either don't mention the 2 issues at all or it's buried.
If you use "FBFriendPickerViewController", it seems return friends who also use this APP. In Facebook document: after API Graph v2.0, "me/friends" will only return friends that also use the app. I think that's why the friend table is blank.
There is another option that you can use "FBTaggableFriendPickerViewController" instead. But your APP will need to be reviewed by Facebook before it can get data back. (https://developers.facebook.com/docs/graph-api/reference/v2.2/user/taggable_friends?locale=zh_TW)

reauthorizeWithPublishPermissions handler is called with ErrorReauthorizedFailedReasonUserCancelled

I'm using iOS SDK 3.1.1 and trying to get both read and publish permission at once.
As tutorial says, I'm calling FBSession openActiveSessionWithReadPermissions and in its handler - handler A - call [[FBSession activeSession] reauthorizeWithPublishPermissions only if handler A is called with session state of FBSessionStateOpen.
When I have facebook account is set in iOS 6's setting, reauthorizeWithPublishPermissions's handler - handler B - is called normally, with error argument of nil.
However, if I don't have facebook account set in iOS 6's setting, handler B is called with reauth error named "ErrorReauthorizeFailedReasonUserCancelled" when app is switched to Safari to gain publish permission.
More weird thing is this. In both cases before handler B is called, handler A is called with session state of FBSessionStateOpenTokenExtended.
Are these normal or expected behavior of new SDK? If so, should I not check if error is nil in handler B?
happened to me and after searching a while I found a solution for that. You have to call reauthorizeWithPublishPermissions in dispatch_async in the handler A of openActiveSessionWithReadPermissions:
dispatch_async(dispatch_get_current_queue(), ^{
[[FBSession activeSession] reauthorizeWithPublishPermissions:permissions
defaultAudience:FBSessionDefaultAudienceEveryone
completionHandler:^(FBSession *session, NSError *error) {
// handle the flow here
}];
});

Resources