AWS Lambda: Execute Code On Demand

On this page:

Amazon Lambda

The AWS Lambda service makes it easy to create scalable, secure, and highly available backends for your mobile apps without the need to provision or manage infrastructure.

You can create secure logical functions in the cloud that can be called directly from your iOS app. Your AWS Lambda code, written in C#, Node.js, Python, or Java, can implement standalone logic, extend your app to a range of AWS services, and/or connect to services and applications external to AWS.

The availability and cost of a AWS Lambda function automatically scales to amount of traffic it receives. Functions can also be accessed from an iOS app through Amazon API Gateway, giving features like global provisioning, enterprise grade monitoring, throttling and control of access.

Setup#

This section provides a step-by-step guide for getting started with AWS Lambda using the AWS Mobile SDK for iOS.

  1. Install the SDK

    Add the AWS SDK for iOS to your project and import the APIs you need, by following the steps described in Set Up the SDK for iOS.

  2. Configure Credentials

    To use Amazon Cognito to create AWS identities and credentials that give your users access to your app's AWS resources, follow the steps described at Amazon Cognito for iOS.

  3. Create and Configure a Lamda Function

    1. Sign in to the AWS Lambda console.

    2. Choose Create a Lamda function.

    3. Choose the Blank Function template.

      Note that dozens of function templates that connect to other AWS services are available.

    4. Choose Next.

      Note that the console allows you to configure triggers for a function from other AWS services, these won't be used in this walkthrough.

    5. Type a Name and select Node.js as the Runtime language.

    6. Under Lambda function handler and role, select Create new role from template(s). Type a Role name. Select the Policy template named Simple Microservice permissions.

    7. Choose Next.

    8. Choose Create function.

Invoking an AWS Lambda Function#

The SDK enables you to call AWS Lambda functions from your iOS mobile apps, using the AWSLambdaInvoker class. When invoked from this SDK, AWS Lambda functions receive data about the device and the end user identity through client and identity context objects. To learn more about using these contexts to create rich, and personalized app experiences, see Client Context and Identity Context.

Import AWS Lambda API#

To use the lambdainvoker API, use the following import statement:

Swift
import AWSLambda
Objective C
#import <AWSLambda/AWSLambda.h>

Call lambdaInvoker#

AWSLambdaInvoker provides a high-level abstraction for AWS Lambda. When invokeFunction JSONObject is invoked, the JSON object is serialized into JSON data and sent to the AWS Lambda service. AWS Lambda returns a JSON encoded response that is deserialized into a JSON object.

A valid JSON object must have the following properties:

  • All objects are instances of string, number, array, dictionary or null objects.
  • All dictionary keys are instances of string objects.
  • Numbers are not NaN or infinity.

The following is an example of valid request.

Swift
let lambdaInvoker = AWSLambdaInvoker.default()
let jsonObject: [String: Any] = ["key1" : "value1",
                         "key2" : 2 ,
                         "key3" : [1, 2],
                         "isError" : false]

