Swift AWS Cognito API`AWSMobileClient.default().addUserStateListener`仅在用户身份验证状态更改时激发

Swift AWS Cognito API`AWSMobileClient.default().addUserStateListener`仅在用户身份验证状态更改时激发,swift,amazon-web-services,amazon-cognito,Swift,Amazon Web Services,Amazon Cognito,我将xcode 11与swift 4配合使用。我在这里和AppDelegate.swift中遵循aws cognito的文档,我有: func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // initialize AWS amplify

我将xcode 11与swift 4配合使用。我在这里和
AppDelegate.swift
中遵循aws cognito的文档,我有:

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

    // initialize AWS amplify
    let apiPlugin = AWSAPIPlugin(modelRegistration: AmplifyModels())

    do {
        try Amplify.add(plugin: apiPlugin)
        try Amplify.configure()
    } catch {
        // Navigate to page showing bad network connection
        print("Failed to configure Amplify \(error)")
    }

    AWSMobileClient.default().addUserStateListener(self) { (userState, info) in
        switch (userState) {
            case .signedOut:
                // user clicked signout button and signedout
                print("AppDelegate.application state: user signed out")
            case .signedIn:
                print("AppDelegate.application state: user signed in: \(userState)")
            case .signedOutUserPoolsTokenInvalid:
                print("need to login again.")
            default:
                print("unsupported")
        }
    }

    return true
}
AWSMobileClient.default().addUserStateListener
仅在用户首次登录或注册时激发。如果用户已通过身份验证。然后,
addUserStateListener
不会启动。这是一个问题,因为我需要获取用户的帐户令牌才能访问他/她的信息。我是否使用了错误的CognitoAPI?或者
addUserStateListener
在错误的函数中使用

如果我使用另一个Cognoto API

AWSMobileClient.default().initialize { (userState, error) ... }

它每次都会激发,但我无法从此api访问用户令牌

您可以通过使用AWSAPSync api访问用户令牌,并在应用程序委托中使用此方法,或者通过扩展appDelegate,或者像我一样使用您自己的自定义类

class CognitoPoolProvider : AWSCognitoUserPoolsAuthProviderAsync {


    func getLatestAuthToken(_ callback: @escaping (String?, Error?) -> Void) {

        AWSMobileClient.default().getTokens { (token, error) in

            if let error = error {
                callback(nil,error)
            }
            callback(token?.accessToken?.tokenString, error)
        }
    }
}
所以,在我的appDelegate中,我做了类似的事情

var appSyncClientBridge : AWSAppSyncClient?

    /// Sets the configuration settings for application's AWSAppSync Client.
    func appSyncSetup()throws -> AWSAppSyncClientConfiguration{

        let cache = try AWSAppSyncCacheConfiguration()
        let serviceConfig = try AWSAppSyncServiceConfig()

        let appSyncConfiguration = try AWSAppSyncClientConfiguration(appSyncServiceConfig: serviceConfig,
                                                                     userPoolsAuthProvider: CognitoPoolProvider(),
                                                                     cacheConfiguration: cache)


        return appSyncConfiguration
    }

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

        do {
            let configFile = try appSyncSetup()
            appSyncClientBridge = try AWSAppSyncClient(appSyncConfig: configFile)
        }
        catch(let error){
            print(error.localizedDescription)
        }

        return true
    }
更新:

如果用户已登录。您可以创建这样的方法

func getTokens(){
        let getPool = CognitoPoolProvider()

        func getToken(completion: @escaping (Result<String,Error>)->Void){
            getPool.getLatestAuthToken { (token, error) in
                if let error = error {
                    completion(.failure(error))
                }
                if let token = token {
                    completion(.success(token))
                }
            }
        }

        getToken { (result) in
            print(("This is the token — \(String(describing: try? result.get() as String))"))
        }
    }
func getTokens(){
让getPool=CognitoPoolProvider()
func getToken(完成:@escaping(Result)->Void){
getPool.GetLateStatuthToken{(标记,错误)位于
如果let error=error{
完成(.failure(error))
}
如果let token=token{
完成(.success(令牌))
}
}
}
得到{(结果)
打印(((“这是标记-\(字符串(将:try?result.get()描述为字符串)))
}
}

如果您将其放置在viewDidLoad中,您将能够访问用户令牌。在本例中,它只是打印出来的,但我认为从这里您可以根据需要使用它。

不,这是CognitoPoolProvider所做的。你可以用任何一种方法。我只是想保持关注点的分离,所以我把它一分为二。您可以扩展AppDelegate并添加我在CognitoPoolProvider中使用的方法,它对您应该具有相同的结果。pod'AWSUserPoolsSignIn',“~>2.13.0”导入AWsAspSync导入AWSMobileClient这是我的pod文件->pod'awsAspSync',“~>3.1.0”pod'AWSMobileClient',“~>2.13.0”pod'AWSAuthUI',“~>2.13.0”pod“AWSUserPoolsSignIn”、“~>2.13.0”据我所知,它只在数据库实际需要时才会调用它,就像在写入数据库时一样。我有一点没用过这个,但让我做一些研究。嘿,我要更新我的回答。我找到了一个解决办法我想。。。