Close currentsession in Facebook login in xcode? - iphone

I m integrating Facebook login in my app.
I have a Log out button in my app.When user clicks Sign Out then Facebook's current session should be closed .Again if I click Login it should show Login screen of Facebook.
When Log out button is clicked:
appDelegate.fbEmail=nil;
if (FBSession.activeSession.isOpen) {
[appDelegate closeSession];
}
AppDelegate.m
-(void)closeSession
{
[[FBSession activeSession] close];
}
-(BOOL)openSessionWithAllowLoginUI:(BOOL)allowLoginUI{
NSArray *permissions=[[NSArray alloc]initWithObjects:#"email", nil];
return[FBSession openActiveSessionWithReadPermissions:permissions allowLoginUI:allowLoginUI completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
[self sessionStateChanged:session state:state error:error];
}];
}
After he clicks logout it changes to login.Now when login is clicked Login screen of facebook should appear..How to do it ?

Could you try FBSessionDelegate Methods? Inside FBSessionDelegate have methods to handle session. In this case, i think you can use this function to handle you question :
- (void)fbDidlogout
{
// your code to get login screen here!
}
This function will called when the request logout has succeeded. Hope this will help, Cheers

Related

Facebook login in iOS app for multiple users on one device

My app will be used by multiple users.
How can I integrate facebook in a way so that the safari doesn't save any user credentials & throw a login page each time some one tries to login.
I already used FBSessionLoginBehaviorForcingWebView to force a web view login within the app but the problem is, when the first user tries to login to fb via the view presented within the app, the control then goes to safari for authentication & it just saves the creds.
So when other user tries to log in, & enters his credentials in the app local UIWebView, the control again goes to safari, which already has previos creds stored & the new user just cannot authenticate.
So basically the first user is permanently logged in. Clearing the cookies for web view doesn't work. I cant clear them for safari.
Help
Thanks in advance.
This is what I have been doing
if([FBSession activeSession].isOpen)
{
[[FBSession activeSession] closeAndClearTokenInformation];//Also, clearing all the local cookies
}
else
{
AppDelegate *delegate = [UIApplication sharedApplication].delegate;
delegate.session = [[FBSession alloc] init];
[FBSession setActiveSession:delegate.session];
[delegate.session openWithBehavior:FBSessionLoginBehaviorForcingWebView completionHandler:^(FBSession *session1, FBSessionState status, NSError *error) {
if (!error) {
[self openSession]; // your method
}
}];
}
- (void)sessionStateChanged:(FBSession *)session state:(FBSessionState) state error:(NSError *)error{
switch (state) {
case FBSessionStateOpen:
{
[FBRequestConnection startForPostStatusUpdate:#"Some message"completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error) {
//logout again
NSLog(#"startForPostStatusUpdate SUCESS");
}
else {
//logout again
NSLog(#"startForPostStatusUpdate FAIL");
}
}];
}
break;
case FBSessionStateClosed:
{
NSLog(#"FBSessionStateClosed");
}
break;
case FBSessionStateClosedLoginFailed:
[FBSession.activeSession closeAndClearTokenInformation];
break;
default:
break;
}
if (error) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error" message:error.localizedDescription delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
}
}
Also, modified the app delegate with your methods.
Found a solution. Basically, calling the following:
[FBSession.activeSession closeAndClearTokenInformation];
[FBSession.activeSession close];
[FBSession setActiveSession:nil];
Only clears the local FB session information but not the Safari cookies. So, after I log in the user, I clear the Safari cookies:
NSHTTPCookie *cookie;
NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (cookie in [storage cookies]) {
[storage deleteCookie:cookie];
}
[[NSUserDefaults standardUserDefaults] synchronize];
It isn't very elegant, but it works. Now, when the next user tries to log in, it forces them to enter their credentials.
You just need to use this method after you want to close the FB Session.
[FBSession.activeSession closeAndClearTokenInformation];
This will clear the Facebook Token, and whenever button will be pressed for Facebook share, it will ask for new token credential and it will show Facebook login view again.
Use following code in AppDelegate
// This method will handle facebook session.
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
// Facebook SDK * login flow *
// Attempt to handle URLs to complete any auth (e.g., SSO) flow.
return [FBAppCall handleOpenURL:url sourceApplication:sourceApplication fallbackHandler:^(FBAppCall *call) {
// Facebook SDK * App Linking *
// For simplicity, this sample will ignore the link if the session is already
// open but a more advanced app could support features like user switching.
if (call.accessTokenData) {
if ([FBSession activeSession].isOpen) {
NSLog(#"INFO: Ignoring app link because current session is open.");
}
else {
[self handleAppLink:call.accessTokenData];
}
}
}];
}
// Helper method to wrap logic for handling app links.
- (void)handleAppLink:(FBAccessTokenData *)appLinkToken {
// Initialize a new blank session instance...
FBSession *appLinkSession = [[FBSession alloc] initWithAppID:nil
permissions:nil
defaultAudience:FBSessionDefaultAudienceNone
urlSchemeSuffix:nil
tokenCacheStrategy:[FBSessionTokenCachingStrategy nullCacheInstance] ];
[FBSession setActiveSession:appLinkSession];
// ... and open it from the App Link's Token.
[appLinkSession openFromAccessTokenData:appLinkToken
completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
// Forward any errors to the FBLoginView delegate.
if (error) {
//TODO: Show error here
}
}];
}
Add following code where you are opening session for Facebook
/***********************************************************************
This method opens browser or App Url to FB authentication and change FB
session state
************************************************************************/
- (void)openSession
{
NSArray *permisssions = [[NSArray alloc] initWithObjects:#"email",#"user_photos",nil];
[FBSession openActiveSessionWithReadPermissions:permisssions
allowLoginUI:YES
completionHandler:
^(FBSession *session,
FBSessionState state, NSError *error) {
[self sessionStateChanged:session state:state error:error];
}];
}
/***********************************************************************
This method will be called whenever FB Session state changed
It also shows an error message if any error occurs
************************************************************************/
- (void)sessionStateChanged:(FBSession *)session
state:(FBSessionState) state
error:(NSError *)error
{
switch (state) {
case FBSessionStateOpen: {
NSLog(#"FBSession Open State");
//Enter your code what you want to perform when session is open
}
break;
case FBSessionStateClosed:
case FBSessionStateClosedLoginFailed:
// Once the user has logged in, we want them to
// be looking at the root view.
NSLog(#"FBSession State Closed");
[FBSession.activeSession closeAndClearTokenInformation];
[FBSession.activeSession close];
[FBSession setActiveSession:nil];
break;
default:
break;
}
if (error) {
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:#"Error"
message:error.localizedDescription
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
}
Now when ever user tap on Facebook Share button check that session exists or not. If not then call openSession method. It will open facebook login view.
There is a sample in the Facebook Github repository, showing how to switch between multiple users.
It looks like it requires use of the custom login flow.

After successfull login with FBSession reshowing login on opening another Fb page

I have used FBSession for authentication to my app natively and this is working fine, I am also getting the accesstoken.
But my problem is after that when i am loading the Client facebook page on webView by passing the specific URl it is showing the page successfully but its not loged in. Still i can see Join and Log in button on the top.
As i am already loged in then why to login again.
Friends give me some hint how to solve this.
Here is the code.
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self updateView];
SLAppDelegate *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 openWithBehavior:FBSessionLoginBehaviorForcingWebView
completionHandler:^(FBSession *session,
FBSessionState status,
NSError *error) {
// this handler is called back whether the login succeeds or fails; in the
// success case it will also be called back upon each state transition between
// session-open and session-close
[self updateView];
}];
NSArray *permissions1 = #[#"email"];
[appDelegate.session requestNewReadPermissions:permissions1
completionHandler:^(FBSession *session,
NSError *error)
{
// Handle new permissions callback
}];
}
}
}
// FBSample logic
// main helper method to update the UI to reflect the current state of the session.
- (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?access_token=%#",
appDelegate.session.accessTokenData.accessToken]];
NSLog(#"Print %#",self.textNoteOrLink.text);
// NSLog(#"Print the user name is %#",appDelegate.session.accessTokenData)
} 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"];
}
}
// FBSample logic
// handler for button click, logs sessions in or out
- (IBAction)buttonClickHandler:(id)sender {
// get the app delegate so that we can access the session property
SLAppDelegate *appDelegate = [[UIApplication sharedApplication]delegate];
// this button's job is to flip-flop the session from open to closed
if (appDelegate.session.isOpen) {
// if a user logs out explicitly, we delete any cached token information, and next
// time they run the applicaiton they will be presented with log in UX again; most
// users will simply close the app or switch away, without logging out; this will
// cause the implicit cached-token login to occur on next launch of the application
[appDelegate.session closeAndClearTokenInformation];
} else {
if (appDelegate.session.state != FBSessionStateCreated) {
// Create a new, logged out session.
appDelegate.session = [[FBSession alloc] init];
}
// if the session isn't open, let's open it now and present the login UX to the user
[appDelegate.session openWithBehavior:FBSessionLoginBehaviorForcingWebView
completionHandler:^(FBSession *session,
FBSessionState status,
NSError *error) {
// this handler is called back whether the login succeeds or fails; in the
// success case it will also be called back upon each state transition between
// session-open and session-close
[self updateView];
}];
}
}
And in another view controller i am opening the client page like this:
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"https://www.facebook.com/abc"]]];

