So when I am logged in to ios's facebook integration, my code works great. I get an active access token with permissions to read and write, and I have actually written to people's walls and whatnot from the app. However, when my app uses safari to authenticate people's login credentials, there is the common error: "An active access token must be used to query information about the current user."
What I don't understand is why I can only get my access code from the ios facebook integration. Anyways, my relevant code below is implemented by the current view controller when it loads:
if (![FBSession activeSession].isOpen) {
[self openSession];
}
my method openSession is defined as follows
- (void)openSession
{
//create the permissions array
NSArray *permissions =
[NSArray arrayWithObjects:#"email", #"basic_info", nil];
[FBSession openActiveSessionWithReadPermissions: permissions
allowLoginUI:YES
completionHandler: ^(FBSession *session, FBSessionState status, NSError *error) {
NSLog(#"\n\nopenSession called error = %#\n\n\n",error);
}];
}
I then go on to continue in the viewDidLoadMethod
[FBRequestConnection
startForMeWithCompletionHandler:^(FBRequestConnection *connection,
id<FBGraphUser> user,
NSError *error)
{
NSLog(#"error requestion connection: %#",error);
}];
I look forward to the response. Thanks in advance.
Using Facebook SDK.
NSString *fbAccessToken = [[[FBSession activeSession] accessTokenData] accessToken];
If you prefer dot syntax,
NSString *fbAccessToken = [FBSession activeSession].accessTokenData.accessToken;`
I hope , it will work for u
Related
I am working on getting posts from a public Facebook page using the Facebook Graph API, without the user logging in. Using the steps from here I got the Token I would need since the end-user is not logging in, and the page is public. In my app, I have the following:
-(IBAction)testing {
NSString *token = #"MYAccessToken";
FBSession* session = [[FBSession alloc] initWithPermissions:#[#"manage_pages"]];
FBAccessTokenData* tokenData =
[FBAccessTokenData createTokenFromString:token
permissions:#[#"manage_pages"]
expirationDate:nil
loginType:FBSessionLoginTypeNone
refreshDate:nil];
[session openFromAccessTokenData:tokenData completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
if ([session isOpen]) {
[self performGraph];
}
}];
}
-(void)performGraph {
NSLog(#"Go");
[FBRequestConnection startWithGraphPath:#"/{your-page}/posts"
parameters:nil
HTTPMethod:#"GET"
completionHandler:^(
FBRequestConnection *connection,
id result,
NSError *error
) {
NSLog(#"Result%#", result);
/* handle the result */
}];
}
It runs the method performGraph as I can see it in my Console, leading me to believe that the FBSession must be open, since that is where it runs it. However, I get the following error message in FBSDKLog: Error for request to endpoint '/{your-page}/posts': An open FBSession must be specified for calls to this endpoint.
If the FBSession isn't open, it shouldn't be even attempting to perform the Graph API call, yet it tells me it needs an open FBSession. Can someone help me out here a bit?
As provided by the documentation for startWithGraphPath:parameters:HTTPMethod:completionHandler: that method uses the [FBSession activeSession], and since you're creating a new session object, it is NOT the activeSession, which is why you're effectively calling the graph API with a nil session.
You can either set the session you created as the activeSession by calling FBSession.activeSession, or you can create an FBRequest object with your session instance, and then create a FBRequestConnection with the FBRequest.
Edit: No work around yet, but Facebook in there own SDK seemed to have deprecated using the system FB sign-on. I tried the latest SDK, and it just completely ignores the system sign-on. Unfortunately I can' used the latest SDK as, despite using the "legacy" setting, it still returns a token which doesn't give me what I need. It might be useful to see how they're bypassing the system settings though!
Original Q
I have an app which is using Facebook to authenticate.
I'm using the Facebook SDK (3.13.1 - the last pre api v2 version)
If I attempt to authenticate, as long as I don't have a FB account setup in the system settings, everything works fine. The app launches either the FB mobile app or mobile Safari to login an prompts me to grant the necessary permissions.
As soon as there is a system account setup, it fails silently. I'm deleting the app in between runs to ensure that the lack of permissions isn't persisting. If I run some of the FB sample apps which come with the SDK, they prompt for permission just fine, so it is obviously a problem with my app or the configuration of the Facebook app.
I've looked at these 2 similar questions:
Facebook Login - If user account is present (and app is not installed) login fails
Facebook Login error when facebook account is already configured in system preferences
but neither provides an answer that works in my situation. (E.g I do have bundle identifiers configured in the Facebook App)
I've tried using my own custom login code (based on the Facebook guide) and using the FBLoginView, both with the same effect.
I've also tried using ACAccountStore to make the request directly to the system store, with the same effect. Any ideas?
I'll include some code, but I'm fairly certain the code is not the problem - it all works fine if the system FB account is not configured: (i've changed my FacebookAppIDkey here)
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType *facebookType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
NSDictionary *options = #{ ACFacebookAppIdKey: #"123",
ACFacebookPermissionsKey: #[#"public_profile", #"user_likes", #"user_friends", #"email"],
ACFacebookAudienceKey: ACFacebookAudienceFriends};
[accountStore requestAccessToAccountsWithType:facebookType options:options completion:^(BOOL granted, NSError *error) {
if (granted) {
NSArray *accounts = [accountStore
accountsWithAccountType:facebookType];
id facebookAccount = [accounts lastObject];
DLog(#"%#", facebookAccount);
}
else
{
if (error)
{
DLog(#"%#", error.localizedDescription);
}
}
}];
Using the SDK:
[FBSession openActiveSessionWithReadPermissions:#[#"public_profile", #"user_likes", #"user_friends", #"email"]
allowLoginUI:YES
completionHandler:
^(FBSession *session, FBSessionState state, NSError *error) {
AppDelegate* appDelegate = (AppDelegate *) [UIApplication sharedApplication].delegate;
[appDelegate sessionStateChanged:session state:state error:error];
if ([FBSession activeSession].isOpen) {
__typeof__(self) strongSelf = weakSelf;
strongSelf.facebookToken = session.accessTokenData.accessToken;
[[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error)
{
completion(error,(NSDictionary *)result);
}];
} else {
completion(error,nil);
}
}];
The problem may is because you are already logged in but doesn't have an access token.
So you have to check the condition
if(appDelegate.session.state == FBSessionStateCreatedTokenLoaded) .
Hope the following code will help.
VNSAppDelegate *appDelegate = [[UIApplication sharedApplication]delegate];
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 initWithPermissions:appDelegate.permissions]openWithCompletionHandler:^(FBSession *session,
FBSessionState status,
NSError *error) {
// we recurse here, in order to update buttons and labels
[self updateView];
}];
}
In the below design we need to connect to facebook from the app itself by entering the username and password in the app textfields. This is similar to the default facebook connect functionality by Apple in iOS6 and iOS7 Settings. So, please suggest how can I approach this design. Thank you guys. :)
http://i.stack.imgur.com/4tJr4.png
Facebook doesn't suggest to use your own views for getting facebook username and passwords for a user. The safest way is to let facebook sdk handle the login flow.
All you need to call is openActiveSessionWithReadPermissions: allowLoginUI: completionHandler: after you have successfully integrated the facebook iOS sdk. Publish permissions are always requested in the next step.
NSArray *permissions = [[NSArray alloc] initWithObjects:
#"email",nil];
_isUserAuthenticated = [FBSession openActiveSessionWithReadPermissions:permissions
allowLoginUI:allowUI
completionHandler:^(FBSession *session,
FBSessionState state,
NSError *error) {
if (error) {
NSLog(#"FACEBOOOK OPEN ACTIVE SESSION ERROR:%#",error);
//[self handleAuthError:error];
}
[self sessionStateChanged:session
state:state
error:error];
}];
_isUserAuthenticated is a bool for keeping track of the result.
I have been trying to publish a FB Opengraph story through xcode and havent been able to do so yet.
The url is a static url, with all the meta tags set in the html file itself.
NSMutableDictionary<FBGraphObject> *action = [FBGraphObject graphObject];
action[#"testaction"] = #"http://myfbapp.com/fbobject.html";
[FBRequestConnection startForPostWithGraphPath:#"me/myfbapp:publish"
graphObject:action
completionHandler:
^(FBRequestConnection *connection, id result, NSError *error) {
}];
The code has been taken straight from the facebook app itself.
Thanks for any help!
Before calling startForPostWithGraphPath,
make sure the session is open:
NSLog(#"activeSession isOpen: %d", [[FBSession activeSession] isOpen]);
make sure the session has 'publish_actions' permissions:
NSLog(#"session perms: %#", [[FBSession activeSession] permissions]);
if not,
if ([FBSession.activeSession.permissions indexOfObject:#"publish_actions"] == NSNotFound) {
then ask for permission:
if ([FBSession.activeSession.permissions indexOfObject:#"publish_actions"] == NSNotFound) {
defaultAudience:FBSessionDefaultAudienceFriends
completionHandler:^(FBSession *session, NSError *error) {
The problem was that the action had not been reviewed by FB and was in test mode. The account I was trying to post with was not the developer account linked with the FB App and therefore I was unable to post the action.
Once I logged in with my dev account, it was working fine.
I am trying to post on a Facebook friend's wall, I tried these two methods but none work:
1.
//post on wall
NSMutableDictionary *variables = [[NSMutableDictionary alloc]initWithCapacity:1];
[variables setObject:#"v" forKey:#"message"];
[graphref doGraphPost:[NSString stringWithFormat:#"1389799421/feed"] withPostVars:variables];
//post on wall
2.
[_facebook requestWithGraphPath:#"1389799421/feed"
andParams:[NSMutableDictionary dictionaryWithObject:#"test wall post" forKey:#"message"]
andHttpMethod:#"POST"
andDelegate:self];
...and I can't understand why!! On the facebook website I have added the bundle and the permissions.
I am trying to post on a Facebook friend's wall
Facebook recently announced in the developer blog, that posting to another user’s wall through the API will not be possible any more from Feb 2013 on:
Removing ability to post to friends walls via Graph API
We will remove the ability to post to a user's friends' walls via the Graph API. Specifically, posts against [user_id]/feed where [user_id] is different from the session user, or stream.publish calls where the target_id user is different from the session user, will fail. If you want to allow people to post to their friends' timelines, invoke the feed dialog.
So I think it’s pretty useless starting to develop a feature like that now.
First off, you have to open your session with publish permissions. Specifically, you must request the publish_stream permission.
NSArray * permissions = [[NSArray alloc] initWithObjects:#"publish_stream", nil];
return [FBSession openActiveSessionWithPublishPermissions:permissions defaultAudience:FBSessionDefaultAudienceFriends allowLoginUI:YES completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
[self sessionStateChanged:session
state:status
error:error];
}];
If you have publish permissions, you can create and send the request. Make sure you include the access_token as one of the parameters. If you don't, you will get authentication errors.
NSDictionary * postParameters = [NSDictionary dictionaryWithObjectsAndKeys:_textView.text, #"message", FBSession.activeSession.accessToken, #"access_token", nil];
NSString * graphPath = #"ID_NUMBER_HERE/feed";
FBRequest * request = [FBRequest requestWithGraphPath:graphPath parameters:postParameters HTTPMethod:#"POST"];
[[request initWithSession:FBSession.activeSession graphPath:graphPath parameters:postParameters HTTPMethod:#"POST"] startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
NSLog(#"Successful posted to Facebook");
}];
}