Ios FBSDKAccessToken currentAccessToken退出应用程序后为零
我正在开发一个ios应用程序,使用Facebook SDK登录。 我已经将一个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始终为零。只有在应用程序
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-您是否验证了问题是否继续在真实设备上测试?尚未在真实设备上尝试。似乎它应该在模拟器上工作-好奇是否有人让它在设备上工作而不是在模拟器上