Ios FBSDKAccessToken currentAccessToken退出应用程序后为零

Ios FBSDKAccessToken currentAccessToken退出应用程序后为零,ios,swift,facebook-login,facebook-access-token,fbsdk,Ios,Swift,Facebook Login,Facebook Access Token,Fbsdk,我正在开发一个ios应用程序,使用Facebook SDK登录。 我已经将一个LogInViewController设置为故事板中的初始视图控制器,用户从中使用FB帐户登录 我有另一个ViewController,它在用户登录后正确加载 在AppDelegate文件中,我正在检查currentAccessToken,如果它不是nil,我将直接加载第二个ViewController,因为用户已经登录 但是,如果我退出应用程序并重新启动它,currentAccessToken始终为零。只有在应用程序

我正在开发一个ios应用程序,使用Facebook SDK登录。 我已经将一个
LogInViewController
设置为故事板中的初始视图控制器,用户从中使用FB帐户登录

我有另一个ViewController,它在用户登录后正确加载

在AppDelegate文件中,我正在检查
currentAccessToken
,如果它不是nil,我将直接加载第二个ViewController,因为用户已经登录

但是,如果我退出应用程序并重新启动它,
currentAccessToken
始终为零。只有在应用程序仍在后台运行时,我按下home(主页)按钮并重新打开应用程序,它才会起作用

以下是代码中的详细信息:

AppDelegate.swift

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    self.customNavigationBar()
    if (!isIcloudAvailable()) {
        self.displayAlertWithTitle("iCloud", message: "iCloud is not available." +
           " Please sign into your iCloud account and restart this app")
        return true
    }

    if (FBSDKAccessToken.currentAccessToken() != nil) {
        self.instantiateViewController("MapViewController", storyboardIdentifier: "Main")
    }

    return FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
}

func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
    return FBSDKApplicationDelegate.sharedInstance().application(
            application,
            openURL: url,
            sourceApplication: sourceApplication,
            annotation: annotation)
}

func applicationWillResignActive(application: UIApplication) {
        FBSDKAppEvents.activateApp()
}

func applicationDidBecomeActive(application: UIApplication) {
        FBSDKAppEvents.activateApp()
}
override func viewDidLoad() {
    super.viewDidLoad()    
    // Listen to the Facebook notification and when received, execute func handleFBSessionStateChangeWithNotification
NSNotificationCenter.defaultCenter().addObserver(self, selector:"handleFBSessionStateChangeWithNotification:", name: "SessionStateChangeNotification", object: nil)
}

func handleFBSessionStateChangeWithNotification(notification: NSNotification) {
    // Switch to MapViewController when logged in
    if ((FBSDKAccessToken.currentAccessToken()) != nil) {
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let mapViewController = storyboard.instantiateViewControllerWithIdentifier("MapViewController") as! MapViewController
        self.presentViewController(mapViewController, animated: false, completion: nil)
    }
}
LogInViewController.swift

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    self.customNavigationBar()
    if (!isIcloudAvailable()) {
        self.displayAlertWithTitle("iCloud", message: "iCloud is not available." +
           " Please sign into your iCloud account and restart this app")
        return true
    }

    if (FBSDKAccessToken.currentAccessToken() != nil) {
        self.instantiateViewController("MapViewController", storyboardIdentifier: "Main")
    }

    return FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
}

func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
    return FBSDKApplicationDelegate.sharedInstance().application(
            application,
            openURL: url,
            sourceApplication: sourceApplication,
            annotation: annotation)
}

func applicationWillResignActive(application: UIApplication) {
        FBSDKAppEvents.activateApp()
}

func applicationDidBecomeActive(application: UIApplication) {
        FBSDKAppEvents.activateApp()
}
override func viewDidLoad() {
    super.viewDidLoad()    
    // Listen to the Facebook notification and when received, execute func handleFBSessionStateChangeWithNotification
NSNotificationCenter.defaultCenter().addObserver(self, selector:"handleFBSessionStateChangeWithNotification:", name: "SessionStateChangeNotification", object: nil)
}

