Аутентификация Swift AWS Cognito: didCompleteStepWithError вызывается только при втором входе в систему - PullRequest
0 голосов
/ 05 марта 2019

У меня возникли проблемы с реализацией потока аутентификации AWS Cognito в моем приложении iOS.

Аутентификация прошла успешно, но только если я запускаю поток во второй раз.В первый раз вызывается метод getDetails (), но didCompleteStepWithError () не вызывается.

Вот мои AWSCognitoIdentityInteractiveAuthenticationDelegate и AWSCognitoIdentityPasswordAuthentication:

import UIKit
import AWSCognito
import AWSCognitoIdentityProvider

class LoginViewController: UIViewController , AWSCognitoIdentityInteractiveAuthenticationDelegate, AWSCognitoIdentityPasswordAuthentication{


@IBOutlet weak var loginButton: UIButton!
@IBOutlet weak var loginButtonStackView: UIStackView!
@IBOutlet weak var cancelButton: UIButton!
@IBOutlet weak var emailTextField: UITextField!
@IBOutlet weak var passwordTextField: UITextField!
var passwordAuthenticationCompletion: AWSTaskCompletionSource<AWSCognitoIdentityPasswordAuthenticationDetails>?
let pool = AWSCognitoIdentityUserPool(forKey: "UserPool")
let fbLoginButton: FBSDKLoginButton = {
    let button = FBSDKLoginButton()
    button.readPermissions = ["email","public_profile"]
    return button
}()

override func viewDidLoad() {
    super.viewDidLoad()
    fbLoginButton.frame = loginButton.frame
    loginButtonStackView.addArrangedSubview(fbLoginButton)
    pool.delegate = self

}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    if FBSDKAccessToken.currentAccessTokenIsActive() {
        HandlePayment.getExistingPaymentMethods()
        dismiss(animated: true, completion: nil)
        if DataStructures.paymentMethods.isEmpty {
            DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
                NotificationCenter.default.post(name: NSNotification.Name("goToPaymentPageVC"), object: nil)
            }
        } else {
            if let clubsViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ClubsViewController") as? ClubsViewController {
                self.present(clubsViewController, animated: true, completion: nil)
            }
        }
}

}

@objc func dismissLoginPage() {
    dismiss(animated: true, completion: nil)
    DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
        NotificationCenter.default.post(name: NSNotification.Name("goToPaymentPageVC"), object: nil)
    }
}


@IBAction func loginTap(_ sender: Any) {
    if let email = emailTextField.text, let password = passwordTextField.text {
        if email.isValidEmail() {
            pool.clearLastKnownUser()
            let authDetails = AWSCognitoIdentityPasswordAuthenticationDetails.init(username: email.lowercased(), password: password)
            self.passwordAuthenticationCompletion?.set(result: authDetails)
            pool.currentUser()?.getSession()

        } else {
            let alert = UIAlertController(title: "Alert", message: "Invalid Email or password", preferredStyle: UIAlertController.Style.alert)
            alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
            self.present(alert, animated: true, completion: nil)
        }
    }
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    emailTextField.resignFirstResponder()
    passwordTextField.resignFirstResponder()
}



func getDetails(_ authenticationInput: AWSCognitoIdentityPasswordAuthenticationInput, passwordAuthenticationCompletionSource:
    AWSTaskCompletionSource<AWSCognitoIdentityPasswordAuthenticationDetails>) {
    self.passwordAuthenticationCompletion = passwordAuthenticationCompletionSource
    DispatchQueue.main.async {
        if (self.emailTextField.text == nil) {
            self.emailTextField.text = authenticationInput.lastKnownUsername
        }
    }
}

func didCompleteStepWithError(_ error: Error?) {
    DispatchQueue.main.async {
        if let error = error as NSError? {
            print("error completeStep")
            let alertController = UIAlertController(title: "Error",
                                                    message: error.userInfo["message"] as? String,
                                                    preferredStyle: .alert)
            let retryAction = UIAlertAction(title: "Retry", style: .default, handler: nil)
            alertController.addAction(retryAction)

            self.present(alertController, animated: true, completion:  nil)
        } else {
            self.emailTextField.text = nil
            self.dismiss(animated: true, completion: nil)

        }
    }
}

func startPasswordAuthentication() -> AWSCognitoIdentityPasswordAuthentication {
    return self
}
}

и присваивают ему соответствующий кодвверх в AppDelegate:

    func setupAWSCognitoUserPool() {
    // setup logging
    AWSDDLog.sharedInstance.logLevel = .verbose

    // setup service configuration
    let serviceConfiguration = AWSServiceConfiguration(region: .EUCentral1, credentialsProvider: nil)

    // create pool configuration
    let poolConfiguration = AWSCognitoIdentityUserPoolConfiguration(clientId: "1_XXXXXXXXX",
                                                                    clientSecret: "1_XXXXXXXXX",
                                                                    poolId: "eu-central-1_XXXXXXXXX")

    // initialize user pool client
    AWSCognitoIdentityUserPool.register(with: serviceConfiguration, userPoolConfiguration: poolConfiguration, forKey: "UserPool")


    self.storyboard = UIStoryboard(name: "Pageview", bundle: nil)

}

Как я уже говорил, при первом нажатии на кнопку входа в систему вызывается getDetails, а didCompleteStepWithError - нет.Если пользователь затем снова нажимает на кнопку входа в систему, вызывается метод getDetails, а затем didCompleteStepWithError, и поток проверки подлинности прошел успешно.

Кто-то знает, почему мой код ведет себя так, как он?

...