Reputation: 27113
I have used this method for logout facebook in app
- (void)fbDidLogout {
// Remove saved authorization information if it exists
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:@"FBAccessTokenKey"]) {
[defaults removeObjectForKey:@"FBAccessTokenKey"];
[defaults removeObjectForKey:@"FBExpirationDateKey"];
[defaults synchronize];
}
NSLog(@"logout success!");
}
This method has been invoked, but when I relaunch app the facebook still know about my latest authorization.
My full implementation
I create singleton object for facebook instance.
this is my manager .h
#import <Foundation/Foundation.h>
#import "FBConnect.h"
@interface FacebookManager : NSObject <FBSessionDelegate> {
Facebook *facebook;
}
@property (nonatomic, strong) Facebook *facebook;
+ (FacebookManager *)sharedInstance;
- (void)initWithAppID:(NSString *)appID;
@end
this is singleton facebookmanager .m
#import "FacebookManager.h"
@implementation FacebookManager
@synthesize facebook;
static FacebookManager *_sharedInstance = nil;
+ (FacebookManager *)sharedInstance {
@synchronized(self) {
if (!_sharedInstance) {
_sharedInstance = [[FacebookManager alloc] init];
}
}
return _sharedInstance;
}
- (void)initWithAppID:(NSString *)appID {
facebook = [[Facebook alloc] initWithAppId:appID andDelegate:self];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:@"FBAccessTokenKey"]
&& [defaults objectForKey:@"FBExpirationDateKey"]) {
facebook.accessToken = [defaults objectForKey:@"FBAccessTokenKey"];
facebook.expirationDate = [defaults objectForKey:@"FBExpirationDateKey"];
}
if (![facebook isSessionValid]) {
[facebook authorize:nil];
}
}
- (void)fbDidLogout {
// Remove saved authorization information if it exists
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:@"FBAccessTokenKey"]) {
[defaults removeObjectForKey:@"FBAccessTokenKey"];
[defaults removeObjectForKey:@"FBExpirationDateKey"];
[defaults synchronize];
}
NSLog(@"logout success!");
}
@end
in appDelegate I make next:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
fbManager = [FacebookManager sharedInstance];
[fbManager initWithAppID:@"myappid"];
... (some other code)
}
also add this code to app delegate:
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
return [fbManager.facebook handleOpenURL:url];
}
- (void)fbDidLogin {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:[fbManager.facebook accessToken] forKey:@"FBAccessTokenKey"];
[defaults setObject:[fbManager.facebook expirationDate] forKey:@"FBExpirationDateKey"];
[defaults synchronize];
}
In other view controller I call this method for logout:
- (IBAction)logoutFacebook:(id)sender {
FacebookManager *fbManager = [FacebookManager sharedInstance];
[fbManager.facebook logout];
}
also in plist I have add needed url scheme.
Upvotes: 1
Views: 6266
Reputation: 143
Modify the Facebook.m code to this, which works for me.
-(void)logout:(id)delegate { self.sessionDelegate = delegate; [_accessToken release]; _accessToken = nil; [_expirationDate release]; _expirationDate = nil; NSHTTPCookieStorage *cookies = [NSHTTPCookieStorage sharedHTTPCookieStorage]; NSArray *facebookCookies = [cookies cookiesForURL:[NSURL URLWithString:@"http://login.facebook.com"]]; for (NSHTTPCookie* cookie in facebookCookies){ [cookies deleteCookie:cookie]; } //Adds this one. for (NSHTTPCookie *_cookie in cookies.cookies){ NSRange domainRange = [[_cookie domain] rangeOfString:@"facebook"]; if(domainRange.length > 0){ [cookies deleteCookie:_cookie]; } } if ([self.sessionDelegate respondsToSelector:@selector(fbDidLogout)]){ [_sessionDelegate fbDidLogout]; } }
Upvotes: 5
Reputation: 11
I have tried with success this code:
NSFileManager *fm = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachesDirectory = [paths objectAtIndex:0];
NSLog(@"cache dir %@", cachesDirectory);
NSError *error = nil;
for (NSString *file in [fm contentsOfDirectoryAtPath:cachesDirectory error:&error]) {
BOOL success = [fm removeItemAtPath:[NSString stringWithFormat:@"%@/%@", cachesDirectory, file] error:&error];
if (!success || error) {
NSLog(@"Error delete file: %@, %@", file, error);
} else {
NSLog(@"Deleted file: %@", file);
}
}
Upvotes: 1
Reputation: 176
In Facebook.m, add the following code to remove cookies at m.facebook.com domain.
- (void)invalidateSession {
...
NSArray* facebookMCookies = [cookies cookiesForURL:
[NSURL URLWithString:@"https://m.facebook.com"]];
for (NSHTTPCookie* cookie in facebookMCookies) {
[cookies deleteCookie:cookie];
}
...
}
Upvotes: 1
Reputation: 50
That seems to be the way the ios sdk api with sso/oauth 2.0 works. I have not been able to logout completely even after clearing the tokens and I have not been able to switch users from the App. Got to go to the FB app to switch users
As a workaround, change the line in Facebook.m and disable the safariAuth
// [self authorizeWithFBAppAuth:YES safariAuth:YES];
[self authorizeWithFBAppAuth:NO safariAuth:NO]
But then you have to type in the username and password everytime you authorize.
Upvotes: 1
Reputation: 14667
What do you mean by "when I relaunch app the facebook still know about my latest authorization" ? Does this mean your FB accesstoken is still valid? You still see the userdefaults values? What exactly?
If you mean that when you trigger the FB login again, it automatically logs you in again, then yes if you have the Facebook APP installed in iOS, the user will have to logout from the FB app manually to switch an account.
If the FB app is not installed, then yes the SSO should prompt the user to login again after initiating a logout.
Upvotes: 2