Logout from facebook in iOS app - ios

I am creating a simple iOS App that Login to facebook, Fetch self and friends details, Logout from facebook.
Now Login from Facebook and Fetching self & friends details is working ok, but I am not able to logout fully from facebook. Whenever I logout and then Login back - I see the Authorization screen instead of Authentication Login screen of Facebook (of Web).
Below is my code - can you please see if there is something wrong in the steps I have performed from Login, to Fetching self & friends details and Logging out from facebook
1) Login to Facebook using below method
- (void)openSession
{
if(FBSession.activeSession.isOpen)
{
[FBSession openActiveSessionWithReadPermissions:nil
allowLoginUI:NO
completionHandler:
^(FBSession *session,
FBSessionState state, NSError *error)
{
[self sessionStateChanged:session state:state error:error];
}];
}
else
{
[FBSession openActiveSessionWithReadPermissions:nil
allowLoginUI:YES
completionHandler:
^(FBSession *session,
FBSessionState state, NSError *error)
{
[self sessionStateChanged:session state:state error:error];
}];
}
}
- (void)sessionStateChanged:(FBSession *)session
state:(FBSessionState) state
error:(NSError *)error
{
switch (state) {
case FBSessionStateOpen:
{
// Connection is Open
lblStatus.text = #"FBSessionStateOpen";
}
break;
case FBSessionStateClosed:
case FBSessionStateClosedLoginFailed:
{
[FBSession.activeSession closeAndClearTokenInformation];
// Connection is Closed / Login Failed
lblStatus.text = #"FBSessionStateClosed";
}
break;
default:
break;
}
}
2) Fetching self details and Friends details using below method
if (FBSession.activeSession.isOpen)
{
[[FBRequest requestForMe] startWithCompletionHandler:
^(FBRequestConnection *connection,
NSDictionary<FBGraphUser> *user,
NSError *error) {
if (!error) {
self.lblSelfDetails.text = user.name;
self.profilePicture.profileID = user.id;
}
}];
}
FBRequest *friendRequest = [FBRequest requestForGraphPath:#"me/friends?fields=name,birthday"];
[friendRequest startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error)
{
NSArray *data = [result objectForKey:#"data"];
for (FBGraphObject<FBGraphUser> *friend in data)
{
NSLog(#"%#:%#", [friend name],[friend birthday]);
}
}];
3) Logout using below method
- (IBAction)logout:(id)sender
{
[FBSession.activeSession closeAndClearTokenInformation];
}

Please use this method to logut successfully from the facebook
- (void)logout:(id<FBSessionDelegate>)delegate {
_sessionDelegate = delegate;
NSMutableDictionary * params = [[NSMutableDictionary alloc] init];
[self requestWithMethodName:#"auth.expireSession"
andParams:params andHttpMethod:#"GET"
andDelegate:nil];
[params release];
[_accessToken release];
_accessToken = nil;
[_expirationDate release];
_expirationDate = nil;
NSHTTPCookieStorage* cookies = [NSHTTPCookieStorage sharedHTTPCookieStorage];
NSArray* facebookCookies = [cookies cookiesForURL:
[NSURL URLWithString:#"https://m.facebook.com"]];
for (NSHTTPCookie* cookie in facebookCookies) {
[cookies deleteCookie:cookie];
}
if ([self.sessionDelegate respondsToSelector:#selector(fbDidLogout)]) {
[_sessionDelegate fbDidLogout];
}
}
Hope this helps you!!!

Add this mathod in appdelegate.m
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
return [FBSession.activeSession handleOpenURL:url];
}
Then Add these methods in your .m file
- (void)sessionStateChanged:(FBSession *)session
state:(FBSessionState) state
error:(NSError *)error
{
switch (state) {
case FBSessionStateOpen: {
UIViewController *topViewController =
[self.navController topViewController];
if ([[topViewController modalViewController]
isKindOfClass:[SCLoginViewController class]]) {
[topViewController dismissModalViewControllerAnimated:YES];
}
}
break;
case FBSessionStateClosed:
case FBSessionStateClosedLoginFailed:
// Once the user has logged in, we want them to
// be looking at the root view.
[self.navController popToRootViewControllerAnimated:NO];
[FBSession.activeSession closeAndClearTokenInformation];
[self showLoginView];
break;
default:
break;
}
if (error) {
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:#"Error"
message:error.localizedDescription
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
}
- (void)openSession
{
[FBSession openActiveSessionWithReadPermissions:nil
allowLoginUI:YES
completionHandler:
^(FBSession *session,
FBSessionState state, NSError *error) {
[self sessionStateChanged:session state:state error:error];
}];
}
Next, create a new method that will close the current session and log a person out:
-(void)logoutButtonWasPressed:(id)sender
{
[FBSession.activeSession closeAndClearTokenInformation];
}

Related

Post multiple images using SLComposeViewController on Facebook/ Twitter?

I am an iOS developer and I am currently using SLComposeViewController to share a post on Facebook/Twitter. My issue is that I have to post multiple images in a single post.
I have done this as follows:
SLComposeViewController* mySLComposerSheet = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];
[mySLComposerSheet setInitialText:textTobeShared];
mySLComposerSheet addURL:[NSURL URLWithString:#"http://click-labs.com/"]];
for(int count=0;count<imageArray.count;count++)
if([mySLComposerSheet addImage:[UIImage imageWithData:[imageArray objectAtIndex:count]]])
In the above code, imageArray is the array of images that I want to post.
When I am doing this on Facebook, all the images are posted as a separate post.
While in case of Twitter, addImage method returns true only for the first images while in case of other images it returns false. So only one image is posted.
So I want to know how to achieve my goal and is it possible to post multiple images in a single tweet.
I think you need to create an album first.
Here's a link to the facebook album API documentation.
- (void)shareToFacebook {
if (FBSession.activeSession.isOpen) {
NSLog(#"SESSION IS OPEN");
[self createFacebookAlbum];
} else {
NSLog(#"SESSION IS NOT OPEN");
NSArray* permissions = [NSArray arrayWithObject:#"email"];
[FBSession openActiveSessionWithReadPermissions:permissions allowLoginUI:YES completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
[self sessionStateChanged:session state:state error:error];
if (error) {
/* handle failure */
NSLog(#"error:%#, %#", error, [error localizedDescription]);
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"There was a problem with your Facebook permissions." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
}
else if (state == FBSessionStateClosed || state == FBSessionStateClosedLoginFailed ) {
[FBSession.activeSession closeAndClearTokenInformation];
}
else if (state == FBSessionStateOpenTokenExtended || state == FBSessionStateOpen) {
if(!self.presentedFacebookSheet) {
[self performSelector:#selector(reauthorizeAndContinuePostToFacebook) withObject:nil afterDelay:0.5];
self.presentedFacebookSheet = YES;
}
}
}];
}
}
- (void)reauthorizeAndContinuePostToFacebook {
NSArray *permissions = [NSArray arrayWithObjects:#"publish_actions", nil];
[[FBSession activeSession] requestNewPublishPermissions:permissions defaultAudience:FBSessionDefaultAudienceFriends completionHandler:^(FBSession *session, NSError *error) {
[self shareToFacebook];
}];
}
- (void)createFacebookAlbum {
NSMutableDictionary* parameters = [NSMutableDictionary dictionary];
[parameters setObject:#"Test name" forKey:#"name"];
[parameters setObject:#"Test message" forKey:#"message"];
FBRequest* request = [FBRequest requestWithGraphPath:#"me/albums" parameters:parameters HTTPMethod:#"POST"];
NSLog(#"creating facebook album");
FBRequestConnection *connection = [[FBRequestConnection alloc] init];
[connection addRequest:request
completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error) {
NSString* albumId = [result objectForKey:#"id"];
NSLog(#"OK %#", albumId);
}
else {
NSLog(#"Error: %#",error.userInfo);
}
}];
[connection start];
}
- (void)sessionStateChanged:(FBSession *)session state:(FBSessionState) state error:(NSError *)error {
switch (state) {
case FBSessionStateOpen:
{
[[FBRequest requestForMe] startWithCompletionHandler:
^(FBRequestConnection *connection,
NSDictionary<FBGraphUser> *user,
NSError *error) {
if (error) {
//error
}
else {
NSLog(#"User session found");
}
}];
}
break;
case FBSessionStateClosed:
case FBSessionStateClosedLoginFailed:
[FBSession.activeSession closeAndClearTokenInformation];
break;
default:
break;
}
}

Problems to login on facebook using social framework on ios

I'm using this code to make a facebook login , and it was working very well in 6.7 version of facebook app.
when the version of the facebook app is the 6.8, the login doesn't work!
Someone can imagine what is going on??
the code i'm using is...
ACAccountType *facebookTypeAccount = [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
[self.accountStore requestAccessToAccountsWithType:facebookTypeAccount
options:#{ACFacebookAppIdKey:facebookAppNumber, ACFacebookPermissionsKey: #[#"email"]}
completion:^(BOOL granted, NSError *error)
{
if(granted)
{
NSArray *accounts = [self.accountStore accountsWithAccountType:facebookTypeAccount];
//NSLog(#"accounts %#",accounts);
self.facebookAccount = [accounts lastObject];
checkFbStatus = statusWaiting;
[self me];
userFbEmail = [jay valueForKey:INFO_FB_EMAIL];
facebookId = [jay valueForKey:INFO_FB_ID];
}
else
{
NSLog(#"one");
//aqui você
if([error code]== ACErrorAccountNotFound)
{
//[SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook];
SLComposeViewController * fb = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
fb.view.hidden = YES;
[self presentViewController:fb animated:NO completion:nil];
checkFbStatus = statusFailed;
//Adicione sua conta de facebook nas configurações.
}
else
{
//Erro desconhecido ou então o usuário não deu permissão.
checkFbStatus = statusFailed;
}
}
} ];
I faced same problem :
had to make
#property (strong, nonatomic) FBSession *session;
in AppDelegate
in
(void)applicationDidBecomeActive:(UIApplication *)application { [FBAppEvents activateApp]; [FBAppCall handleDidBecomeActiveWithSession:self.session]; }
in
(void)applicationWillTerminate:(UIApplication *)application { [self.session close]; }
in
(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { return [FBAppCall handleOpenURL:url sourceApplication:sourceApplication withSession:self.session]; }
in your settings class
if (appDelegate.session.isOpen) {
[FBSession setActiveSession:appDelegate.session];
[[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection,
NSDictionary *user, NSError *error) { [self registerationWithFBRequestConnection:connection andFBGraphUser:user andNSError:error]; }];
}
else
{
[appDelegate.session closeAndClearTokenInformation];
NSArray *permissions = [NSArray arrayWithObjects:#"email", nil];
appDelegate.session = [[FBSession alloc] initWithPermissions:permissions];
[FBSession setActiveSession:appDelegate.session];
[appDelegate.session openWithBehavior:(FBSessionLoginBehaviorWithFallbackToWebView)
completionHandler:^(FBSession *session, FBSessionState status, NSError *error) { [self sessionStateChangedWithFBSession:session andFBSessionState:status andNSError:error]; }];
}
(void)sessionStateChangedWithFBSession:(FBSession*)session andFBSessionState:(FBSessionState)status andNSError:(NSError*) error { switch (status) { case FBSessionStateOpen: { [[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection, NSDictionary *user, NSError *error) {
[self registerationWithFBRequestConnection:connection andFBGraphUser:user andNSError:error];
}]; }
break;
case FBSessionStateClosed:
break;
case FBSessionStateClosedLoginFailed:
break;
default:
break;
} }
in your in registerationWithFBRequestConnection: methods you can get all information for login.

How not to ask for publish permission everytime?

I did this in facebook
[self vSuspendAndHaltThisThreadTillUnsuspendedWhileDoing:^{
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self.ACAstore requestAccessToAccountsWithType:self.ACAccounts options:[self dicPostOptions] completion:^(BOOL granted, NSError *error) {
self.bPermissionToAccessStoreGranted=granted;
[self vContinue];
}];
}];
}];
Basically I am asking for publish permission. What I want to do is to check whether such publish permission has been granted or not before asking again.
How to do so?
To check permissions available:
if(![postRequest.session.permissions containsObject:#"publish_actions"])
You can make an FBRequest with the open graph API with me/permissions. It will return you a response with a dictionary where the key are the permissions.
FBRequest *req = [FBRequest requestWithGraphPath:#"me/permissions" parameters:Nil HTTPMethod:#"GET"];
[req startWithCompletionHandler: ^(FBRequestConnection *connection,
NSDictionary* result,
NSError *error) {
BOOL canPublish = FALSE;
if (!error)
{
FBGraphObject *data = [result objectForKey:#"data"];
for(NSDictionary<FBGraphObject> *aKey in data)
{
canPublish = [[aKey objectForKey:#"publish_stream"] boolValue];
}
}
else
{
NSLog(#"%#", error);
}
NSLog(#"%#", canPublish ? #"I have publish perms" : #"I don't have publish perms");
}];
Try this -
First of all implement all the facebook sdk delegate methods in your app delegate.
- (IBAction)loginWithFacebookButtonTapped:(id)sender
{
IntubeAppDelegate *delegat = (IntubeAppDelegate*)[[UIApplication sharedApplication] delegate];
[delegat doLoginAndSwitch];
}
Now, in your appDelegate -
-(void) doLoginAndSwitch
{
[self openSessionWithAllowLoginUI:YES];
}
- (BOOL)openSessionWithAllowLoginUI:(BOOL)allowLoginUI
{
NSArray *permissions = [NSArray arrayWithObjects:#"email", nil];
return [FBSession openActiveSessionWithPublishPermissions:permissions
defaultAudience:FBSessionDefaultAudienceFriends
allowLoginUI:YES
completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
[self sessionStateChanged:session
state:state
error:error];
}];
}
-(BOOL)openSessionWithAllowPublishStreamPermission:(BOOL)allowLoginUI
{
NSArray *permissions = [NSArray arrayWithObjects:#"publish_actions",#"publish_stream", nil];
[[FBSession activeSession] requestNewPublishPermissions:permissions defaultAudience:FBSessionDefaultAudienceEveryone completionHandler:^(FBSession *session, NSError *error){
}];
return YES;
}
- (void)sessionStateChanged:(FBSession *)session
state:(FBSessionState)state
error:(NSError *)error
{
switch (state) {
case FBSessionStateOpen:
if(!error)
{
// NSLog(#"FBSessionStateOpen :- logged in");
[self openSessionWithAllowPublishStreamPermission:YES];
// Your code
}
}
}
I hope you would get what you desire now. :)

Handle cancel button in facebook iOS using session

I tried to search this but couldn't find anything useful.
[FBSession setActiveSession:[[FBSession alloc] initWithPermissions:[NSArray arrayWithObjects:#"publish_actions,read_stream,user_hometown,user_birthday,email", nil]]];
[[FBSession activeSession] openWithBehavior:FBSessionLoginBehaviorForcingWebView completionHandler:
^(FBSession *session,FBSessionState state,NSError *error)
{
if(state == FBSessionStateOpen)
{
// use user's detail and post on Facebook
}
}];
Now this works fine for me. But what if user presses close/cancel button before logging into Facebook. I need to execute set of statements if user pressed cancel button. How can i do this.
Any help would be appreciated.
You can use Facebook error category and to handle errors refer this link
[FBSession openActiveSessionWithPublishPermissions:permissions defaultAudience:FBSessionDefaultAudienceEveryone allowLoginUI:YES completionHandler:^(FBSession *session, FBSessionState status, NSError* error){
if(!error){
//success do something
}
else{
//Error
if([FBErrorUtility errorCategoryForError:error] == FBErrorCategoryUserCancelled){
//user have pressed on cancel/close button
}
else {
//loging failed
}
}
}];
try this
[FBSession setActiveSession:[[FBSession alloc] initWithPermissions:[NSArray arrayWithObjects:#"publish_actions,read_stream,user_hometown,user_birthday,email", nil]]];
[[FBSession activeSession] openWithBehavior:FBSessionLoginBehaviorForcingWebView completionHandler:
^(FBSession *session,FBSessionState state,NSError *error)
{
if(state == FBSessionStateOpen)
{
// use user's detail and post on Facebook
}
else if(state == FBSessionStateClosed)
{
// if user not authenticated
}
else if(steate == FBSessionStateClosedLoginFailed)
{
}
}];
After calling the login function, eg:
- (BOOL)openSessionWithAllowLoginUI:(BOOL)allowLoginUI {
NSArray *permissions = [NSArray arrayWithObjects:#"friends_photos",#"friends_birthday",#"email", nil];
return [FBSession openActiveSessionWithReadPermissions:permissions
allowLoginUI:allowLoginUI
completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
[self sessionStateChanged:session state:state error:error];
}];
}
You can get the callback in the delegate meth9od , eg:
- (void)sessionStateChanged:(FBSession *)session
state:(FBSessionState)state
error:(NSError *)error
{
switch (state) {
case FBSessionStateOpen:
if(!error)
{
}
break;
case FBSessionStateClosed:
{
NSLog(#"FBSessionStateClosed");
[FBSession.activeSession closeAndClearTokenInformation];
}
break;
case FBSessionStateClosedLoginFailed:
{
NSLog(#"FBSessionStateClosedLoginFailed :- logged failed");
}
break;
default:
break;
}
[[NSNotificationCenter defaultCenter] postNotificationName:FBSessionStateChangedNotification
object:session];
if (error) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:#"Error: %#",
[AppDelegate FBErrorCodeDescription:error.code]]
message:error.localizedDescription
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
}

Facebook iOS SDK not calling completion handler when authorized app

I call doFacebookLogin my app switches to facebook to authorize the app but after I allow the app to access my information and switches back.
Nothing happen. No "complete" in console.
If I call doFacebookLogin again the console shows
complete
Session state closed
Here is my code.
- (void)doFacebookLogin:(id)sender
{
[FBSession openActiveSessionWithReadPermissions:nil
allowLoginUI:YES
completionHandler:
^(FBSession *session,FBSessionState state, NSError *error) {
NSLog(#"complete");
[self sessionStateChanged:session state:state error:error];
}];
}
- (void)sessionStateChanged:(FBSession *)session state:(FBSessionState)state error:(NSError *)error
{
NSLog(#"Session state changed");
switch (state) {
case FBSessionStateOpen:
NSLog(#"Session state open");
[[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
if(error == nil) {
NSLog(#"%#", [user debugDescription]);
}
}];
break;
case FBSessionStateClosed:
case FBSessionStateClosedLoginFailed:
NSLog(#"Session state closed");
[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];
}
}
Do you have this in AppDelegate?
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
// attempt to extract a token from the url
if ([[url scheme] hasPrefix:#"fb"]) {
return [FBSession.activeSession handleOpenURL:url];
}
.....
And also you need to check if your app has Url Types section for facebook in AppName-info.plist

Resources