Changing defaultAudience when sharing to a feed using Facebook IOS SDK - ios

Using the IOS SDK for Facebook (3.1) , I find that once I set up my project, I am unable to change the default audience.
For instance, I set up my test project to publish to "Only Me". It works fine. I am working off of this example, making the change that I start out with audience "Only Me".
http://developers.facebook.com/docs/howtos/publish-to-feed-ios-sdk/
Then I arrange to call the following:
[FBSession.activeSession
reauthorizeWithPublishPermissions:
[NSArray arrayWithObject:#"publish_actions"]
defaultAudience:FBSessionDefaultAudienceFriends
completionHandler:^(FBSession *session, NSError *error) {
if (!error) {
// If permissions granted, publish the story
NSLog (#"Here goes nothing");
[self publishStory];
}
}];
which should publish the story to DefaultAudienceFriends. However, it continues to publish to Only Me.
Shouldn't this work? Am I missing something?

Ok, here is the answer I came up with, which addresses my particular need. I change the privacy settings for the app, in Facebook, here:
http://www.facebook.com/settings?tab=applications
And come to think of it, this makes sense. I, as a user of this app (which I happened to create, but that probably isn't relevant), am specifying the behavior it displays when it posts on my behalf.
So I'm happy, because now I can work on my app, freely test it, without disturbing anybody. And I can change it to post more widely, when I'm ready.

During the authorization flow you set the default audience, in your case "Only Me". Now that your app has permissions trying to reauthorize will likely do nothing, unless you probably logout and back in. What you can try doing instead is passing the audience you want as a part of the post parameter.
So, based on the sample, let's say you wanted "Only Me", you would add:
[self.postParams setObject:#"{'value':'SELF'}",
forKey:#"privacy"];
And if you wanted "Friends", you would use:
[self.postParams setObject:#"{'value':'ALL_FRIENDS'}",
forKey:#"privacy"];

Related

Limit permissions when accessing Facebook using Accounts framework

I need some help on this one ....
So the problem I am facing is that while fetching the Facebook account from ACAccount, the alert view informs too many permissions. I am getting an alert box when I use the ACAccount login for facebook.
It says APP_NAME would like to access your basic profile info and list of friends
This shows up even when my permissions set is an empty array.
NSArray * FB_PERMISSIONS = #[];
// or FB_PERMISSIONS = #[#"public_profile", #"likes", #"email"];
// It does not matter what the array is -> The alert has extra sentences.
ACAccountType *FBaccountType= [_accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
NSString *key = [[NSBundle mainBundle] objectForInfoDictionaryKey:#"FacebookAppID"];;
NSDictionary *dictFB = [NSDictionary dictionaryWithObjectsAndKeys:key,ACFacebookAppIdKey,FB_PERMISSIONS,ACFacebookPermissionsKey, nil];
[_accountStore requestAccessToAccountsWithType:FBaccountType options:dictFB completion:
What am I trying to do here?
I am just needing the "public_profile", #"email" and "likes". The alert says APP_NAME would like to access your profile, and likes on your behalf. In addition, APP_NAME would like to access your basic profile info and list of friends
Why is that second sentence there? How do I get rid of it? I can see a number of apps where the second line that talks about basic profile and list of friends does not show up.
Expected result:
APP_NAME would like to access your profile and likes.
Update:
Check my answer for solution.
There is nothing in the FB SDK docs that explain any of this. They made this way so that users can use the Facebook pop UI and pick the permissions they want to authorize. I guess Facebook design's philosophy is to give as much control and transparency to the user. But with the OS pop-up it hides a lot of permissions underneath. I guess it's Apple's design philosophy to show minimal information. This works best for developers scenario, as users usually freak out when they see so many permissions being asked by the app.
Anyway, if you take a look at FBSDKLoginManager+Internal.h you can checkout the capabilities for System login. Further digging, I've discovered that FBSDKLoginButton is pointless. The best way to go about this is using your own instance of FBSDKLoginManager, and set the system account type to be native, and if you get the error code 306, fall back to default login mechanism.
Somehow ->> This way does not show additional permissions. I have no idea how. All I know is that everything falls into place now.
Further more, you will have to setup a separate listener for ACAccountStoreDidChangeNotification so that you can tie up some edge cases. But yes, \m/
The Fix
The fix to this problem involves adding code to the view header file as well as adding code to your view file. The code examples are listed below.
To the view header file add:
// ViewController.h
#import <FBSDKLoginKit/FBSDKLoginKit.h>
#interface ViewController : UIViewController
#property (weak, nonatomic) IBOutlet FBSDKLoginButton *loginButton;
#end
And to the view file add:
loginButton.readPermissions =
#[#"public_profile", #"email", #"likes"];
Note that the comment in the first example was just for reference.
Why did it happen?
The reason why your problem happened was because the Account Framework and Facebook API think by default that you mean every permission there is. It requires you to be more specific in the code. I am pretty sure that you for got to do the first example of code which was supposed to go in your view header file. I understand that the code above is not what you will put in the file you are working on, but it just gives you a rough idea on doing it.
Still Confused?
If you are still confused please comment below and I will try to update my answer. It would be really helpful if you could send the code you were doing with he arrays filled not blank. If I wasn't clear please tell me and I will do the best I can to help. Sorry if there is any inconvenience!
Sources
Mainly, I found the info on here: https://developers.facebook.com/docs/facebook-login/permissions/overview and over here: https://developers.facebook.com/docs/facebook-login/ios#permissions
Facebook is pretty trustworthy and creditable. I think...
Is there a reason you're not using the Facebook API instead? Requesting access via iOS APIs will require the user to be logged into Facebook via the iOS Settings. If you make the same request with Facebook's API, it can detect if the user is logged in via the settings, the FB app, or Safari. And if the user is not logged in, it'll prompt them to do so (as opposed to just erroring out and telling them to do so via settings)
Version 4.X:
https://developers.facebook.com/docs/facebook-login/ios/permissions
FBSDKLoginManager *loginManager = [[FBSDKLoginManager alloc] init];
[loginManager logInWithReadPermissions:#[#"public_profile", #"likes", #"email"]
fromViewController:self
handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) {
//TODO: process error or result
}];
Version 3.X
[FBSession openActiveSessionWithReadPermissions: #[#"public_profile", #"likes", #"email"]
allowLoginUI:YES
completionHandler:
^(FBSession *session, FBSessionState state, NSError *error) {
// Handle completion by calling AppDelegate
}];

Facebook Share Dialog: Permission Error - OAuth "Facebook Platform" "insufficient_scope (#200) Permissions error"

My requirement is here:
Share to Facebook from my app using Open Graph Action - using Share Dialog (because I don't want special dialog for login)
I request publish permission, and upon obtaining it I try to share via Post dialog. Here is the brief code I use:
[FBRequestConnection startWithGraphPath:#"/MY_FB_APP_ID/app_link_hosts"
parameters:paramsForAppLinksHost HTTPMethod:#"POST"
completionHandler:^(FBRequestConnection *connection, id result, NSError *error)
{
NSString * appLinkHostURLID = [result objectForKey:#"id"]; // store this ID in an NSString
if(error)
{
NSLog(#"error = %#", error.description);
}
else
{
[self ShareToFB : appLinkHostURLID]; //Code to share OG story via Share Dialog
}
}];
However, above error gives me this:
com.facebook.sdk:HTTPStatusCode=403, com.facebook.sdk:ParsedJSONResponseKey={
body = {
error = {
code = 200;
message = "(#200) Permissions error";
type = OAuthException;
};
};
The problem with Facebook SDK is that there is so much documentation and almost no support that I haven't got my previous questions answered too (where I was trying to share without permission), and this problem simply doesn't yield.
Somebody please tell - Is having FB app approved by Facebook a REQUIREMENT for this to work perfectly? If so, how does one correctly provide app store ID when the app isn't even live on Apple store? They use it even in code for applinks related permissions (see above).
The crux of the issue is that everything works with developer facebook login perfectly but fails with another FB user. This means that all my plist and everything is OK. However the FB app isn't submitted (and for many valid reasons such as my iOS app is still in development - how can one be expected to submit screenshots and all even before app is live?)
Someone please help...
OK, I figured it out myself - like many other developers.
1 - This error is due to the fact that FB app isn't approved for certain permissions but still trying to use / request that permission from user. publish_action is one such permission.
2 - In order to test this, facebook app developer needs to approve test users from within develolper.facebook.com portal.
3 - This test user is located in your FB app portal under:
a) Status & Review -> Items under Review section
and
b) Roles section.
You (FB app administrator Developer) need to add the user in b), and not a).
Then the user needs to approve your request. And in order to do that, he needs to register himself as FB developer too.
So much for neat documentation...one can easily get lost.
The github samples and all are great, but none of them tells the whole picture.
Alas, they modify their error descriptions instead.

AppCenter Rejection - missing (NOT) SSO

I have a problem with App Center Review. I have an iOS application which has the Single Sign-On implemented (I just tested it on both types of devices). Still, when I submit my app's page for App Center Review I always get the same message (see screenshot below).
I don't know what to do anymore. It has been like this for at least few months now. I checked everything in my application, even was able to post an update in the meantime, and the page still get's rejected. The message is always the same so I don't get any more info about the error (which in my opinion does not exists).
What should I do with this issue? Who can I contact directly about it (via email preferably)?
Edit #1: In my opinion I am using the native login screen. I am 100% sure that I use official FB API (downloaded from FB page). When I connect with FB in my application the screen that pops up is a screen from FB application (see below).
Edit #2: Okay, so I've implemented new way of logging in with FB but still native login view is not presented. Instead, the login screen of FB application opens up, which is exactly the same behaviour as before... I have the FacebookDisplayName set in the .plist file.
[FBSettings setDefaultAppID:#"some_facebook_app_id"];
[FBSettings setDefaultUrlSchemeSuffix:#"some_suffix"];
[FBSession openActiveSessionWithReadPermissions:#[#"basic_info"] allowLoginUI:TRUE completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
// handler logic goes here
}];
Edit #3: yeap, the new API was the solution. Thanks!

How to send custom message to one friend using iOS facebook-graph-api?

I have a philosophy multiplayer question-answering app that allows players to play against each other answering questions about philosophy and ethics. For signup i allow facebook-login. I have a list where a player can invite his facebook friends to play. Its done with a request to the app-backend with all players friends, and return which have installed the app.
For those who dont yet have installed the app, i want to let the player invite them to install the app. I haven't found a way to do this with iOS graph API. Is it possible when a player taps a friend (i have the fbID), to send a message with some custom text and a link to download the app?
With the webdialogs method it does not seem to allow custom text send to one specific player. And that method opens a new window with friend selection. I don't need that as the user allready has selected a friend to invite. Is there a way to use FBWebDialogs to do this, or any other method in the Facebook iOS API?
[FBWebDialogs
presentRequestsDialogModallyWithSession:nil
message:#"Learn how to make your iOS apps social."
title:nil
parameters:nil
handler:nil]
The way to do this is to set up a simple XMPP server on your server and send it using their XMPP login which you can get with the following code snippet.
if (![FBSession.activeSession.permissions containsObject:#"xmpp_login"]){
[[FBSession activeSession] requestNewReadPermissions:#[#"xmpp_login"] completionHandler:^(FBSession * session, NSError * error){
if (!error){
[self functionThatCommunicatesWithServerAndSendsXMPPLoginInformation];
} else {
// handle error
}
}];
}
There are some nice frameworks that make XMPP really easy to implement on a simple level, such as SleekXMPP for python/django.
It's definitely a little work to do this, but probably much more effective. Just don't spam.
For more guides (although I think a little outdated):
Facebook chat framework for iphone sdk

How to get native Facebook login on iOS using SDK 3.1?

I downloaded the new Facebook iOS SDK 3.1, which promises to have a native login prompt. I ran their sample login app on my iOS 6 device. When I attempted to connect with Facebook, I did not get a native login. Instead, the Facebook app launched - same as the old SDK. Their Facebook login button basically does this:
[appDelegate.session
openWithCompletionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
[self updateView];
}
];
I thought maybe the sample code isn't calling the right function. So I tried FBSession's other login function.
[appDelegate.session
openWithBehavior:FBSessionLoginBehaviorWithNoFallbackToWebView
completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
[self updateView];
}
];
I tried all possible behaviours and none of them popped up the native login prompt.
Did you log into Facebook from the iOS settings first?
Once you do that, their example project Scrumptious will use the native login prompt when you try to connect.
Read this: https://developers.facebook.com/docs/howtos/ios-6/#nativeauthdialog
Basically you must request basic permissions and read permissions first and then request publish permissions separately.
This is by design, and described in the second section of https://developers.facebook.com/docs/getting-started/facebook-sdk-for-ios/3.1/upgrading-from-3.0/
Basically, you are not able to ask for both read and publish permissions with the iOS6 dialog. Therefore you are more-or-less required to ask for them in a staggered way (e.g. read on first login, and then publish when your app actually needs to publish).
If you insist on using the deprecated method to try and get read & publish at the same time, the SDK has no choice but to return to the web or app-switched technique.

Resources