我无法解雇该代表,也不确定我缺少什么

时间:2019-08-03 19:17:08

标签: ios swift amazon-web-services aws-sdk amazon-cognito

我有一个登录屏幕,可以使用SDK通过Amazon Cognito进行身份验证。完成后,应该调用一个委托(或iOS Swift中的扩展)。应该调用didCompleteWithError或getDetails方法。

我已经尝试了一些示例,但我没有运气(https://github.com/awslabs/aws-sdk-ios-samples/tree/master/CognitoYourUserPools-Sample/Swift)。有任何想法吗?仅在登录屏幕和下面的AppDelegate.swift时,请参阅我的代码。我在做什么错了?

//  LoginViewController.swift


import UIKit
import AWSCognitoIdentityProvider
import AWSCognitoAuth
import AWSMobileClient
import AWSUserPoolsSignIn
import AWSAuthUI

class LoginViewController: BaseViewController {

    @IBOutlet var password: UITextField!
    @IBOutlet var email: UITextField!
    var pool: AWSCognitoIdentityUserPool?
    var passwordAuthenticationCompletion: AWSTaskCompletionSource<AWSCognitoIdentityPasswordAuthenticationDetails>?
    var usernameText: String?


    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.password.text = nil
        self.email.text = usernameText
        self.navigationController?.setNavigationBarHidden(true, animated: false)
    }

    @IBAction func login_Tap(_ sender: Any) {
        if (self.email.text != nil && self.password.text != nil) {
            let authDetails = AWSCognitoIdentityPasswordAuthenticationDetails(username: self.email.text!, password: self.password.text! )
            self.passwordAuthenticationCompletion?.set(result: authDetails)
        } else {
            let alertController = UIAlertController(title: "Missing information",
                                                    message: "Please enter a valid user name and password",
                                                    preferredStyle: .alert)
            let retryAction = UIAlertAction(title: "Retry", style: .default, handler: nil)
            alertController.addAction(retryAction)
        }
    }

}

extension LoginViewController: AWSCognitoIdentityPasswordAuthentication {

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

    public func didCompleteStepWithError(_ error: Error?) {
        print(error)
        DispatchQueue.main.async {
            if let error = error as NSError? {
                let alertController = UIAlertController(title: error.userInfo["__type"] as? String,
                                                        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.email.text = nil
                self.dismiss(animated: true, completion: nil)
            }
        }
    }
}

AppDelegate.swift我有这个

//
//  AppDelegate.swift


import UIKit
import AWSCognitoAuth
import AWSSNS
import AWSCognitoIdentityProvider
import UserNotifications
import ESTabBarController_swift
import AWSMobileClient

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

    var window: UIWindow?
var navigationController: UINavigationController?
    var storyboard: UIStoryboard?
    var loginViewController: LoginViewController?


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


        // setup logging
        AWSDDLog.sharedInstance.logLevel = .verbose


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

        // create pool configuration
        let poolConfiguration = AWSCognitoIdentityUserPoolConfiguration(clientId: Constants.APIKeys.AWSClientID,
                                                                        clientSecret: Constants.APIKeys.AWSSecret,
                                                                        poolId: Constants.APIKeys.AWSPoolID)

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

        // fetch the user pool client we initialized in above step
        let pool = AWSCognitoIdentityUserPool(forKey: "UserPool")



        self.window = UIWindow(frame: UIScreen.main.bounds)

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

