Быстрая попытка представить UIAlertController, чье представление не находится в иерархии окон (представлено после TWTRShareEmailViewController)

Я использую логин Twitter в процессе регистрации моего приложения. И я прошу электронную почту пользователя. Как только я его получу, я хотел бы представить UIAlertController.

Вот мой код:

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

Но я получаю эту ошибку (я думаю, потому что TWTRShareEmailViewController не отклонен):

Предупреждение: попытайтесь представить UIALertController на xViewController, чье представление не находится в иерархии окон!

Любая идея о том, как я должен написать это? Как я могу узнать, когда TWTRShareEmailViewController будет отклонен, чтобы продолжить процесс регистрации и представить свой UIAlertController? Я не знаю о методе делегата, связанном с TWTRShareEmailViewController.

Любая помощь приветствуется. Спасибо.


person Marie Dm    schedule 31.03.2015    source источник


Ответы (4)


Нашел решение здесь . Я, вероятно, делаю это неправильно, но если нет, это может быть ошибка Apple. Обходной путь — отложить представление UIAlertController:

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

EDIT: я нашел другой обходной путь (я больше не использую решение, которое я здесь изложил). Мне пришлось изменить это, потому что вход в Твиттер также нарушал мои переходы между венчурными капиталистами.

Теперь я вызываю конкретный UIViewController (я назвал его примерно TWLoginVC), где я делаю все входы в Твиттер и другие вещи. Представление просто черное, поэтому пользователь не видит, что процесс на самом деле выполняется в другом VC (ему просто нужно выбрать пользователя Twitter, с которым он хочет войти). Я думаю, вы могли бы также поставить чистый фон, чтобы быть еще более невидимым.

Когда я вызываю этот контроллер представления и закрываю его, переход к нему не применяется, и у меня больше нет с ним проблем.


EDIT Обновление для Swift:

DispatchQueue.main.async{
     self.present(alertController, animated: true, completion: nil)
}
person Marie Dm    schedule 14.04.2015
comment
Вы нашли лучшее решение для этой проблемы? Я также использую dispatch_async - person ignacio chiazzo; 04.03.2016
comment
Как я объяснил в своем отредактированном ответе, у меня есть специальный VC для Твиттера. Поэтому, когда пользователь хочет войти в систему с помощью Twitter, я модально представляю свой «TWLoginVC», где все делается (в некоторых случаях избегая странного поведения, например, со специальными переходами между VC). Но я немного изменил свой код, и мне больше не нужно представлять UIAlertController. Так что нет, извините, у меня нет лучшего решения :/ - person Marie Dm; 04.03.2016
comment
С новым TwitterKit (я только что обновил его до версии 2.0.2) изменился способ запроса электронной почты пользователей. Это объясняется в документе Twitter: docs.fabric.io/ios. /twitter/request-user-email-address.html. - person Marie Dm; 22.04.2016

Вот обновленный ответ для Swift 3, протестированный на Xcode 8, на основе ответа Мари Дм.

DispatchQueue.main.sync {
     self.present(alertController, animated: true, completion: nil)
}
person Asdrubal    schedule 10.11.2016

Если DispatchQueue.main.sync вызвал крах, попробуйте DispatchQueue.main.async. «асинхронный» работал для моей проблемы при возвращении из contactPicker().

person HIEPING    schedule 16.07.2017

задержка представления viewController решила мою проблему и спасла мой день: D

Свифт 4.0:

DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { 
    //present your view controller her
    self.presentViewController(alertController, animated: true, completion: nil)
}
person Amer AlZibak    schedule 17.07.2020
comment
добавление кода, основанного на времени (который затем основан на устройстве), как это, никогда не бывает хорошей идеей. - person Sat Thiru; 16.02.2021