AWS Cognito User Pools in iOS (Swift) app
<p>I'm trying to implement the new AWS Cognito User Pools in my iOS (Swift) app, but I'm struggling to get the sign in process to work. I am essentially trying to follow the example available <a href="https://github.com/awslabs/aws-sdk-ios-samples/tree/developer-authenticated-identities-2-4/CognitoYourUserPools-Sample/Objective-C/CognitoYourUserPoolsSample" rel="noreferrer">here</a>.</p>

<p>This is what I have so far:</p>

<p>AppDelegate:</p>

<pre><code>class AppDelegate: UIResponder, UIApplicationDelegate, AWSCognitoIdentityInteractiveAuthenticationDelegate {
    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -&gt; Bool {
        let serviceConfiguration = AWSServiceConfiguration(region: AWSRegionType.USEast1, credentialsProvider: nil)
        AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = serviceConfiguration
        let configurationUserPool = AWSCognitoIdentityUserPoolConfiguration(
            clientId: "###",
            clientSecret: "#########",
            poolId: "###")
        AWSCognitoIdentityUserPool.registerCognitoIdentityUserPoolWithConfiguration(serviceConfiguration, userPoolConfiguration: configurationUserPool, forKey: "UserPool")
        self.userPool = AWSCognitoIdentityUserPool(forKey: "UserPool")

        self.userPool!.delegate = self

        return true
    }

    func startPasswordAuthentication() -&gt; AWSCognitoIdentityPasswordAuthentication {
        let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let logInNavigationController = mainStoryboard.instantiateViewControllerWithIdentifier("LogInNavigationController") as! UINavigationController

        dispatch_async(dispatch_get_main_queue(), {
            self.window?.rootViewController = logInNavigationController
        })

        let logInViewController = mainStoryboard.instantiateViewControllerWithIdentifier("LogInViewController") as! LogInViewController
        return logInViewController
    }
}
</code></pre>

<p>LogInViewController:</p>

<pre><code>class LogInViewController: UIViewController, AWSCognitoIdentityPasswordAuthentication {
    var usernameText : String?
    var passwordAuthenticationCompletion = AWSTaskCompletionSource()

    func getPasswordAuthenticationDetails(authenticationInput: AWSCognitoIdentityPasswordAuthenticationInput, passwordAuthenticationCompletionSource: AWSTaskCompletionSource) {
        self.passwordAuthenticationCompletion = passwordAuthenticationCompletionSource

        dispatch_async(dispatch_get_main_queue(), {
            if self.usernameText == nil {
                self.usernameText = authenticationInput.lastKnownUsername
            }
        })
    }

    func didCompletePasswordAuthenticationStepWithError(error: NSError) {
        dispatch_async(dispatch_get_main_queue(), {
            let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
            let mainNavigationController = mainStoryboard.instantiateViewControllerWithIdentifier("MainNavigationController") as! UINavigationController
            (UIApplication.sharedApplication().delegate as! AppDelegate).window?.rootViewController = mainNavigationController
        })
    }

    func logInButtonPressed() {
        self.passwordAuthenticationCompletion.setResult(AWSCognitoIdentityPasswordAuthenticationDetails(username: emailTextField.text, password: passwordTextField.text))
    }
}
</code></pre>

<p>Nothing seems to happen when I hit the log in button, although if I hit it again I get an NSInternalInconsistencyException (which I believe is because the AWSTask result has already been set).</p>

<p>Any help with this would be appreciated. I am using the AWS SDK for iOS version 2.4.1.</p>

<p><strong>UPDATE:</strong></p>

<p>Not a solution to my original problem, but I've been able to get User Pools working by using the explicit sign in method rather than the delegate method (see this <a href="http://docs.aws.amazon.com/cognito/latest/developerguide/using-amazon-cognito-user-identity-pools-ios-sdk.html#using-amazon-cognito-user-identity-pools-ios-sdk-user-sign-in" rel="noreferrer">page</a> for details). Here is the code from my SignInViewController:</p>

<pre><code>class SignInViewController: UIViewController {
    @IBAction func signInButtonTouched(sender: UIButton) {
        if (emailTextField.text != nil) &amp;&amp; (passwordTextField.text != nil) {
            let user = (UIApplication.sharedApplication().delegate as! AppDelegate).userPool!.getUser(emailTextField.text!)
            user.getSession(emailTextField.text!, password: passwordTextField.text!, validationData: nil, scopes: nil).continueWithExecutor(AWSExecutor.mainThreadExecutor(), withBlock: {
                (task:AWSTask!) -&gt; AnyObject! in

                if task.error == nil {
                    // user is logged in - show logged in UI
                } else {
                    // error
                }

                return nil
            })
        } else {
            // email or password not set
        }
    }
}
</code></pre>

<p>Then, to consume an AWS service (which in my case is located in a different region to Cognito) I have created a new Credentials Provider using the User Pool:</p>

<pre><code>let credentialsProvider = AWSCognitoCredentialsProvider(regionType: .USEast1, identityPoolId: "###", identityProviderManager: (UIApplication.sharedApplication().delegate as! AppDelegate).userPool!)
let serviceConfiguration = AWSServiceConfiguration(region: .APNortheast1, credentialsProvider: credentialsProvider)
AWSLambdaInvoker.registerLambdaInvokerWithConfiguration(serviceConfiguration, forKey: "Lambda")
let lambdaInvoker = AWSLambdaInvoker(forKey: "Lambda")
</code></pre>

<p>One additional issue is that I was seeing this error each time I launched the app: "Could not find valid 'AWSDefaultRegionType', 'AWSCognitoRegionType', and 'AWSCognitoIdentityPoolId' values in info.plist.". This seems to be related to Fabric, which I am using to track crashes. I've solved this by changing this line in the AppDelegate:</p>

<pre><code>Fabric.with([AWSCognito.self, Crashlytics.self])
</code></pre>

<p>to this:</p>

<pre><code>Fabric.with([Crashlytics.self])
</code></pre>

<p>I hope this helps someone else.</p>