2015-10-05 17 views
27

Ich entwickle eine iOS-App mit dem Facebook SDK zum Anmelden. Ich habe eine LogInViewController als anfängliche View Controller im Storyboard eingestellt, von wo aus der Benutzer sich mit dem FB-Account anmeldet.FBSDKAccessToken currentAccessToken nil nach Beenden der App

ich einen anderen Viewcontroller haben, die korrekt, sobald die Benutzer anmeldet geladen wird.

In der AppDelegate Datei, die ich für currentAccessToken bin Überprüfung und wenn es nicht gleich Null ist, ich bin Laden direkt den zweiten Viewcontroller, weil der Benutzer bereits angemeldet.

Allerdings ist die currentAccessToken immer Null, wenn ich die App beende und neu starte. Es funktioniert nur, wenn ich die Home-Taste drücke und die App wieder öffne, während sie noch im Hintergrund läuft.

Hier sind die Details im 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) 
    } 
} 

Ich weiß nicht, ob es sich bezieht, aber ich bekomme auch eine Warnung für die MapViewController, weil es keine Überfahrt gibt owards es aus dem Storyboard:

Warnung: Versuch MapViewController deren Ansicht zu präsentieren ist nicht in der Fenster Hierarchie!

+0

FBAccessToken.currentAccessToken dauert einige Zeit, um ausgefüllt werden. Sie sollten darauf warten, dass es mit der sessionStateChangedNotification verfügbar ist (wie Sie es bereits getan haben). – ZeMoon

+0

Vielen Dank für Ihre Antwort. Wie viel Zeit braucht es? Das heißt, wenn der Benutzer die App schnell beendet, muss er sich erneut anmelden. Ich erinnere mich an frühere FBSDK-Versionen, es gab eine Überprüfung für zwischengespeicherte Zugriffstoken, die ich jetzt nicht weiß, wie das geht. –

+0

Ich habe versucht, die SessionsChangedNotification in ViewDidAppear des LoginViewController zu setzen, aber nichts geändert. –

Antwort

51

Das Problem ist, weil Sie für FBSDKAccessToken.currentAccessToken() fordern vor

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

Sie für den Zugriffstoken jederzeit überprüfen kann aufgerufen zu haben, nachdem die obige Zeile aufrufen.

EDIT: Erläuterung

Die obige Linie können die Facebook-SDK Prozess die launchOptions und die notwendigen Informationen extrahieren, die sie benötigen wird den Benutzer für die Anwendung zu erkennen und beharren.

In Fällen, in denen der Benutzer bereits angemeldet ist, initialisiert dies einfach das Facebook SDK, das den Benutzer wiederum auf der Grundlage von persistenten Daten anmeldet.

+0

@ZeMoon können Sie bitte Ihre Antwort erarbeiten. – Kaunteya

+0

@Kaunteya Das Facebook SDK muss initialisiert werden, bevor Sie eine Operation ausführen. Könnten Sie genauer erläutern, was zu erarbeiten ist? – ZeMoon

+2

Großartig! Danke-- Wo hast du das in den Dokumenten gefunden? –

13

Ich verbrachte einen schönen halben Tag mit meinem Kopf gegen dieses Problem. Obwohl sichergestellt wurde, dass alle Delegate-Methoden vorhanden waren, gab FBSDKAccessToken.current() immer nil zurück.

Es stellt sich heraus, dass dies daran liegt, dass Keychain Sharing nicht aktiviert ist (Xcode 8, iOS 10). Um zu beheben, gehen Sie zu App -> Fähigkeiten -> Keychain Sharing und schalten Sie ein.

Sobald dies erledigt ist, müssen Sie noch den Autorisierungsprozess durchlaufen und zur App zurückkehren. Alles sollte danach gut sein.

+0

habe ich auch versucht, funktioniert immer noch nicht für mich. Der Simulator verliert gerade seine Sitzung. Könnte es zu dieser Zeichenfolge, die ich in den Protokollen bekomme: "Zurück zum Speichern von Zugriffstoken in NSUserDefaults wegen Simulator-Fehler" – victor

+0

@victor - Haben Sie das Problem weiterhin getestet auf einem echten Gerät? – syllabix

+0

Habe es noch nicht auf einem echten Gerät versucht. Scheint, dass es am Simulator arbeiten sollte - neugierig, wenn jemand es am Gerät und nicht am Simulator arbeiten ließ – victor

-1

Wenn Sie bereits versucht, die Lösungen, aber immer noch das Problem haben, versuchen Sie es.

Mein Co-Programmierer und ich verwenden die in Facebook Swift SDK zur Verfügung gestellte Methode LoginManager().login. (Xcode8, Swift 3, iOS 10)

Eine mögliche Aktion, die dieses Problem verursacht, ist, wenn Sie sich erfolgreich anmelden und die App sofort beenden, dann öffnen Sie Ihre App erneut und AccessToken.current gibt nil zurück. Nach dem Login, wenn Sie 20 Sekunden oder länger warten (wir sind nicht sicher, die genaue Wartezeit, wir haben 7-20 Sekunden gewartet) und die App zu töten, schien das Problem gelöst zu sein.

Wir sind nicht sicher, warum das passiert ist, aber das hat unser Problem gelöst, und wir vermuten, dass es eine Netzwerkverzögerung oder einen Bug geben könnte.

0

Für diejenigen, die immer noch das Problem, die auch nach den FBSDKApplicationDelegate.sharedInstance() auf der AppDelegate gesetzt, entpuppen, wenn u Fehler auf Ihrer Xcode-Konsole wie diese

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

erhalten, ist es Simulator Fehler und ich versuche, reales Gerät verwenden und es funktioniert, das Access-Token ist nicht nil wieder .. so vielleicht Antwort @ VICTOR Kommentar über diese auf @KAL Antwort ..