I am using facebook sdk 4.7 and I need to check if accesstoken is expired.
FBSDKAccessToken *access_token = [FBSDKAccessToken currentAccessToken];
if (access_token != nil) {
//user is not logged in
//How to Check if access token is expired?
if ([access_token isExpired]) {
//access token is expired ......
//
}
}
And if I success with that I have to log the user again.
The SDK gives an expiration_date.how can that help? The device may have wrong date.
Assuming user has been logged in with Facebook before and has [FBSDKAccessToken currentAccessToken] != nil
(I am not going into details here, because login via FB is another story).
In my app, I do the following to make sure the FB access token is always valid and synced with my app server.
To keep it simple, all the code below is in AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// ...
/**
Add observer BEFORE FBSDKApplicationDelegate's
application:didFinishLaunchingWithOptions: returns
FB SDK sends the notification at the time it
reads token from internal cache, so our app has a chance
to be notified about this.
*/
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(fbAccessTokenDidChange:)
name:FBSDKAccessTokenDidChangeNotification
object:nil];
return [[FBSDKApplicationDelegate sharedInstance] application: application didFinishLaunchingWithOptions: launchOptions];
}
- (void)fbAccessTokenDidChange:(NSNotification*)notification
{
if ([notification.name isEqualToString:FBSDKAccessTokenDidChangeNotification]) {
FBSDKAccessToken* oldToken = [notification.userInfo valueForKey: FBSDKAccessTokenChangeOldKey];
FBSDKAccessToken* newToken = [notification.userInfo valueForKey: FBSDKAccessTokenChangeNewKey];
NSLog(@"FB access token did change notification\nOLD token:\t%@\nNEW token:\t%@", oldToken.tokenString, newToken.tokenString);
// initial token setup when user is logged in
if (newToken != nil && oldToken == nil) {
// check the expiration data
// IF token is not expired
// THEN log user out
// ELSE sync token with the server
NSDate *nowDate = [NSDate date];
NSDate *fbExpirationDate = [FBSDKAccessToken currentAccessToken].expirationDate;
if ([fbExpirationDate compare:nowDate] != NSOrderedDescending) {
NSLog(@"FB token: expired");
// this means user launched the app after 60+ days of inactivity,
// in this case FB SDK cannot refresh token automatically, so
// you have to walk user thought the initial log in with FB flow
// for the sake of simplicity, just logging user out from Facebook here
[self logoutFacebook];
}
else {
[self syncFacebookAccessTokenWithServer];
}
}
// change in token string
else if (newToken != nil && oldToken != nil
&& ![oldToken.tokenString isEqualToString:newToken.tokenString]) {
NSLog(@"FB access token string did change");
[self syncFacebookAccessTokenWithServer];
}
// moving from "logged in" state to "logged out" state
// e.g. user canceled FB re-login flow
else if (newToken == nil && oldToken != nil) {
NSLog(@"FB access token string did become nil");
}
// upon token did change event we attempting to get FB profile info via current token (if exists)
// this gives us an ability to check via OG API that the current token is valid
[self requestFacebookUserInfo];
}
}
- (void)logoutFacebook
{
if ([FBSDKAccessToken currentAccessToken]) {
[[FBSDKLoginManager new] logOut];
}
}
- (void)syncFacebookAccessTokenWithServer
{
if (![FBSDKAccessToken currentAccessToken]) {
// returns if empty token
return;
}
// BOOL isAlreadySynced = ...
// if (!isAlreadySynced) {
// call an API to sync FB access token with the server
// }
}
- (void)requestFacebookUserInfo
{
if (![FBSDKAccessToken currentAccessToken]) {
// returns if empty token
return;
}
NSDictionary* parameters = @{@"fields": @"id, name"};
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me"
parameters:parameters];
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
NSDictionary* user = (NSDictionary *)result;
if (!error) {
// process profile info if needed
}
else {
// First time an error occurs, FB SDK will attemt to recover from it automatically
// via FBSDKGraphErrorRecoveryProcessor (see documentation)
// you can process an error manually, if you wish, by setting
// -setGraphErrorRecoveryDisabled to YES
NSInteger statusCode = [(NSString *)error.userInfo[FBSDKGraphRequestErrorHTTPStatusCodeKey] integerValue];
if (statusCode == 400) {
// access denied
}
}
}];
}
Each time you think it is good time to check FB token (e.g. an app was in background for a while), call -requestFacebookUserInfo
. This will submit Open Graph request and returns an error if token is invalid/expired.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With