iOS Facebook SDK 3.2 Check Permissions via Graph Path Request - facebook

I am trying to check if user has already granted publish permission or not. if he has not granted permissions before then i navigate him to permissions screen via: requestNewPublishPermissions
-(void)checkPermissions
{
// Get the most recent status
[FBRequestConnection
startWithGraphPath:#"me/permissions"
completionHandler:^(FBRequestConnection *connection,
id result,
NSError *error) {
if (!error) {
//This Condition Never Executed
if([[result objectForKey:#"data"] objectForKey:#"publish_actions"])
{
//permissions exist
}
else
{
[self openSessionForPublishPermissions];
}
NSString *permission = [[result objectForKey:#"data"] objectForKey:#"publish_actions"];
NSLog(#"permissions data = %#",data);
}
else
{
NSLog(#"error"); //Control goes to this block
}
}];
}
In code above if(!error) block is never executed and it always returns Error
Where i'm going wrong? Am i missing something?

You can see permissions in the active session. Here is how it's done in the HelloFacebookSample :
if ([FBSession.activeSession.permissions indexOfObject:#"publish_actions"] == NSNotFound) {
// permission does not exist
} else {
// permission exists
}

Instead of manually checking the permissions, you could check if the session is active and request publish permissions: if the user has already granted the permissions, an additional confirmation dialog will not be posted. See the code sample below:
- (void)requestWritePermission:(UIViewController *)viewController channel:(NSString *)channel callback:(void(^)(BOOL success))callback
{
if ([FBSession.activeSession isOpen])
{
[FBSession.activeSession requestNewPublishPermissions:#[#"publish_actions"]
defaultAudience:FBSessionDefaultAudienceFriends
completionHandler:^(FBSession *session, NSError *error) {
callback(error == nil);
}];
}
else
{
// Attempt to request publish permission without read permission.
}
}
The code is not complete, but should get you started.

Related

iphone development: cannot open active Facebook session with publish permission

In my app I want to post a image on my wall however I think i miss something. I did lots of research and end up with that code. Actually it sometimes working but generally when the code is running since there is no session with publish_action permission, second part of the code is working but the problem is I always get error log at the second part, so I cant proceed...Do you have any idea why I cant open active session with publish permissions?
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_action"] defaultAudience:FBSessionDefaultAudienceOnlyMe
completionHandler:^(FBSession *session,NSError *error){
action();
}];
}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");
}
}];
}
In the first part of the code when you are requesting new publish permissions you have
[NSArray arrayWithObject:#"publish_action"] ....
If i am not not mistaken I think that should be [NSArray arrayWithObject:#"publish_actions"]
Here is code snip from facebook docs
https://developers.facebook.com/docs/technical-guides/iossdk/errors/
// Method that requests permissions needed to make the API call.
- (void)requestPermissionCallAPI {
[FBSession.activeSession
requestNewPublishPermissions:[NSArray arrayWithObject:#"publish_actions"]
defaultAudience:FBSessionDefaultAudienceEveryone
completionHandler:^(FBSession *session, NSError *error) {
if (error) {
// Handle new permissions request errors
[self handleRequestPermissionError:error];
} else {
// Make API call
...
}
}];
}

iOS Facebook SDK 3.5 publication. App name is not displayed (posts published via "iOS")

I want to make facebook publication on the iOS6. The way I do it:
Ask for read permission
Ask for publish permission
Call [FBDialogs presentOSIntegratedShareDialog...]
It works but in feed I see "via iOS" and I want to see my app name instead. How can it be fixed? If I make publications with Feed Dialog (web based) - my application name is displayed correct
- (IBAction)facebookShareButtonTaped:(id)sender
{
[FBSession openActiveSessionWithReadPermissions:#[#"email"]
allowLoginUI:YES
completionHandler:^(FBSession *session, FBSessionState status, NSError *error)
{
if (status == FBSessionStateOpen)
{
[FBSession.activeSession requestNewPublishPermissions:#[#"publish_actions"] defaultAudience:FBSessionDefaultAudienceOnlyMe completionHandler:^(FBSession *session, NSError *error) {
[self sendFacebookPost];
}];
}
}];
}
- (BOOL)sendFacebookPost
{
BOOL dialogShown = [FBDialogs presentOSIntegratedShareDialogModallyFrom:self initialText:#"" image:nil url:nil handler:^(FBOSIntegratedShareDialogResult result, NSError *error) {
if (error && [error code] == 7)
{
return;
}
if (error)
{
[self showAlert:[self checkErrorMessage:error]];
}
else if (result == FBNativeDialogResultSucceeded)
{
[self showAlert:#"Posted successfully."];
}
}];
return dialogShown;
}
You can specify the name that should show up by adding a new entry to the Information Property List within your plist file. Just add the key FacebookDisplayName with the name you want as its value.

Facebook SDK 3.1 error when posting from iOS app

I'm facing the following problems with my iOS app:
While publishing to user's friend's wall, using iOS app I'm getting the error "com.facebook.sdk error 5".
The app is asking to login every time when I check for "FBSession.activeSession.isOpen".
Everything was working fine before. But since I've changed my app ID (as now I have to use different Facebook app). I'm getting the error.
I've done some research on this and found some solutions. Ive tried them all but nothing works.
I've written the following code to login to Facebook:
- (BOOL)openSessionWithAllowLoginUI:(BOOL)allowLoginUI {
comingfromFB = YES;
NSArray *permissions = [[NSArray alloc] initWithObjects:
#"friends_birthday",
nil];
return [FBSession openActiveSessionWithReadPermissions:permissions
allowLoginUI:allowLoginUI
completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
[self sessionStateChanged:session state:state error:error];
}];
}
And the following code for publishing story:
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];
}
When I run the app I get the following error:
Error: HTTP status code: 403
2013-02-05 14:36:47.109 <appname>[1705:c07] Error Domain=com.facebook.sdk Code=5 "The operation couldn’t be completed. (com.facebook.sdk error 5.)" UserInfo=0xaa9af20 {com.facebook.sdk:ParsedJSONResponseKey={
body = {
error = {
code = 200;
message = "(#200) The user hasn't authorized the application to perform this action";
type = OAuthException;
};
};
code = 403;
}, com.facebook.sdk:HTTPStatusCode=403}
Please help me to understand where I'm going wrong.
I've also added some key-value pair to NSUserDefaults. Could that be a possible reason for that?
Thanks.
When you're first showing your view with post button, perhaps you want to check if the session is open and set your post button title according to session state. Assuming your button initially has "Post" title:
[FBSession openActiveSessionWithAllowLoginUI: NO];
if (![FBSession.activeSession isOpen])
{
[self setSendButtonTitle:NSLocalizedString(#"Log in",#"")];
}
Then add the following code to your Post button action:
- (void) send: (UIButton*) sender
{
if (![FBSession.activeSession isOpen])
{
[FBSession openActiveSessionWithPublishPermissions: [NSArray arrayWithObjects: #"publish_stream", nil]
defaultAudience: FBSessionDefaultAudienceEveryone
allowLoginUI: YES
completionHandler: ^(FBSession *session,
FBSessionState status,
NSError *error)
{
if (error)
{
NSLog(#"error");
}
else
{
[FBSession setActiveSession:session];
[self setSendButtonTitle: NSLocalizedString(#"Post",#"")];
}
}];
return;
}
// here comes the code you use for sending the message
}
So if the user presses send and the app is not authorized, it will perform a login operation and change your Post button title from "Log in" to "Post". Then the user will be able to post the message by pressing the button once again.
Hope it helps

How to login just in time to facebook in iOS app

Have reviewed the facbook pages on how to integrate facebook with iOS, but what i had been looking for is a bit different.
I would like to prompt for Facbook login only when a user decides to share stuff, the flow explained in FB docs walk thru how to login (handle asyc response from FB login) and show publish button, but what we need is to show "Post to FB" button, when the user clicks, i would like the user to login and then go to the preview of what is going to be posted and then post to FB.
I am using FB SDK and iOS 5, the difficulty is how to wire FB login flow directly to Post flow.
Thanks
Elango
Below is some code that I wrote that does this. If the user has not signed in to Facebook from the device settings, it is a better user experience to just call openActiveSessionWithPublishPermissions:, which does both the read and publish permissions in one step. Otherwise, you just do the two permissions serially. As soon as the read permission succeeds, you do the publish permission.
I tested this code on an iOS6 and iOS5 device, using Facebook SDK 3.2.1
- (BOOL)hasFacebookInDeviceSettings
{
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType *accountTypeFB = [accountStore accountTypeWithAccountTypeIdentifier:#"com.apple.facebook"];
BOOL hasFacebookBuiltinAccount = (accountTypeFB != nil);
return hasFacebookBuiltinAccount;
}
- (BOOL)hasLoggedInToFacebookInDeviceSettings
{
if (![self hasFacebookInDeviceSettings]) {
return NO;
}
BOOL result = [SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook];
return result;
}
- (void)openFacebookSessionWithAllowLoginUI:(BOOL)allowLoginUI
{
if (![self hasLoggedInToFacebookInDeviceSettings]) {
// Simpler if we don't have the built in account
[FBSession openActiveSessionWithPublishPermissions:#[#"publish_actions"]
defaultAudience:FBSessionDefaultAudienceFriends
allowLoginUI:allowLoginUI
completionHandler:^(FBSession *session,
FBSessionState state,
NSError *error) {
[self facebookSessionStateChanged:session
state:state
error:error];
}];
}
else if (!FBSession.activeSession.isOpen) {
__block BOOL recursion = NO;
[FBSession openActiveSessionWithReadPermissions:nil
allowLoginUI:allowLoginUI
completionHandler:^(FBSession *session,
FBSessionState state,
NSError *error) {
if (recursion) {
return;
}
recursion = YES;
if (error || !FBSession.activeSession.isOpen) {
[self facebookSessionStateChanged:session
state:state
error:error];
}
else {
assert(FBSession.activeSession.isOpen);
if ([FBSession.activeSession.permissions indexOfObject:#"publish_actions"] == NSNotFound) {
[FBSession.activeSession requestNewPublishPermissions:#[#"publish_actions"]
defaultAudience:FBSessionDefaultAudienceFriends
completionHandler:^(FBSession *session,
NSError *error) {
[self facebookSessionStateChanged:session
state:FBSession.activeSession.state
error:error];
}];
}
}
}];
}
}
hasFacebookInDeviceSettings tells you if this device even supports Facebook from the settings (i.e. this is iOS6+).
hasLoggedInToFacebookInDeviceSettings tells you if the user has signed into to Facebook from the iOS6 Facebook device settings.
You'll need to create your own facebookSessionStateChanged: and other code, as described in the login tutorial

iOS Facebook SDK - Check Permissions

I have a Facebook SSO working perfectly on my app, using last release of Facebook Objective-C SDK.
I need to ask an extra permission inside the app if user do "something". I don't need to ask that permission if user gave it to me before, so, I guess, in Facebook SDK there should be a method
-(BOOL) checkPermission:(NSString*) permission;
so I can use it like this:
if( [facebook checkPermission:#"email"] ) {
Is there a way to do this?
This question is a bit old but you can now check what permissions the active session has without making a graph request. Here is how it's done in the HelloFacebookSample :
if ([FBSession.activeSession.permissions indexOfObject:#"publish_actions"] == NSNotFound) {
// permission does not exist
} else {
// permission exists
}
Just replace "publish_actions" with "email".
SDK not providing direct method for checking specific permissions but you can check if user granted permission to your application by checking permissions connection of user object in Graph API
GET https://graph.facebook.com/me/permissions
Same can be achieved with FQL query on permissions table
SELECT email FROM permissions WHERE uid = me()
IMPORTANT: This seems to be true for an older version of the Facebook SDK (for example 3.9.0). In 3.15.0 it doesn't work this way anymore. You should use [session.permissions] as Raphaël Agneau says in his answer.
You have to use the following method, because [FBSession activeSession].permissions seems to return the permissions you requested, not the real ones.
[FBRequestConnection startWithGraphPath:#"/me/permissions"
completionHandler:^(FBRequestConnection *c, id result, NSError *error) {
if (!error) {
NSDictionary *permissions= [(NSArray *)[result data] objectAtIndex:0];
if (![permissions objectForKey:#"publish_actions"]) {
// Ok, continue with your logic
} else {
// Permission not found, maybe request it (see below)
}
} else {
// Treat error
}
}];
See here for more info:
https://developers.facebook.com/docs/facebook-login/ios/v2.0#permissions-checking
If the permission is not found you may want to request it this way:
[session requestNewPublishPermissions:PERMISSIONS_YOU_WANT
defaultAudience:FBSessionDefaultAudienceFriends
completionHandler:^(FBSession* session, NSError* error) {
// Try again the /me/permissions above
}];
Here's my code for FBSDK 4.2.0 for checking permissions. The string that's passed in is the name of the permission, e.g. "publish_actions"
- (void) checkForPermission:(NSString *)permission granted:(void (^)(void))sBlock denied:(void (^)(void))fBlock {
if ([FBSDKAccessToken currentAccessToken]) {
[[[FBSDKGraphRequest alloc] initWithGraphPath:#"me/permissions" parameters:nil] startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
BOOL hasPermission = NO;
if (!error) {
NSArray *permissions = [result objectForKey:#"data"];
for (NSDictionary *dict in permissions) {
if ([[dict objectForKey:#"permission"] isEqualToString:permission]) {
if ([[dict objectForKey:#"status"] isEqualToString:#"granted"]) {
hasPermission = YES;
}
}
}
}
if (hasPermission) {
(sBlock) ? sBlock() : sBlock;
} else {
(fBlock) ? fBlock() : fBlock;
}
}];
} else {
(fBlock) ? fBlock() : fBlock;
}
}
For the SDK 4+ you have these 2 ways of getting the permissions:
[[FBSDKAccessToken currentAccessToken] hasGranted:#"user_photos"]
or
[[[FBSDKAccessToken currentAccessToken] permissions] containsObject:#"user_photos"]