swift - 使用 AWS 登录

标签 swift xcode swift3 xcode8

当我尝试使用 cognito aws 进行签名时,出现以下错误,它实际上会检查用户凭据,但会在运行时导致应用程序崩溃。

我想在成功登录后显示我的 mainView,但我不知道我缺少什么,但应用程序在运行时崩溃了。

我希望我能很好地解释自己。

   2017-02-19 19:46:12.770 HDPTestV2[28298:5420991] -[AWSTask exception]: unrecognized selector sent to instance 0x60000006ab40
2017-02-19 19:46:12.773 HDPTestV2[28298:5420991] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[AWSTask exception]: unrecognized selector sent to instance 0x60000006ab40'
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010b32dd4b __exceptionPreprocess + 171
    1   libobjc.A.dylib                     0x000000010ad9621e objc_exception_throw + 48
    2   CoreFoundation                      0x000000010b39df04 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132
    3   CoreFoundation                      0x000000010b2b3005 ___forwarding___ + 1013
    4   CoreFoundation                      0x000000010b2b2b88 _CF_forwarding_prep_0 + 120
    5   HDPTestV2                           0x0000000109d9f8f7 __35-[AWSIdentityManager completeLogin]_block_invoke_2 + 263
    6   libdispatch.dylib                   0x000000010d84f978 _dispatch_call_block_and_release + 12
    7   libdispatch.dylib                   0x000000010d8790cd _dispatch_client_callout + 8
    8   libdispatch.dylib                   0x000000010d8598a4 _dispatch_main_queue_callback_4CF + 406
    9   CoreFoundation                      0x000000010b2f1e49 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
    10  CoreFoundation                      0x000000010b2b737d __CFRunLoopRun + 2205
    11  CoreFoundation                      0x000000010b2b6884 CFRunLoopRunSpecific + 420
    12  GraphicsServices                    0x000000010f79ca6f GSEventRunModal + 161
    13  UIKit                               0x000000010b751c68 UIApplicationMain + 159
    14  HDPTestV2                           0x0000000109d9c8af main + 111
    15  libdyld.dylib                       0x000000010d8c568d start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) 

--> SignInController.swift

//  SignInViewController.swift
//  HDPTestV2
//
//  Created by Gael Wamba Musikingala on 2017/02/19.
//  Copyright © 2017 Gael Wamba Musikingala. All rights reserved.
//

import UIKit
import AWSMobileHubHelper
import AWSCognitoIdentityProvider

class SignInViewController: UIViewController {

    @IBOutlet weak var usernameField: UITextField!
    @IBOutlet weak var passwordField: UITextField!

    var passwordAuthenticationCompletion: AWSTaskCompletionSource<AWSCognitoIdentityPasswordAuthenticationDetails>?

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func onSignIn(_ sender: UIButton) {
        self.handleCustomSignIn()
    }

    func handleLoginWithSignInProvider(signInProvider: AWSSignInProvider){
        AWSIdentityManager.defaultIdentityManager().loginWithSign(signInProvider) { (result:Any?, error: Error?) in
            if error == nil {
                /* Handle successful login. */
                DispatchQueue.main.async(execute:{
                    let mainViewController = self.storyboard!.instantiateViewController(withIdentifier: "MainView") as! MainViewController
                    let appDelegate = UIApplication.shared.delegate as! AppDelegate
                    appDelegate.window?.rootViewController = mainViewController
                    appDelegate.window?.makeKeyAndVisible()
                })
            }
            print("Login with signin provider result = \(result), error = \(error)")
        }
    }

}

---> SignInViewControllerExtensions.swift

import Foundation
import AWSCognitoIdentityProvider
import AWSMobileHubHelper

// Extension containing methods which call different operations on Cognito User Pools (Sign In, Sign Up, Forgot Password)
extension SignInViewController {

    func handleCustomSignIn() {
        // set the interactive auth delegate to self, since this view controller handles the login process for user pools
        AWSCognitoUserPoolsSignInProvider.sharedInstance().setInteractiveAuthDelegate(self)
        self.handleLoginWithSignInProvider(signInProvider: AWSCognitoUserPoolsSignInProvider.sharedInstance())
    }

    func handleUserPoolSignUp () {
        let storyboard = UIStoryboard(name: "UserPools", bundle: nil)
        let viewController = storyboard.instantiateViewController(withIdentifier: "SignUp")
            self.present(viewController, animated:true, completion:nil);
    }

    func handleUserPoolForgotPassword () {
        let storyboard = UIStoryboard(name: "UserPools", bundle: nil)
        let viewController = storyboard.instantiateViewController(withIdentifier: "ForgotPassword")
            self.present(viewController, animated:true, completion:nil);
    }
}

// Extension to adopt the `AWSCognitoIdentityInteractiveAuthenticationDelegate` protocol
extension SignInViewController: AWSCognitoIdentityInteractiveAuthenticationDelegate {