lambdaInvoker.invokeFunction("myFunction", jsonObject: jsonObject)
    .continueWith(block: {(task):AWSTask<AnyObject>) -> Any? in
    if( let error = task.error != nil) {as? NSError {
        print(task.("Error: \(error!))")
        return nil
    }

    // Handle response in task.result
    return nil
})
Objective C
AWSLambdaInvoker *lambdaInvoker = [AWSLambdaInvoker defaultLambdaInvoker];

[[lambdaInvoker invokeFunction:@"myFunction"
            JSONObject:@{@"key1" : @"value1",
                         @"key2" : @2,
                         @"key3" : [NSNull null],
                         @"key4" : @[@1, @"2"],
                         @"isError" : @NO}] continueWithBlock:^id(AWSTask *task) {
    // Handle response
    return nil;
}];

Using function returns#

On successful execution, task.result contains a JSON object. For instance, if myFunctions returns a dictionary, you can cast the result to a dictionary object as follows.

Swift
if let JSONDictionary = task.result as? NSDictionary {
    print("Result: \(JSONDictionary)")
    print("resultKey: \(JSONDictionary["resultKey"])")
}
Objective C
if (task.result) {
    NSLog(@"Result: %@", task.result);
    NSDictionary *JSONObject = task.result;
    NSLog(@"result: %@", JSONObject[@"resultKey"]);
}

Handling service execution errors#

On failed AWS Lambda service execution, task.error may contain a NSError with AWSLambdaErrorDomain domain and the following error code.

  • AWSLambdaErrorUnknown
  • AWSLambdaErrorService
  • AWSLambdaErrorResourceNotFound
  • AWSLambdaErrorInvalidParameterValue

On failed function execution, task.error may contain a NSError with AWSLambdaInvokerErrorDomain domain and the following error code:

  • AWSLambdaInvokerErrorTypeUnknown
  • AWSLambdaInvokerErrorTypeFunctionError

When AWSLambdaInvokerErrorTypeFunctionError error code is returned, error.userInfo may contain a function error from your AWS Lambda function with AWSLambdaInvokerFunctionErrorKey key.

The following code shows error handling.

Swift
if let error = task.error as? NSError {
    if error.domain == AWSLambdaInvokerErrorDomain && AWSLambdaInvokerErrorType.functionError == AWSLambdaInvokerErrorType(rawValue: error.code) {
        print("Function error: \(error.userInfo[AWSLambdaInvokerFunctionErrorKey])")
    } else {
        print("Error: \(error)")
    }
    return nil
}
Objective C
if (task.error) {
    NSLog(@"Error: %@", task.error);
    if ([task.error.domain isEqualToString:AWSLambdaInvokerErrorDomain]
        && task.error.code == AWSLambdaInvokerErrorTypeFunctionError) {
        NSLog(@"Function error: %@", task.error.userInfo[AWSLambdaInvokerFunctionErrorKey]);
    }
}

Comprehensive example#

The following code shows invoking an AWS Lambda call and handling returns and errors all together.

Swift
let lambdaInvoker = AWSLambdaInvoker.default()

let jsonObject: [String: Any] = ["key1" : "value1",
                       "key2" : 2,
                       "key3" : [1, 2],
                       "isError" : false]

lambdaInvoker.invokeFunction("myFunction", jsonObject: jsonObject).continueWith(block: {(task:AWSTask<AnyObject>) -> Any? in
    if let error = task.error as? NSError {
        if error.domain == AWSLambdaInvokerErrorDomain && AWSLambdaInvokerErrorType.functionError == AWSLambdaInvokerErrorType(rawValue: error.code) {
            print("Function error: \(error.userInfo[AWSLambdaInvokerFunctionErrorKey])")
        } else {
            print("Error: \(error)")
        }
        return nil
    }

    // Handle response in task.result
    if let JSONDictionary = task.result as? NSDictionary {
        print("Result: \(JSONDictionary)")
        print("resultKey: \(JSONDictionary["resultKey"])")
    }
    return nil
})
Objective C
AWSLambdaInvoker *lambdaInvoker = [AWSLambdaInvoker defaultLambdaInvoker];

[[lambdaInvoker invokeFunction:@"myFunction"
            JSONObject:@{@"key1" : @"value1",
                         @"key2" : @2,
                         @"key3" : [NSNull null],
                         @"key4" : @[@1, @"2"],
                         @"isError" : @NO}] continueWithBlock:^id(AWSTask *task) {
    if (task.error) {
        NSLog(@"Error: %@", task.error);
        if ([task.error.domain isEqualToString:AWSLambdaInvokerErrorDomain]
            && task.error.code == AWSLambdaInvokerErrorTypeFunctionError) {
            NSLog(@"Function error: %@", task.error.userInfo[AWSLambdaInvokerFunctionErrorKey]);
        }
    }
    if (task.result) {
        NSLog(@"Result: %@", task.result);
        NSDictionary *JSONObject = task.result;
        NSLog(@"result: %@", JSONObject[@"resultKey"]);
    }
    return nil;
}];

Client Context#

Calls to AWS Lambda using this SDK provide your functions with data about the calling device and app using the ClientContext class.

You can access the client context in your lambda function as follows.

JavaScript
exports.handler = function(event, context) {
    console.log("installation_id = " + context.clientContext.client.installation_id);
    console.log("app_version_code = " + context.clientContext.client.app_version_code);
    console.log("app_version_name = " + context.clientContext.client.app_version_name);
    console.log("app_package_name = " + context.clientContext.client.app_package_name);
    console.log("app_title = " + context.clientContext.client.app_title);
    console.log("platform_version = " + context.clientContext.env.platform_version);
    console.log("platform = " + context.clientContext.env.platform);
    console.log("make = " + context.clientContext.env.make);
    console.log("model = " + context.clientContext.env.model);
    console.log("locale = " + context.clientContext.env.locale);

    context.succeed("Your platform is " + context.clientContext.env.platform;
}

ClientContext has the following fields:

client.installation_id
Auto-generated UUID that is created the first time the app is launched. This is stored in the keychain on the device. In case the keychain is wiped a new installation ID will be generated.
client.app_version_code
CFBundleShortVersionString
client.app_version_name
CFBundleVersion
client.app_package_name
CFBundleIdentifier
client.app_title
CFBundleDisplayName
env.platform_version
systemVersion
env.platform
systemName
env.make
Hardcoded as "apple"
env.model
Model of the device
env.locale
localeIdentifier from autoupdatingCurrentLocale

Identity Context#

The IdentityContext class of the SDK passes Amazon Cognito credentials making the AWS identity of the end user available to your function. You can access the Identity ID as follows.

JavaScript
exports.handler = function(event, context) {
    console.log("clientID = " + context.identity);

    context.succeed("Your client ID is " + context.identity);
}

For more about Amazon Cognito in the AWS Mobile SDK for iOS, see Amazon Cognito for iOS.