Amazon AWS Cognito SDK для iOS (Swift) не вызывает делегата аутентификации UserPool - PullRequest
0 голосов
/ 02 марта 2020

Я работаю над приложением, которое аутентифицирует пользователей, используя AWS Cognito, используя UserPools. Я прочитал, скомпилировал и попытался понять примеры , предоставленные Amazon на GitHub.

В базовой архитектуре моего приложения используются шаблоны MVVM и Coordinator. Это то, что я чувствую уверенно, и мне бы хотелось, чтобы все было так.

Возможно, у меня есть некоторые пробелы в использовании этого SDK, но есть вещи, которые не работают, и я не знаю почему.

AFAIK SDK предполагает, что пользователь вошел в систему при запуске приложения. Теперь ваша очередь выполнить аутентификацию и подтвердить, вошел ли пользователь в систему или нет. Как я видел в приведенном примере, они делают это в AppDelegate. Как мне реализовать это с помощью координаторов? Проверьте статус входа в AppDelegate или AppCoordinator? . В настоящее время весь код находится внутри AppDelegate следующим образом:

import UIKit
import ReactiveSwift
import AWSCognitoIdentityProvider

// MARK: Undesranding how AWS Cognito works
// 1. The app assumes it is logged in and then triggers the delegate which triggers authenticatino of the login screens if it's not
// 2. The authentication delegate is triggered with pool.getUser().getDetails()


@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow? = UIWindow(frame: UIScreen.main.bounds)
    var rememberDeviceCompletionSource: AWSTaskCompletionSource<NSNumber>?

    lazy var appCoordinator: AppCoordinator = {
        guard let window = self.window else { fatalError() }
        let coordinator = AppCoordinator(window: window)
        return coordinator
    }()

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        AWSDDLog.sharedInstance.logLevel = .verbose

        let serviceConfiguration = AWSServiceConfiguration(region: cognitoIdentityUserPoolRegion, credentialsProvider: nil)

        let poolConfiguration = AWSCognitoIdentityUserPoolConfiguration(clientId: cognitoIdentityUserPoolAppClientId,
                                                                        clientSecret: cognitoIdentityUserPoolAppClientSecret,
                                                                        poolId: cognitoIdentityUserPoolId)

        AWSCognitoIdentityUserPool.register(with: serviceConfiguration, userPoolConfiguration: poolConfiguration, forKey: AWSCognitoUserPoolsSignInProviderKey)

        let pool = AWSCognitoIdentityUserPool(forKey: AWSCognitoUserPoolsSignInProviderKey)

        let currentUser = pool.currentUser()
        dump(currentUser)


        if let currentUser = currentUser {

            // I have some doubts here whether is correct or not    
            if currentUser.isSignedIn {
                appCoordinator.presentHomeViewController()
            } else {

                let user = pool.getUser()
                let details = user.getDetails()
                appCoordinator.start()

            }
        }

        return true
    }

}

// MARK: - AWSCognitoIdentityInteractiveAuthenticationDelegate protocol delegate
extension AppDelegate: AWSCognitoIdentityInteractiveAuthenticationDelegate {

    func startPasswordAuthentication() -> AWSCognitoIdentityPasswordAuthentication {

        let compositeDisposable = CompositeDisposable()
        let logInViewModel = LogInViewModel(compositeDisposable: compositeDisposable)
        let logInViewController = LogInViewController(viewModel: logInViewModel, compositeDisposable: compositeDisposable)

        return logInViewController
    }
}

AppDelegate правильно показывает мой UIViewController когда пользователь не вошел в систему. Презентация V C выполняется в AppCoordinator. Моя проблема возникает сейчас, когда я построил экран входа в систему, и когда я нажимаю кнопку входа в систему, никаких действий не выполняется, и я не знаю почему. Мой LogInViewController - вот этот,

import Foundation
import UIKit
import ReactiveSwift
import ReactiveCocoa

import AWSCore
import AWSCognito
import AWSCognitoIdentityProvider

