2015-10-05 26 views
27

Sto sviluppando un'applicazione ios utilizzando l'SDK di Facebook per accedere. Ho impostato un LogInViewController come controller di visualizzazione iniziale nello storyboard, da cui l'utente accede utilizzando l'account FB.FBSDKAccessToken currentAccessToken nil dopo aver smesso di app

ho un altro ViewController che viene caricato correttamente una volta che l'utente accede a.

Nel file AppDelegate sto controllando per currentAccessToken e se non è pari a zero, sto caricando direttamente il secondo ViewController, perché l'utente è già registrato.

Tuttavia, lo currentAccessToken è sempre nullo se chiudo l'app e la riavvio. Funziona solo se premo il pulsante Home e riapri l'app mentre è ancora in esecuzione in background.

Ecco i dettagli nel codice:

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

Non so se si riferisce, ma ricevo anche un avviso per lo MapViewController perché non vi è alcun passaggio ERSO dalla Storyboard:

Attenzione: tentativo di presentare MapViewController la cui vista non è nella gerarchia finestra!

+0

FBAccessToken.currentAccessToken richiede un po 'di tempo per essere popolato. Dovresti aspettare che sia disponibile usando sessionStateChangedNotification (come hai già fatto). – ZeMoon

+0

Grazie per la risposta. Quanto tempo ha bisogno? Ciò significa che se l'utente chiude l'app abbastanza velocemente, dovrà effettuare nuovamente l'accesso? Ricordo nelle precedenti versioni di FBSDK, c'era un controllo per il token di accesso memorizzato nella cache, che ora non so come farlo. –

+0

Ho provato a mettere le sessioniStateChangedNotification in viewDidAppear di LoginViewController ma nulla è cambiato. –

risposta

51

Il problema è perché si sta chiamando per FBSDKAccessToken.currentAccessToken() prima di aver chiamato

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

È possibile verificare il token di accesso in qualsiasi momento dopo aver chiamato la linea di cui sopra.

EDIT: Spiegazione

La linea di cui sopra permette al processo di Facebook SDK le launchOptions ed estrarre le informazioni necessarie che sarà necessario riconoscere e persistere l'utente per l'applicazione.

Nei casi in cui l'utente abbia già effettuato l'accesso, questo semplicemente inizializza l'SDK di Facebook che a sua volta registra l'utente sulla base dei dati persistenti.

+0

@ZeMoon puoi per favore elaborare la tua risposta. – Kaunteya

+0

@ Kaunteya L'SDK di Facebook ha bisogno di essere inizializzato prima di eseguire qualsiasi operazione su di esso. Potresti essere più specifico su cosa elaborare? – ZeMoon

+2

Ottimo! Grazie ... Dove hai trovato questo nei documenti? –

13

Ho passato una bella mezza giornata sbattendo la testa contro questo problema. Nonostante si assicurasse che tutti i metodi delegati fossero presenti, lo FBSDKAccessToken.current() restituiva sempre zero.

Si scopre che questo è dovuto al fatto che Keychain Sharing non è abilitato (Xcode 8, iOS 10). Per risolvere, vai su App -> Funzionalità -> Condivisione portachiavi e attiva.

Una volta eseguita questa operazione, è necessario continuare la procedura di autorizzazione e tornare all'app. Tutto dovrebbe andare bene dopo.

+0

Provato anche questo, ancora non funziona per me. Il simulatore perde la sessione. Potrebbe essere correlato a questa stringa che ottengo nei registri: "Ritorno a memorizzare il token di accesso in NSUserDefaults a causa del bug del simulatore" – victor

+0

@victor: hai verificato che il problema continui a testare su un dispositivo reale? – syllabix

+0

Non l'ho ancora provato su un dispositivo reale. Sembra che dovrebbe funzionare sul simulatore - curioso se qualcuno lo avesse funzionato sul dispositivo e non sul simulatore – victor

-1

Se hai già provato le soluzioni su, ma hai ancora il problema, prova questo.

Il mio co-programmatore e io stiamo utilizzando il metodo LoginManager().login fornito in Facebook Swift SDK. (Xcode8, Swift 3, iOS 10)

Una possibile azione che ha causato quel problema è quando si effettua il login con successo e si chiude immediatamente l'app, quindi si riapre l'app e lo AccessToken.current restituisce nil. Dopo l'accesso, se si attende 20 secondi o più (non si è sicuri del tempo di attesa esatto, abbiamo aspettato per 7-20 secondi) e si è conclusa l'app, il problema sembrava risolto.

Non siamo sicuri del motivo per cui questo è successo, ma questo ha risolto il nostro problema, e la nostra ipotesi è che potrebbe esserci un ritardo di rete o un bug.

0

Per coloro che continua ad avere il problema anche dopo aver impostato il FBSDKApplicationDelegate.sharedInstance() sul AppDelegate, si rivelano se u get errore sulla tua console Xcode come questo

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

si è simulatore di bug e cerco tramite dispositivo reale e funziona, il token di accesso non è nul nuovo .. quindi forse rispondi a @ commento commento su questo su risposta @Kal ..