2015-03-31 13 views
14

Sto utilizzando il login di Twitter nel processo di registrazione della mia app. E sto chiedendo l'email dell'utente. Una volta ottenuto, mi piacerebbe presentare un UIAlertController.Swift Tentativo di presentare UIAlertController la cui vista non è nella gerarchia delle finestre (presentata dopo TWTRShareEmailViewController)

Ecco il mio codice:

func askForTWMail(){ 
    if (Twitter.sharedInstance().session() != nil) { 
     let shareMailVC=TWTRShareEmailViewController(completion: {(mail:String!, error:NSError!) in 
      if (mail != nil) { 
       print("GOT MAIL: \(mail)") 
       self.gotMail() 
      }else{ 
       print("MAIL VC ERROR: \(error)") 
      } 
     }) 
     println("PRESENT MAIL VC") 
     self.presentViewController(shareMailVC, animated: true, completion: nil) 
    }else{ 
     println("User not logged in") 
    } 
} 

func gotMail(){ 
    var alertController=UIAlertController(title: "Some title", message: "Some message", preferredStyle: UIAlertControllerStyle.Alert) 
    var okAction=UIAlertAction(title:"Yes", style: UIAlertActionStyle.Default) { 
    UIAlertAction in 
    //some action 
    } 
    var cancelAction=UIAlertAction(title:"No", style: UIAlertActionStyle.Cancel){ 
    UIAlertAction in 
    //some action 
    } 
    alertController.addAction(okAction) 
    alertController.addAction(cancelAction) 
    self.presentViewController(alertController, animated: true, completion: nil)     
} 

ma ottengo questo errore (credo perché il TWTRShareEmailViewController non è respinto):

Attenzione: tentativo di presentare UIALertController su xViewController cui vista non è nella gerarchia della finestra!

Qualche idea su come dovrei scrivere questo? Come posso sapere quando lo TWTRShareEmailViewController viene rimosso per continuare la procedura di registrazione ed essere in grado di presentare il mio UIAlertController? Non sono a conoscenza di un metodo delegato relativo a TWTRShareEmailViewController.

Qualsiasi aiuto è apprezzato. Grazie.

risposta

31

Trovato una soluzione here. Probabilmente sto sbagliando ma in caso contrario potrebbe essere un bug di Apple. La soluzione è quello di ritardare la presentazione della UIAlertController:

dispatch_async(dispatch_get_main_queue(), ^{ 
    self.presentViewController(alertController, animated: true, completion: nil) 
}) 

EDIT: ho trovato un'altra soluzione (io non uso la soluzione che ho messo giù più qui). Ho dovuto cambiare questo perché il login di Twitter stava anche rompendo le mie transizioni tra VC.

Ora chiamo uno specifico UIViewController (l'ho chiamato qualcosa come TWLoginVC) dove faccio tutto il login di Twitter e altre cose. La vista è solo nera, quindi l'utente non vede il processo in realtà è fatto in un altro VC (deve solo prendere l'utente di Twitter con cui vuole accedere). Immagino che potresti anche mettere uno sfondo chiaro per essere ancora più invisibile.

Quando chiamo questo controller vista e lo disgiungi, la transizione non viene applicata ad esso e non ho più alcun problema con esso.


EDIT Aggiornamento per Swift:

DispatchQueue.main.async{ 
    self.present(alertController, animated: true, completion: nil) 
} 
+0

Hai trovato una soluzione migliore per questo problema? Sto anche usando dispatch_async –

+0

Come ho spiegato nella mia risposta modificata, ho un VC speciale per le cose di Twitter. Quindi, quando l'utente vuole accedere con Twitter, io presento modamente il mio "TWLoginVC" dove tutto è fatto (evitando comportamenti strani in alcuni casi, con transizioni speciali tra VC per esempio). Ma ho cambiato il mio codice un po 'e non ho più bisogno di presentare un UIAlertController. Quindi non mi dispiace non ho una soluzione migliore:/ –

+1

Con il nuovo TwitterKit (l'ho appena aggiornato alla 2.0).2), il modo per richiedere l'e-mail degli utenti è cambiato. È spiegato nel documento Twitter: https://docs.fabric.io/ios/twitter/request-user-email-address.html. –

5

Ecco una risposta aggiornata per Swift 3 testato su Xcode 8 sulla base di risposta di Marie Dm.

DispatchQueue.main.sync { 
    self.present(alertController, animated: true, completion: nil) 
} 
-1

Se DispatchQueue.main.sync schiacciamento causato, provare DispatchQueue.main.async. "async" ha funzionato per il mio problema mentre tornavo da contactPicker().

Problemi correlati