Facebook Login ask to install (iPhone)

I need help in the facebook login from Facebook-SDK-3.1 for iOS 6.I have used all the code of the Facebook sdksample code sessionLoginSample,I have used the WebView opening code in this and whenever i login from the new id ...it takes me to the below image link to install in my project .dont know what exactly it is...and if i do so and after that logout from the code ..and when I again press button to login , it automatically log-in without asking for the id and pssword``login page. and again again it automatically logs-in , even after logout./.can anyone help me why after being logout it ask stores the previous access token and password.
and code is
- (IBAction)buttonClickHandler:(id)sender {
AppDelegate* appDelegate = [[UIApplication sharedApplication]delegate];
if (appDelegate.session.isOpen) {
[appDelegate.session closeAndClearTokenInformation];
} else {
if (appDelegate.session.state != FBSessionStateCreated) {
appDelegate.session = [[FBSession alloc] initWithPermissions:[NSArray arrayWithObjects:#"email", nil]];
}
[appDelegate.session openWithBehavior:FBSessionLoginBehaviorForcingWebView
completionHandler:^(FBSession *session,
FBSessionState state,
NSError *error) {
FBSession.activeSession = session;
[self updateView];
NSLog(#" state=%d",state);
[FBRequestConnection
startForMeWithCompletionHandler:^(FBRequestConnection *connection,
id<FBGraphUser> user,
NSError *error) {
userInfo = #"";
userInfo = user.username;
NSLog(#"string %#", userInfo);
[self checkfacebook];
}];
}]; }
}
FB grants access to your app once the user logs in . If the user wants to modify the privileges he can do it by loggin into fb and changing permissions. You might want to look into oAuth for further details.
As u login through new emailid it has to install your app for them...so,its asking for different login..but again u login with the same it will not ask...the answer for ur 2nd question is....is u doing something to the server side...bcoz there might be a provision on the server which remember user for few hour or few days...so,check with server side..if not working with server...reply me back i will try to answer further...

Fetch cached access token through FBSession using Facebook SDK

Is there a way to fetch cached access token through FBSession using Facebook SDK if the user is logged in native Facebook.
I am trying to implement autologin through Facebook in an app i.e.when a user is logged in native Facebook then the app should not ask for the login and user should get automatically logged in.
I have used FBSession and FBTokenCacheStrategy and the user is getting logged in automatically but I am not able to fetch the access token which I need to call some API. The following code I am using to get this done :
CacheToken = [[FBTokenCache alloc]init];
NSArray *permissions = [[NSArray alloc]initWithObjects:#"email,user_photos,user_videos,publish_stream,offline_access,user_checkins,friends_checkins", nil];
self.fbsession = [[FBSession alloc] initWithAppID:#"484473011575776"
permissions:permissions
urlSchemeSuffix:nil
tokenCacheStrategy:CacheToken];
(fbsession is the object of Facebook SDK class FBSession)
[FBSession setActiveSession:self.fbsession];
[FBSession openActiveSessionWithReadPermissions:permissions
allowLoginUI:YES
completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
[self sessionStateChanged:session state:state error:error];
Thanks in advance.
To get the access token you should use this:
[FBSession activeSession] accessToken]
However, it seems like you want to check whether there is already a (cached) access token. To do this you can do this:
// See if we have a valid token for the current state.
if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded) {
NSLog(#"The value access token is: %#", [[FBSession activeSession] accessToken]);
} else {
// No, display the login page.
}
Make sure also to do this in your app delegate or the access token will be nil:
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
return [FBSession.activeSession handleOpenURL:url];
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// We need to properly handle activation of the application with regards to Facebook Login
// (e.g., returning from iOS 6.0 Login Dialog or from fast app switching).
[FBSession.activeSession handleDidBecomeActive];
}
Hope this helps
Try following code..
if (FBSession.activeSession.isOpen)
{
NSString *token = [[[FBSession activeSession] accessTokenData] accessToken];
}
hope this will work out for you..

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