ios Facebook SDK v4.x access token null despite being logged in via FBSDKLoginButton

萝らか妹 提交于 2019-11-30 18:19:55

The FBSDKApplicationDelegate needs to be called first to resolved cached tokens. Since you are setting the root view controller immediately, that calls your viewDidLoad before the FBSDKApplicationDelegate. Instead, you can move the FBSDKApplicationDelegate up:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  // Override point for customization after application launch.
  [FBSDKLoginButton class];
  BOOL r = [[FBSDKApplicationDelegate sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions];

  self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

  [self.window setRootViewController:[[RootViewController alloc] init]];

  [self.window makeKeyAndVisible];

  [self.window setBackgroundColor:[UIColor purpleColor]];


  return r;
}

I got same issue today, only because I missed one step:

- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation {

    BOOL handled = [[FBSDKApplicationDelegate sharedInstance] application:application
                                                                  openURL:url
                                                        sourceApplication:sourceApplication
                                                               annotation:annotation];

    return handled;
}

I have had an issue where I could not get the Access Token because I am calling it before return [[FBSDKApplicationDelegate sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions];. I needed to check the access token to check whether the user is logged in or not to decide which should be my root view controller. What I did was I tried to get the access token from the cache manually in application didFinishLaunchingWithOptions by:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    FBSDKProfile *cachedProfile = [FBSDKProfile fetchCachedProfile];
    [FBSDKProfile setCurrentProfile:cachedProfile];

    FBSDKAccessToken *cachedToken = [[FBSDKSettings accessTokenCache] fetchAccessToken];
    NSLog(@"Cached Token: %@", cachedToken.tokenString);

    if (cachedToken) {
        //User is logged in, do logic here.
    }

    return [[FBSDKApplicationDelegate sharedInstance] application:application
                                didFinishLaunchingWithOptions:launchOptions];
}

You can see this method by checking the implementation of - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions in FBSDKApplicationDelegate.m

UPDATE

This does not seem to work anymore. I'm not sure why. But it seems that the fetchCachedProfile and accessTokenCache methods have been made internal. I could not access these methods anymore in my code as it gives me an error.

You could build the logic around waiting for FBSDKAccessTokenDidChangeNotification notification in your ViewController's code.

In your AppDelegate.m:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // ...

    // add observer BEFORE FBSDKApplicationDelegate's - application:didFinishLaunchingWithOptions: returns
    [[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]) {
        if ([FBSDKAccessToken currentAccessToken]) {
            // token is ready to be used in the app at this point
        }
    }
}

It happened to me too, the "Login with Facebook" button was working as expected, I was being asked for permissions, allowed them, the application:openURL:... delegate method was being called with an URL that seemed valid, nonetheless the accessToken property remained nil.

The problem in my case was the fact that somehow Shared Keychain was removed from the application entitlements, thus the Facebook SDK was not able to save the token in keychain. Enabling the capability solved the problem.

The odd thing is that this was a silent error, so it was not clear from the beginning why the access token wasn't being set...

You should use tokenString instead, like this:

FBSDKAccessToken* access_token =[FBSDKAccessToken currentAccessToken].tokenString; NSLog(@"Access Token, %@",access_token);

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!