【问题标题】:FBSDKAccessToken currentAccessToken nil after quitting app退出应用程序后 FBSDKAccessToken currentAccessToken nil
【发布时间】:2016-01-02 05:56:27
【问题描述】:

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

我有另一个 ViewController,一旦用户登录,它就会正确加载。

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

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

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

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()
}

LogInViewController.swift

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 窗口层次结构!

【问题讨论】:

  • FBAccessToken.currentAccessToken 需要一些时间来填充。您应该使用 sessionStateChangedNotification 等待它可用(就像您已经完成的那样)。
  • 感谢您的回答。需要多少时间?这意味着如果用户很快退出应用程序,他将需要重新登录?我记得在以前的 FBSDK 版本中,有一个缓存访问令牌的检查,现在我不知道该怎么做。
  • 我尝试将 sessionStateChangedNotification 放在 LoginViewController 的 viewDidAppear 中,但没有任何改变。

标签: ios swift facebook-login facebook-access-token fbsdk


【解决方案1】:

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

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

您可以在调用上述代码后随时检查访问令牌。

编辑:解释

以上行让 Facebook SDK 处理 launchOptions 并提取必要的信息,以便识别和持久化应用程序的用户。

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

【讨论】:

  • @ZeMoon 你能详细说明你的答案吗?
  • @Kaunteya Facebook SDK 需要有机会在您对其进行任何操作之前进行初始化。您能否更具体地详细说明一下?
  • 这对我不起作用。 FBSDKAccessToken.currentAccessToken() 在登录时会给出正确的令牌。但杀死应用程序后将为零。您提到的 appdelfate 方法没有任何区别。
  • 对我也不起作用。上面的行在 AppDelegate 中,在 FBSDKAccessToken.current() 方法之前被调用。我仍然得到一个 nil 令牌
  • 它确实对我有用。如果它不适合您,请确保您在覆盖 -[application:didFinishLaunchingWithOptions:] 时从 AppDelegate 内部调用它,并将您在此处收到的相同参数传递给 FBSDKApplicationDelegateapplicationlaunchOptions
【解决方案2】:

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

原来这是因为没有启用钥匙串共享(Xcode 8、iOS 10)。要解决此问题,请转到 App -> Capabilities -> Keychain Sharing 并打开。

完成此操作后,您仍需完成授权流程并返回应用。之后一切都应该好了。

【讨论】:

  • 也试过了,还是不适合我。模拟器只是失去了它的会话。它是否与我在日志中得到的这个字符串有关:'由于模拟器错误而回退到在 NSUserDefaults 中存储访问令牌'
  • @victor - 您是否确认问题继续在真实设备上测试?
  • 还没有在真机上尝试过。似乎它应该在模拟器上工作 - 好奇是否有人让它在设备上而不是模拟器上工作
【解决方案3】:

如果您已经尝试了上述解决方案,但仍有问题,请尝试此操作。

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

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

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

【讨论】:

    【解决方案4】:

    对于那些即使在 appdelegate 上设置了FBSDKApplicationDelegate.sharedInstance() 后仍然遇到问题的人,如果你在 Xcode 控制台上遇到这样的错误,请查看

    Falling back to storing access token in NSUserDefaults because of simulator bug
    

    这是模拟器错误,我尝试使用真实设备并且它可以工作,访问令牌不再为零.. 所以也许可以在@Kal 答案上回答@victor 对此的评论..

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多