Как вернуться в основной поток в Xcode? - PullRequest
0 голосов
/ 19 декабря 2018

Я использую свой SignUpViewController для создания учетной записи, и когда пользователь регистрирует учетную запись с паролем, который НЕ соответствует спецификации пароля, программа должна выдать предупреждение.По какой-то причине вместо этого я продолжаю получать:

Завершение приложения из-за необработанного исключения 'NSInternalInconsistencyException', причина: '- [UIKeyboardTaskQueue waitUntilAllTasksAreFinished] может вызываться только из основного потока.'

Как мне вернуться в основной поток, чтобы программа просто выдавала предупреждение?

Вот код для этого контроллера представления:

@IBAction func signupPressed(_ sender: Any) {
     // Get a reference to the user pool
    let userPool = AppDelegate.defaultUserPool()
    // Collect all of the attributes that should be included in the signup call
        let emailAttribute = AWSCognitoIdentityUserAttributeType(name: "email", value: self.email.text!)
        let firstNameAttribute = AWSCognitoIdentityUserAttributeType(name: "given_name", value: self.firstName.text!)
        let lastNameAttribute = AWSCognitoIdentityUserAttributeType(name: "family_name", value: self.lastName.text!)
        let birthdayAttribute = AWSCognitoIdentityUserAttributeType(name: "birthdate", value: self.birthday.text!)
    // Actually make the signup call passing in those attributes

        userPool.signUp(UUID().uuidString, password: self.password.text!, userAttributes: [emailAttribute, firstNameAttribute, lastNameAttribute, birthdayAttribute], validationData: nil)
        .continueWith { (response) -> Any? in
            if response.error != nil {
                // Error in the signup process
                let alert = UIAlertController(title: "Error", message: response.error?.localizedDescription, preferredStyle: .alert)
                alert.addAction(UIAlertAction(title: "OK", style: .default, handler:nil))
                self.present(alert, animated: true, completion: nil)
            } else {
                self.user = response.result!.user
                // Does user need verification?
                if (response.result?.userConfirmed?.intValue != AWSCognitoIdentityUserStatus.confirmed.rawValue) {
                    // User needs confirmation, so we need to proceed to the verify view controller
                    DispatchQueue.main.async {
                        self.performSegue(withIdentifier: "VerifySegue", sender: self)
                    }
                } else {
                    // User signed up but does not need verification
                    DispatchQueue.main.async {
                        self.presentingViewController?.dismiss(animated: true, completion: nil)
                    }
                }
            }
            return nil
    }
}

Ответы [ 5 ]

0 голосов
/ 19 декабря 2018

Наряду с DispatchQueue.main.async мы можем добавить [weak self] проверку, чтобы избежать сохранения цикла, например

DispatchQueue.main.async { [weak self] in
    self?.present(alert, animated: true, completion: nil)
}
0 голосов
/ 19 декабря 2018

Просто напишите

self.present(alert, animated: true, completion: nil)

внутри Dispatch.main.async, как вы уже делали для других сегментов

DispatchQueue.main.async {
                        self.present(alert, animated: true, completion: nil)
                    }
0 голосов
/ 19 декабря 2018

В вашем закрытии, где, если ошибка не равна нулю, вы можете обновить код следующим образом и повторить попытку:

if response.error != nil {
            // Error in the signup process

            DispatchQueue.main.async {
                let alert = UIAlertController(title: "Error", message: response.error?.localizedDescription, preferredStyle: .alert)
                alert.addAction(UIAlertAction(title: "OK", style: .default, handler:nil))
                self.present(alert, animated: true, completion: nil)    
            }
        } 
0 голосов
/ 19 декабря 2018

вы уже делаете маршалинг, представляя контроллер представления и выполняя segue с DispatchQueue.main.async.Вы также должны сделать это, чтобы отобразить UIAlertController.С тем же успехом вы можете просто направить все тело метода в основной поток.

0 голосов
/ 19 декабря 2018

Это также основной поток работы

DispatchQueue.main.async { 
    let alert = UIAlertController(title: "Error", message: response.error?.localizedDescription, preferredStyle: .alert)
    alert.addAction(UIAlertAction(title: "OK", style: .default, handler:nil))
    self.present(alert, animated: true, completion: nil)
}

Кстати, у вас может быть только 1 DispatchQueue.main.async, чтобы окружить ответ, если все должно быть сделано в основном

...