                pool.delegate = self
                AppController.sharedInstance.launchInWindow(aWindow: self.window)
        return true
    }


    //MARK: Push Notification

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {

        /// Attach the device token to the user defaults
        var token = ""
        for i in 0..<deviceToken.count {
            token = token + String(format: "%02.2hhx", arguments: [deviceToken[i]])
        }

        print(token)
        UserDefaults.standard.set(token, forKey: "deviceTokenForSNS")

        /// Create a platform endpoint. In this case, the endpoint is a
        /// device endpoint ARN
        let sns = AWSSNS.default()
        let request = AWSSNSCreatePlatformEndpointInput()
        request?.token = token
        request?.platformApplicationArn = Constants.APIKeys.AWSSSNSARN

        sns.createPlatformEndpoint(request!).continueWith(executor: AWSExecutor.mainThread(), block: { (task: AWSTask!) -> AnyObject? in
            if task.error != nil {
                print("Error: \(String(describing: task.error))")
            } else {
                let createEndpointResponse = task.result! as AWSSNSCreateEndpointResponse
                if let endpointArnForSNS = createEndpointResponse.endpointArn {
                    print("endpointArn: \(endpointArnForSNS)")
                    Settings.setPushArn(endpointArnForSNS)

                    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "RegisteredForPush"), object: nil)

                }
            }

            return nil
        })
    }

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {

        let visible = window?.visibleViewController()

        if let data = userInfo["aps"] as? [AnyHashable: Any] {
            if let route = data["route"] as? String {
                switch route {
                case "matchRequested":
                    var projectId = ""
                    if let project = data["projectId"] as? String {
                        projectId = project
                    }
                    var matchId = ""
                    if let match = data["matchId"] as? String {
                        matchId = match
                    }
                    let projectMatches = MatchRequestedViewController(withNotificationPayload: projectId, matchId: matchId)
                    visible?.navigationController?.pushViewController(projectMatches, animated: true)

                case "projectDetails":
                    var projectId = ""
                    if let project = data["projectId"] as? String {
                        projectId = project
                    }
                    let projectMatches = ProjectDetailsViewController(withProject: TERMyProject(), orProjectId: projectId)
                    visible?.navigationController?.pushViewController(projectMatches, animated: true)
                case "matched":
                    var projectId = ""
                    if let project = data["projectId"] as? String {
                        projectId = project
                    }
                    var matchId = ""
                    if let match = data["matchId"] as? String {
                        matchId = match
                    }
                    var originProject: TERMyProject = TERMyProject()
                    var matchedProject: TERMatchedProject = TERMatchedProject()

                    AppController.sharedInstance.AWSClient?.projectsGet(id:projectId).continueWith(block: { (task: AWSTask) -> Any? in

                        if let error = task.error {
                            print("Error: \(error)")

                        } else if let result = task.result {
                            if result is NSDictionary {
                                DispatchQueue.main.async {
                                    let array = [result]
                                    let parsedProject: [TERMyProject] = TERMyProject.parseFromAPI(array:array as! [NSDictionary])
                                    for project in parsedProject {
                                        originProject = project
                                    }
                                    //                        self.initialSetup()
                                }
                                AppController.sharedInstance.AWSClient?.projectsGet(id:matchId).continueWith(block: { (task: AWSTask) -> Any? in

                                    if let error = task.error {
                                        print("Error: \(error)")

                                    } else if let result = task.result {
                                        if result is NSDictionary {
                                            DispatchQueue.main.async {
                                                let array = [result]
                                                let parsedProject: [TERMatchedProject] = TERMatchedProject.parseFromAPI(array:array as! [NSDictionary])
                                                for project in parsedProject {
                                                    matchedProject = project
                                                }
                                                let projectMatches = MatchedViewController(withProject: originProject, match: matchedProject, isComplete: false)
                                                visible?.navigationController?.pushViewController(projectMatches, animated: true)
                                            }

                                        }
                                    }
                                    return nil
                                })
                            }
                        }
                        return nil
                    })



                default:
                    break
                }

            }
        }
    }

    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        print(error.localizedDescription)
    }

    // Called when a notification is delivered to a foreground app.
    @available(iOS 10.0, *)
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        print("User Info = ",notification.request.content.userInfo)
        completionHandler([.alert, .badge, .sound])
    }

    //MARK: Boiler-plate methods

    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) {

    }

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

}


extension AppDelegate: AWSCognitoIdentityInteractiveAuthenticationDelegate {

    func startPasswordAuthentication() -> AWSCognitoIdentityPasswordAuthentication {
        if (self.navigationController == nil) {

            self.navigationController = self.storyboard?.instantiateViewController(withIdentifier: "LoginViewController") as? UINavigationController
        }

        if (self.loginViewController == nil) {
            self.loginViewController = self.navigationController?.viewControllers[0] as? LoginViewController
        }

        DispatchQueue.main.async {
            self.navigationController!.popToRootViewController(animated: true)
            if (!self.navigationController!.isViewLoaded
                || self.navigationController!.view.window == nil) {
                self.window?.rootViewController?.present(self.navigationController!,
                                                         animated: true,
                                                         completion: nil)
            }

        }
        return self.loginViewController!
    }


}

// MARK:- AWSCognitoIdentityRememberDevice protocol delegate

extension AppDelegate: AWSCognitoIdentityRememberDevice {
    func didCompleteStepWithError(_ error: Error?) {

    }


    func getRememberDevice(_ rememberDeviceCompletionSource: AWSTaskCompletionSource<NSNumber>) {


    }

}
extension UIWindow {

    func visibleViewController() -> UIViewController? {
        if let rootViewController: UIViewController = self.rootViewController {
            return UIWindow.getVisibleViewControllerFrom(vc: rootViewController)
        }
        return nil
    }

    class func getVisibleViewControllerFrom(vc:UIViewController) -> UIViewController {

        switch(vc){
        case is UINavigationController:
            let navigationController = vc as! UINavigationController
            return UIWindow.getVisibleViewControllerFrom( vc: navigationController.visibleViewController!)
            break;

        case is UITabBarController:
            let tabBarController = vc as! UITabBarController
            return UIWindow.getVisibleViewControllerFrom(vc: tabBarController.selectedViewController!)
            break;

        default:
            if let presentedViewController = vc.presentedViewController {
                //print(presentedViewController)
                if let presentedViewController2 = presentedViewController.presentedViewController {
                    return UIWindow.getVisibleViewControllerFrom(vc: presentedViewController2)
                }
                else{
                    return vc;
                }
            }
            else{
                return vc;
            }
            break;
        }

    }


}

0 个答案:

没有答案