В iOS SDK, сгенерированном AWS API Gateway, отсутствует обязательный элемент defaultClient - PullRequest
0 голосов
/ 25 марта 2019

Я следовал двум учебникам API Gateway для двух разных REST API, которые вызывают AWS Lambda. Вот ссылка на Calc API, которая является темой этого поста.

В каждом случае тестовые вызовы через Консоль AWS работают отлично. Но когда я генерирую iOS Swift SDK из развернутой вкладки этапа «Создание SDK», распаковываю и импортирую в мой проект Xcode, элемент defaultClient отсутствует в <API-Name>Client.swift.

Файл README.md в каждом случае говорит, что он должен быть там:

# Use the SDK in your project

1. Grab the `defaultClient` from your code

        let client = <API-Name>Client.defaultClient()

1. You can now call your method using the client SDK

Но в <API-Name>Client.swift.

НЕТ defaultClient.

UPDATE defaultClient нет, но есть default (с обратными галочками вокруг него, потому что default - зарезервированное слово в Swift). Поэтому я заменил это в вызове REST API ... и это сработало! Я понятия не имею, почему ... Я не знаю, что означают эти галочки в Свифте ... и если кто-то может мне это объяснить, прекрасно. Но я проверил через API Gateway, что API был вызван успешно; и я проверил через Cloudwatch, что функция Lambda возвращает правильное значение.

Вот мой код, который вызывает API:

@IBAction func userInvokeApi(_ sender: UIButton) {
    print("You clicked invoke api...")
    let client = SVTLambdaGateClient.default()
    client.calcGet(operand2: "3", _operator: "+", operand1: "5").continueWith{ (task: AWSTask?) -> AnyObject? in
        if let error = task?.error {
            print("Error occurred: \(error)")
            return nil
        }

        if let result = task?.result {
            // Do something with result
            print("The result is... \(result)")
        }

        return nil
    }
}

Однако я еще не понимаю структуру данных, возвращаемых на Клиента. Вот что я получаю:

You clicked invoke api...
The result is... <AmplifyRestApiTest.Empty: 0x600002020770> {
}

Вот полное содержимое сгенерированного файла <API-Name>Client.swift (некоторые комментарии удалены). Я думаю, что возможно, что README больше не синхронизируется с генерацией SDK.

import AWSCore
import AWSAPIGateway

public class SVTLambdaGateClient: AWSAPIGatewayClient {

    static let AWSInfoClientKey = "SVTLambdaGateClient"

    private static let _serviceClients = AWSSynchronizedMutableDictionary()
    private static let _defaultClient:SVTLambdaGateClient = {
        var serviceConfiguration: AWSServiceConfiguration? = nil
        let serviceInfo = AWSInfo.default().defaultServiceInfo(AWSInfoClientKey)
        if let serviceInfo = serviceInfo {
            serviceConfiguration = AWSServiceConfiguration(region: serviceInfo.region, credentialsProvider: serviceInfo.cognitoCredentialsProvider)
        } else if (AWSServiceManager.default().defaultServiceConfiguration != nil) {
            serviceConfiguration = AWSServiceManager.default().defaultServiceConfiguration
        } else {
            serviceConfiguration = AWSServiceConfiguration(region: .Unknown, credentialsProvider: nil)
        }

        return SVTLambdaGateClient(configuration: serviceConfiguration!)
    }()

    /**
     Returns the singleton service client. If the singleton object does not exist, the SDK instantiates the default service client with `defaultServiceConfiguration` from `AWSServiceManager.defaultServiceManager()`. The reference to this object is maintained by the SDK, and you do not need to retain it manually.
     @return The default service client.
     */ 

    public class func `default`() -> SVTLambdaGateClient{
        return _defaultClient
    }

    /**
     Creates a service client with the given service configuration and registers it for the key.
     @param configuration A service configuration object.
     @param key           A string to identify the service client.
     */

    public class func registerClient(withConfiguration configuration: AWSServiceConfiguration, forKey key: String){
        _serviceClients.setObject(SVTLambdaGateClient(configuration: configuration), forKey: key  as NSString);
    }

