I've followed two API Gateway tutorials for two different REST APIs that call AWS Lambda. Here's the link to the Calc API, which is the subject of this post.
In each case, test invocations via the AWS Console work perfectly. But when I generate the iOS Swift SDK from the deployed stage 'SDK Generation' tab, unzip and import into my Xcode project, the defaultClient member is missing in Client.swift.
The README.md file in each case says it should be there:
# Use the SDK in your project
1. Grab the `defaultClient` from your code
let client = Client.defaultClient()
1. You can now call your method using the client SDK
But there is NO defaultClient in Client.swift.
UPDATE There is no defaultClient, but there is a default (with backticks around it because default is a reserved word in Swift). So I substituted that in the REST API invocation... and it worked! I have no idea why... I don't know what the backticks mean in Swift... and if someone can explain this to me, great. But I verified via API Gateway that the API was called successfully; and I verified via Cloudwatch that the Lambda function returns the correct value.
Here is my code that invokes the 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
}
}
However, I don't understand the data structure returned at the Client yet. This is what I get:
You clicked invoke api...
The result is... {
}
Here are the full contents of the generated Client.swift file (with some comments removed). I'm thinking it's possible that the README is no longer in sync with the SDK generation.
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://.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 {
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
}
/*
@param body
return type: Empty
*/
public func calcPost(body: SVTInput) -> AWSTask {
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
}
/*
@param operand2
@param _operator
@param operand1
return type: SVTResult
*/
public func calcOperand1Operand2OperatorGet(operand2: String, _operator: String, operand1: String) -> AWSTask {
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
}
Any help greatly appreciated!
JavaScript questions and answers, JavaScript questions pdf, JavaScript question bank, JavaScript questions and answers pdf, mcq on JavaScript pdf, JavaScript questions and solutions, JavaScript mcq Test , Interview JavaScript questions, JavaScript Questions for Interview, JavaScript MCQ (Multiple Choice Questions)