xcode присутствует segue при восстановительном обратном вызове (быстрый)

Я сам научил пользователя Swift и пытаюсь сделать что-то простое, но у меня все в порядке. У меня простая форма регистрации. После отправки элементов для регистрации я хочу переместить страницу на страницу «как это работает» через segue, но ТОЛЬКО, когда мой успокаивающий API возвращает успех. Вот что я до сих пор; не стесняйтесь присылать мне лучший способ сделать это. Все критические замечания приветствуются.

let myUrl = NSURL(string:"http://www.example.com/scripts/Register.php") let request = NSMutableURLRequest(URL: myUrl!) request.HTTPMethod = "POST" let postString = "email=\(email)&password=\(pass)" request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding) let task = NSURLSession.sharedSession().dataTaskWithRequest(request){ data, response, error in if (error != nil) { println("Error: \(error)") return } var err: NSError? var json = NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers, error: &err) as? NSDictionary var showTutorial : Bool = false if let parseJSON = json { var returnValue = parseJSON["status"] as? String println("Status: \(returnValue)") var isUserRegistered: Bool = false if (returnValue == "Success") { showTutorial = true } else if (returnValue == "Error") { // handle error } } // if successful registration, show how it works page if (showTutorial) { self.performSegueWithIdentifier("howItWorksSegue", sender: self) } } task.resume() 

У меня есть howItWorksSegue именем howItWorksSegue прикрепленный к этому контроллеру представления, идущему в HowItWorksViewController . Я получаю эту ошибку от Xcode:

2015-10-12 21: 22: 43.261 ZiftDine [11396: 2307755] Ошибка утверждения в – [UIKeyboardTaskQueue waitUntilAllTasksAreFinished], /SourceCache/UIKit_Sim/UIKit-3347.44.2/Keyboard/UIKeyboardTaskQueue.m:374
2015-10-12 21: 22: 43.391 ZiftDine [11396: 2307755] Завершение приложения из-за неперехваченного исключения «NSInternalInconsistencyException», причина: '- [UIKeyboardTaskQueue waitUntilAllTasksAreFinished] может вызываться только из основного потока.'

    Все, что сделано с пользовательским интерфейсом, должно выполняться в основном потоке, попробуйте сделать так, чтобы вы выполняли вызов функции следующим образом:

     dispatch_async(dispatch_get_main_queue(),{ self.performSegueWithIdentifier("howItWorksSegue", sender: self) }) 

    @ Swinny89 дал решение вашей проблемы, но некоторые объяснения в порядке.

    Если вы прочитали описание dataTaskWithRequest:completionHandler: который является тем методом, который вы используете (хотя ваш код Swift использует синтаксис закрывающего закрытия, чтобы удалить метку completionHandler и поместить закрытие вне круглых скобок), он говорит:

    completeHandler: обработчик завершения вызова, когда запрос на загрузку завершен. Этот обработчик выполняется в очереди делегатов.

    Затем, если вы прочитаете описание метода init sessionWithConfiguration:delegate:delegateQueue: он говорит:

    queue: очередь для планирования вызовов делегатов и обработчиков завершения. Если nil, сеанс создает очередь последовательных операций для выполнения всех вызовов метода делегата и вызовов обработчика завершения.

    Серийные очереди выполняются в другом потоке.

    Итак, объединяя все эти части информации, это означает, что ваше завершение закрытия будет выполняться в потоке, отличном от основного потока.

    Основным правилом разработки iOS / Mac является то, что вы должны выполнять все вызовы пользовательского интерфейса из основного потока. Если вызов меняет что-либо на экране, это вызов пользовательского интерфейса.

    Ваш код вызывает performSegueWithIdentifier: из фонового потока. Он изменяет то, что отображается на экране, поэтому это должен быть вызов пользовательского интерфейса. Поэтому его нужно запускать на основном потоке.

    Функция GCD dispatch_async() с очередью dispatch_get_main_queue() отправляет закрытие, которое должно быть запущено в основной диспетчерской очереди, очередь, которая выполняется в основном потоке.

    Поэтому решение Swinny устраняет вашу проблему.

    Выезд здесь:

    Каждый раз, когда вы запускаете код в закрытии, остановитесь и подумайте: «Я уверен, что это закрытие всегда будет выполняться в основном потоке?» Если ответ отрицательный, приложите код к вызову dispatch_async(dispatch_get_main_queue() , как ответ Swinny.

    Ответы @Duncan C и @ Swinny89 хорошие. Для всех, кто пришел из Google, синтаксис в Swift 3 немного изменился:

     DispatchQueue.main.async(execute: { self.performSegueWithIdentifier("howItWorksSegue", sender: self) }) 
    Interesting Posts

    Доступ к ManagedObjectContext

    как липкие 2 столбца с использованием горизонтальной и вертикальной прокрутки в UICollectionView

    Как остановить вращение с помощью viewWillTransitionToSize

    UILabel.text с Singleton String – nil – Предупреждение: попытка представить **, чей вид отсутствует в иерархии окон

    Откройте телефон (звонок) с помощью кнопки и текстового поля / вида (iPhone)

    Является ли это действительным использованием NSNotificationCenter

    Анимация изменения пути CAShapeLayer

    IOS Как получить событие при загрузке xib-файла?

    Пользовательские переменные Google Analytics за клик, а не за сеанс

    Как вставить UIImagePickerController внутри UITabbarController

    Как установить фоновое изображение внутри календаря по умолчанию и пользовательский календарь

    «Подтвердить» в XCode 4

    создание формата изображения с неизвестным типом является ошибкой. От выбора изображения от фотобиблиотеки

    Неверный запрос Google api в ios5

    Приложение iPhone, скомпилированное с Xcode 6, работает как Universal на iPad

    Давайте будем гением компьютера.