func handleFBSessionStateChangeWithNotification(notification: NSNotification) {
    // Switch to MapViewController when logged in
    if ((FBSDKAccessToken.currentAccessToken()) != nil) {
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let mapViewController = storyboard.instantiateViewControllerWithIdentifier("MapViewController") as! MapViewController
        self.presentViewController(mapViewController, animated: false, completion: nil)
    }
}
我不知道它是否相关,但我还收到了一条关于
MapViewController
的警告,因为故事板上没有向它添加任何分段:

警告:尝试显示其视图不在列表中的MapViewController 窗口层次结构


问题是因为您在调用之前正在调用
FBSDKAccessToken.currentAccessToken()

FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
您可以在拨打上述线路后随时检查访问令牌

编辑:解释

上面这一行允许Facebook SDK处理启动选项并提取必要的信息,这些信息是识别和保存应用程序用户所需的


在用户已经登录的情况下,这只需初始化Facebook SDK,然后根据持久数据登录用户。

我花了整整半天的时间来讨论这个问题。尽管确保所有委托方法都存在,
FBSDKAccessToken.current()
始终返回nil

事实证明,这是因为没有启用密钥链共享(Xcode 8,iOS 10)。要修复此问题,请转到应用程序->功能->钥匙链共享并启用


完成此操作后,您仍需通过授权流程并返回应用程序。之后一切都会好起来的

如果您已经尝试了解决方案,但仍然存在问题,请尝试此方法

我和我的合作程序员正在使用Facebook Swift SDK中提供的
LoginManager().login
方法。(Xcode8、Swift 3、iOS 10)

导致该问题的一个可能操作是,您成功登录并立即终止应用程序,然后再次打开应用程序,并且
AccessToken.current
返回
nil
。登录后,如果您等待20秒或更长时间(我们不确定确切的等待时间,我们等待了7-20秒)并关闭应用程序,问题似乎得到了解决


我们不确定为什么会发生这种情况,但这解决了我们的问题,我们猜测可能存在网络延迟或错误。

对于那些即使在appdelegate上设置了
FBSDKApplicationDelegate.sharedInstance()
后仍有问题的用户,如果您在Xcode控制台上遇到类似这样的错误,就可以使用它

Falling back to storing access token in NSUserDefaults because of simulator bug
这是模拟器的错误,我尝试使用真实的设备,它的工作,访问令牌不是零再次。。
因此,可能需要在@Kal answer..

FBAccessToken.currentAccessToken上回答@victor对这一问题的评论。您应该使用sessionStateChangedNotification等待它可用(您已经这样做了)。谢谢您的回答。需要多少时间?这意味着,如果用户很快退出应用程序,他将需要重新登录?我记得在以前的FBSDK版本中,有一个缓存访问令牌的检查,现在我不知道该怎么做。我已经尝试将sessionsStateChangedNotification放在LoginViewController的视图中,但没有任何更改。@ZeMoon能否请您详细说明您的答案。@Kaunteya Facebook SDK在您对其进行任何操作之前需要一次初始化的机会。你能详细说明一下吗?这对我不起作用。FBSDKAccessToken.currentAccessToken()在登录时提供正确的令牌。但在关闭应用程序后将为零。你提到的appdelefate方法没有任何区别,对我也不起作用。上面的行位于AppDelegate中,在FBSDKAccessToken.current()方法之前被调用。但我还是得到了零分,这对我来说确实有效。如果它对您不起作用,请确保您是从AppDelegate内部调用它,当覆盖
-[application:didFinishLaunchingWithOptions:
,并将您在那里收到的相同参数传递给
FBSDKApplicationDelegate
应用程序
启动选项
)时,您也尝试了此操作,还是不为我工作。模拟器只是松开了它的会话。这可能与我在日志中得到的字符串有关:“由于模拟器错误,正在退回到在NSUserDefaults中存储访问令牌”@victor-您是否验证了问题是否继续在真实设备上测试?尚未在真实设备上尝试。似乎它应该在模拟器上工作-好奇是否有人让它在设备上工作而不是在模拟器上