class LogInViewController: UIViewController {

    var pool: AWSCognitoIdentityUserPool?
    var user: AWSCognitoIdentityUser?
    var passwordAuthenticationCompletion: AWSTaskCompletionSource<AWSCognitoIdentityPasswordAuthenticationDetails>?

    // Define the views and elements to be added to the View Controller

    let compositeDisposable: CompositeDisposable
    let viewModel: LogInViewModel

    init(viewModel: LogInViewModel, compositeDisposable: CompositeDisposable) {
        self.viewModel = viewModel
        self.compositeDisposable = compositeDisposable

        super.init(nibName: nil, bundle: nil)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func loadView() {
        // Add AutoLayout constraints for the views
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        setUpBindings()
    }

    func setUpBindings() {

        compositeDisposable += logInButton.reactive.controlEvents(.touchUpInside).observe({ [weak self] (_) in


            // I can see this printed in the console but no further action is performed
            print("Tapped LOG IN button")

            guard let self = self else { fatalError() }

            guard let email = self.emailTextField.text else { return }
            guard let password = self.passwordTextField.text else { return }

            let authDetails = AWSCognitoIdentityPasswordAuthenticationDetails(username: email, password: password)
            self.passwordAuthenticationCompletion?.set(result: authDetails)
            // At this point nothing happens, not even shows an error or a call to the didCompleteStepWithError function

            let user = self.pool?.getUser(email)
            user?.getDetails()
        })  
    }

    func configureAwsIdentity() {

            let serviceConfiguration = AWSServiceConfiguration(region: cognitoIdentityUserPoolRegion, credentialsProvider: nil)

            let poolConfiguration = AWSCognitoIdentityUserPoolConfiguration(clientId: cognitoIdentityUserPoolAppClientId,
                                                                            clientSecret: cognitoIdentityUserPoolAppClientSecret,
                                                                            poolId: cognitoIdentityUserPoolId)

            AWSCognitoIdentityUserPool.register(with: serviceConfiguration, userPoolConfiguration: poolConfiguration, forKey: AWSCognitoUserPoolsSignInProviderKey)

            // Fetch the user pool client we initialized in above step
            self.pool = AWSCognitoIdentityUserPool(forKey: AWSCognitoUserPoolsSignInProviderKey)
            self.pool!.delegate = self

            self.pool?.currentUser()?.getDetails()
            self.pool?.getUser().getDetails()
    }

    deinit {
        compositeDisposable.dispose()
    }
}

// MARK: AWS Cognito Identity Interactive Authentication Delegate
extension LogInViewController: AWSCognitoIdentityInteractiveAuthenticationDelegate {
    func startPasswordAuthentication() -> AWSCognitoIdentityPasswordAuthentication {
        return self
    }
}

extension LogInViewController: AWSCognitoIdentityPasswordAuthentication {

    public func getDetails(_ authenticationInput: AWSCognitoIdentityPasswordAuthenticationInput, passwordAuthenticationCompletionSource: AWSTaskCompletionSource<AWSCognitoIdentityPasswordAuthenticationDetails>) {

        self.passwordAuthenticationCompletion = passwordAuthenticationCompletionSource
        DispatchQueue.main.async {
            print("> Last known username: \(String(describing: authenticationInput.lastKnownUsername))")

        }
    }

    public func didCompleteStepWithError(_ error: Error?) {
        DispatchQueue.main.async {
            if let error = error as NSError? {

                guard let alertTitleString = error.userInfo["__type"] as? String else { return }
                guard let alertBodyString = error.userInfo["message"] as? String else { return }

                self.presentAlertViewWithError(title: alertTitleString, body: alertBodyString)
            } else {
                // Successful authentication, do whatever's needed!
                self.viewModel.presentTabBarControllerAfterSuccessfulAuthentication()
            }
        }
    }
}

Я не знаю, почему ничего не происходит после нажатия logInButton. Мне удалось заставить это работать несколько дней go, но оно внезапно перестало работать, и я не вижу, где это не так.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...