    // this function handles the UI setup for initial login screen, in our case, since we are already on the login screen, we just return the View Controller instance
    func startPasswordAuthentication() -> AWSCognitoIdentityPasswordAuthentication {
        return self as AWSCognitoIdentityPasswordAuthentication
    }

    // prepare and setup the ViewController that manages the Multi-Factor Authentication
    func startMultiFactorAuthentication() -> AWSCognitoIdentityMultiFactorAuthentication {
        let storyboard = UIStoryboard(name: "UserPools", bundle: nil)
        let viewController = storyboard.instantiateViewController(withIdentifier: "MFA")
        DispatchQueue.main.async(execute: {
            self.present(viewController, animated:true, completion:nil);
        })
        return viewController as! AWSCognitoIdentityMultiFactorAuthentication
    }
}

// Extension to adopt the `AWSCognitoIdentityPasswordAuthentication` protocol
extension SignInViewController: AWSCognitoIdentityPasswordAuthentication {

    func getDetails(_ authenticationInput: AWSCognitoIdentityPasswordAuthenticationInput,
            passwordAuthenticationCompletionSource: AWSTaskCompletionSource<AWSCognitoIdentityPasswordAuthenticationDetails>){
        self.passwordAuthenticationCompletion = passwordAuthenticationCompletionSource
    }

    func didCompleteStepWithError(_ error: Error?){
        if let error = error {
            let errorString = (error as NSError).userInfo
            DispatchQueue.main.async(execute: {
            UIAlertView(title: errorString["__type"] as? String,
                        message: errorString["message"] as? String,
                        delegate: nil,
                        cancelButtonTitle: "Ok").show()
            })
        }

    }
}

// Extension to adopt the `AWSCognitoUserPoolsSignInHandler` protocol
extension SignInViewController: AWSCognitoUserPoolsSignInHandler {
    func handleUserPoolSignInFlowStart() {
        // check if both username and password fields are provided
        guard let username = self.usernameField.text, !username.isEmpty,
            let password = self.passwordField.text, !password.isEmpty else {
                DispatchQueue.main.async(execute: {
                    UIAlertView(title: "Missing UserName / Password",
                        message: "Please enter a valid user name / password.",
                        delegate: nil,
                        cancelButtonTitle: "Ok").show()
                })
                return
        }
        // set the task completion result as an object of AWSCognitoIdentityPasswordAuthenticationDetails with username and password that the app user provides
        self.passwordAuthenticationCompletion?.set(result: AWSCognitoIdentityPasswordAuthenticationDetails(username: username, password: password))
    }
}

--> AppDelegate.swift

//  AppDelegate.swift
//  HDPTestV2
//
//  Created by Gael Wamba Musikingala on 2017/02/18.
//  Copyright © 2017 Gael Wamba Musikingala. All rights reserved.
//

import UIKit
import AWSMobileHubHelper

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?


    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        return AWSMobileClient.sharedInstance.didFinishLaunching(application: application, withOptions: launchOptions as [NSObject : AnyObject]?)
    }

    func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
        return AWSMobileClient.sharedInstance.withApplication(application: application, withURL: url as NSURL, withSourceApplication: sourceApplication, withAnnotation: annotation as AnyObject)
    }

    func applicationWillResignActive(_ application: UIApplication) {
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
        // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
    }

    func applicationDidEnterBackground(_ application: UIApplication) {
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    }

    func applicationWillEnterForeground(_ application: UIApplication) {
        // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
         AWSMobileClient.sharedInstance.applicationDidBecomeActive(application: application)
    }

    func applicationWillTerminate(_ application: UIApplication) {
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    }


}

最佳答案

DispatchQueue.main.async(execute:{
                let mainViewController = self.storyboard!.instantiateViewController(withIdentifier: "MainView") as! MainViewController
                let appDelegate = UIApplication.shared.delegate as! AppDelegate
                appDelegate.window?.rootViewController = mainViewController
                appDelegate.window?.makeKeyAndVisible()
            })

评论这一行一段时间并在此处打印一些内容并检查您是否到达那里?

关于swift - 使用 AWS 登录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42330918/

相关文章:

ios - RealmPlugin (Swift) v0.92.2 导致 Shell 脚本调用错误

uitableview - 上下滚动时如何显示/隐藏 UITableView 标题?

ios - 如何停止跳转到下一个 View Controller ? ( swift )

swift - 获取位于 Assets.xcassets 中的数据集中文件的路径

ios - Swift - 无法从 Firebase 数据库中检索数据

objective-c - 如何使用 Objective C 检测击键?

ios - 在 Swift 中检查获取的对象是图像还是视频

ios - xcode 中@IB* 的完整列表及其用例

ios - Alamofire 4.4.0 : Extra Argument 'Method' in Call: Do not know What is Throwing Error

ios - 无法使用委托(delegate)协议(protocol)设置标签中的值