Hi I'm working on an app. In the app is possible to sing-in with facebook or not... And in several places of the app you can share stuff on you own timeline.
I followed the scrumptious example that facebook provides, and the log-in is working fine... But when I have to share stuff, I don't know if it's necessary or not to check if the session is active before calling the FBRequestConnection method to post to fb.
What's the best way to handle this? Because all the authentication is made calling an open session method in the delegate so... I have to call this methods from anywhere in the app? How do I go back to the place where I was before calling the authentication method... I'm sure there must be some kind of patron to use, but I can't find which one...
Any idea?
thanks!
Use a block of code like this to make sure that the session is open, which is important because if the user isn't, your app will crash. And then you need to have you OpenGraph objects within the FBRequestConnection.
if (FBSession.activeSession.isOpen) {
[[FBRequest requestForMe] startWithCompletionHandler:
^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
if (!error) {
self.nameString = user.name;
self.profileImage.profileID = user.id;
self.userName = user.username;
[self.tableView reloadData];
}
}];
}
}
** For your comment below: **
Okay, then perhaps bring up a UIAlertView asking the user to log into Facebook. If they select yes, then do something like
AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
[appDelegate openSessionWithAllowLoginUI:YES];
assuming that your AppDelegate looks like Scrumptious.
Related
I have logged in on my iOS app that I am building using the easier method of FBSDKLoginButton.
Since all I want is the users name and a link to their facebook I know I can find this under [FBSDKProfile currentprofile].
My question really is how do I use this?
I am trying all sorts of combinations but something akin to the below is an example of what I'm doing.
[FBSDKProfile enableUpdatesOnAccessTokenChange:YES];
NSString *name = [[NSString alloc]init];
name = [[FBSDKProfile currentProfile]firstName];
I figure since my app now has access which I quickly tested through an if on the [FBSDKAccessToken currentAccessToken] so I believe I am primed. My app delegate is all setup also. So shouldn't my above code just work? I mean, I assume currentProfile is set if a user is logged in? Maybe? Arghhh!!!
Thanks guys
Try this code :
FBRequestHandler completionBlock = ^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
NSLog(#"USER DICTIONARY : %#", user);
};
[[FBRequest requestForMe] startWithCompletionHandler:completionBlock];
you can then get the user details from the user dictionary.
I sorted it guys. Essentially the FBSDKLoginButton logs you in but offers no permissions. Simply ask for them as so;
loginButton.readPermissions = #[#"email", #"public_profile"];
Then the normal code I tried in my above comment will work. My mistake here is I assumed a simple login would at least give me the public profile. It doesn't, you have to ask.
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];
}];
}
I'm experimenting trying to call FBRequest:requestForMe:startWithCompletionHandler and couldn't get it to work in my own code so have tried adding it to the example project SessionLoginSample but still get the same result which is that the result is nil.
I've added to the updateView method within the example project, but it makes no difference where its placed, id is always nil:
- (void)updateView {
// get the app delegate, so that we can reference the session property
SLAppDelegate *appDelegate = [[UIApplication sharedApplication]delegate];
if (appDelegate.session.isOpen) {
// valid account UI is shown whenever the session is open
[self.buttonLoginLogout setTitle:#"Log out" forState:UIControlStateNormal];
[self.textNoteOrLink setText:[NSString stringWithFormat:#"https://graph.facebook.com/me/friends?access_token=%#",
appDelegate.session.accessTokenData.accessToken]];
FBRequest *me = [FBRequest requestForMe];
[me startWithCompletionHandler:^(FBRequestConnection *connection,
id result,
NSError *error) {
NSDictionary<FBGraphUser> *my = (NSDictionary<FBGraphUser> *) result;
NSLog(#"My dictionary: %#", my.first_name);
}];
} else {
// login-needed account UI is shown whenever the session is closed
[self.buttonLoginLogout setTitle:#"Log in" forState:UIControlStateNormal];
[self.textNoteOrLink setText:#"Login to create a link to fetch account data"];
}
}
The NSError contains domain: com.facebook.sdk code: 5.
After some googling and experimentation I got requestForMe to work by adding a call to [FBSession setActiveSession:appDelegate.session] just prior to it, however I can not transfer this working code into my own project where I get the same error code of 5, however I cannot see any difference with my project's code to that of the example project.
After lots of googling I managed to fix this by adding the following line just before the call to requestForMe
[FBSession setActiveSession:appDelegate.session];
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
Hi I was reading and reading tutorials here on http://developers.facebook.com/ .
About Login in to Facebook and publish Feed from application, my problem is I cannot login to Facebook at all.
And I can't get it work. It sucks, annoying, and there is no clear tutorial/explanation about this.
Im trying to login from my app, when safari open and then the URL were like going nuts
blinking..
And I dont get an error, why?
Is there any CLEAR tutorial About Loging in?
it works GREAT on simulator, but not on the Device.
Im on Xcode 4.5 beta right now, but it also doesn't work on 4.4.
I need Help!
[CLOSED]
EDIT: I fixed it! I was so stupid... I was struggling in seven days just to login to FB,
then i changed ( Cookies Allowed on the device ), Everything worked PERFECT!
Damn that device just needed some cookies.. Lol
I just updated to the recent FB sdk about 2 weeks ago. Here's the way I've done it:
//FB recommends to put these two in the app delegate in their sample apps but you can place them other places
- (BOOL)openSessionWithAllowLoginUI:(BOOL)allowLoginUI {
NSArray *permissions = [NSArray arrayWithObjects:#"publish_actions", nil];
return [FBSession openActiveSessionWithPermissions:permissions
allowLoginUI:allowLoginUI
completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
NSLog((#"session.state is %d",session.state));
if(session.state==513){
[AppPrefererences sharedAppPrefererences].faceBookLoggedIn=YES;
NSLog((#"facebookLogin pref has been set to yes from inside appDelegate"));
}
else{
[AppPrefererences sharedAppPrefererences].faceBookLoggedIn=NO;
}
}];
}
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
// FBSample logic
// We need to handle URLs by passing them to FBSession in order for SSO authentication
// to work.
return [FBSession.activeSession handleOpenURL:url];
}
//Then whereever you want to initiate the log in (i use mine in a tableView)
AppDelegate *appDelegate =(AppDelegate*) [[UIApplication sharedApplication]delegate];
if (![appDelegate openSessionWithAllowLoginUI:NO]) {
[appDelegate openSessionWithAllowLoginUI:YES];
facebookLoginLabel.text=#"Facebook Log Out";
[AppPrefererences sharedAppPrefererences].faceBookEnabled=YES;
}
else{
facebookLoginLabel.text=#"Facebook Log In";
[AppPrefererences sharedAppPrefererences].faceBookLoggedIn=NO;
[FBSession.activeSession closeAndClearTokenInformation];
}
And then whererever you want to post you do this:
[FBRequestConnection startForPostStatusUpdate:#"any thing you want to post"
completionHandler:^(FBRequestConnection *connection, id result, NSError *error){}];
And, also don't forget to set the FBLoginViewDelegate
Let me know if you have any questions! Hope it helps!