    /**
     Retrieves the service client associated with the key. You need to call `registerClient(withConfiguration:configuration, forKey:)` before invoking this method or alternatively, set the configuration in your application's `info.plist` file. If `registerClientWithConfiguration(configuration, forKey:)` has not been called in advance or if a configuration is not present in the `info.plist` file of the app, this method returns `nil`.
     Then call the following to get the service client:

        let serviceClient = SVTLambdaGateClient.client(forKey: "USWest2SVTLambdaGateClient")

     @param key A string to identify the service client.
     @return An instance of the service client.
     */
    public class func client(forKey key: String) -> SVTLambdaGateClient {
        objc_sync_enter(self)
        if let client: SVTLambdaGateClient = _serviceClients.object(forKey: key) as? SVTLambdaGateClient {
            objc_sync_exit(self)
            return client
        }

        let serviceInfo = AWSInfo.default().defaultServiceInfo(AWSInfoClientKey)
        if let serviceInfo = serviceInfo {
            let serviceConfiguration = AWSServiceConfiguration(region: serviceInfo.region, credentialsProvider: serviceInfo.cognitoCredentialsProvider)
            SVTLambdaGateClient.registerClient(withConfiguration: serviceConfiguration!, forKey: key)
        }
        objc_sync_exit(self)
        return _serviceClients.object(forKey: key) as! SVTLambdaGateClient;
    }

    /**
     Removes the service client associated with the key and release it.

     @param key A string to identify the service client.
     */
    public class func removeClient(forKey key: String) -> Void{
        _serviceClients.remove(key)
    }

    init(configuration: AWSServiceConfiguration) {
        super.init()

        self.configuration = configuration.copy() as! AWSServiceConfiguration
        var URLString: String = "https://<my-api-id>.execute-api.us-east-2.amazonaws.com/test"
        if URLString.hasSuffix("/") {
            URLString = URLString.substring(to: URLString.index(before: URLString.endIndex))
        }
        self.configuration.endpoint = AWSEndpoint(region: configuration.regionType, service: .APIGateway, url: URL(string: URLString))
        let signer: AWSSignatureV4Signer = AWSSignatureV4Signer(credentialsProvider: configuration.credentialsProvider, endpoint: self.configuration.endpoint)
        if let endpoint = self.configuration.endpoint {
            self.configuration.baseURL = endpoint.url
        }
        self.configuration.requestInterceptors = [AWSNetworkingRequestInterceptor(), signer]
    }

    /*


     @param operand2 
     @param _operator 
     @param operand1 

     return type: Empty
     */
    public func calcGet(operand2: String, _operator: String, operand1: String) -> AWSTask<Empty> {
        let headerParameters = [
                   "Content-Type": "application/json",
                   "Accept": "application/json",

                ]

        var queryParameters:[String:Any] = [:]
        queryParameters["operand2"] = operand2
        queryParameters["operator"] = _operator
        queryParameters["operand1"] = operand1

        let pathParameters:[String:Any] = [:]

        return self.invokeHTTPRequest("GET", urlString: "/calc", pathParameters: pathParameters, queryParameters: queryParameters, headerParameters: headerParameters, body: nil, responseClass: Empty.self) as! AWSTask<Empty>
    }


    /*


     @param body 

     return type: Empty
     */
    public func calcPost(body: SVTInput) -> AWSTask<Empty> {
        let headerParameters = [
                   "Content-Type": "application/json",
                   "Accept": "application/json",

                ]

        let queryParameters:[String:Any] = [:]

        let pathParameters:[String:Any] = [:]

        return self.invokeHTTPRequest("POST", urlString: "/calc", pathParameters: pathParameters, queryParameters: queryParameters, headerParameters: headerParameters, body: body, responseClass: Empty.self) as! AWSTask<Empty>
    }


    /*


     @param operand2 
     @param _operator 
     @param operand1 

     return type: SVTResult
     */
    public func calcOperand1Operand2OperatorGet(operand2: String, _operator: String, operand1: String) -> AWSTask<SVTResult> {
        let headerParameters = [
                   "Content-Type": "application/json",
                   "Accept": "application/json",

                ]

        let queryParameters:[String:Any] = [:]

        var pathParameters:[String:Any] = [:]
        pathParameters["operand2"] = operand2
        pathParameters["operator"] = _operator
        pathParameters["operand1"] = operand1

        return self.invokeHTTPRequest("GET", urlString: "/calc/{operand1}/{operand2}/{operator}", pathParameters: pathParameters, queryParameters: queryParameters, headerParameters: headerParameters, body: nil, responseClass: SVTResult.self) as! AWSTask<SVTResult>
    }

Любая помощь с благодарностью!

1 Ответ

0 голосов
/ 05 апреля 2019

Команда Amplify (которая поддерживает и разрабатывает AWS iOS SDK) проверила, что документация неверна . Он должен ссылаться на default(), а не defaultClient().

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