I am developing an ios app using the Facebook SDK to login.
I have set a LogInViewController
as the initial View Controller in the Storyboard, from where the user logins using the FB account.
I have another ViewController which is loaded correctly once the user logs in.
In the AppDelegate file I am checking for currentAccessToken
and if it is not nil, I am loading directly the second ViewController, because the user is already logged in.
However, the currentAccessToken
is always nil if I quit the app and relaunch it. It only works if I press the home button and re-open the app while it's still running in the background.
Here are the details in the code:
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)
}
}
I don't know if it is related, but I am also getting a warning for the MapViewController
because there is no segue put towards it from the Storyboard:
Warning: Attempt to present MapViewController whose view is not in the window hierarchy!
The problem is because you are calling for FBSDKAccessToken.currentAccessToken()
before having called
FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
You can check for the access token anytime after calling the above line.
EDIT: Explanation
The above line lets the Facebook SDK process the launchOptions and extract the necessary information which it will require to recognise and persist the user for the application.
In cases where the user is already logged in, this simply initialises the Facebook SDK which in turn logs in the user on the basis of persisted data.