Introducing Swift-Sprinter, an open-source library for Swift with AWS Serverless

Andrea Scuderi
Sep 30 · 5 min read
The Power of Swift to AWS Lambda

Introduction

This story starts some years ago when, as an iOS developer at BJSS, I was involved in delivering an iOS mobile app for a government agency in the UK with an AWS Serverless backend. I had an exciting time learning about Lambda, S3, DynamoDB, SNS, Cognito, API Gateway, IAM, and friends. At the end my proof of concept of for an AWS Serverless backend and the mobile iOS Swift native app went to alpha, beta, and now production.

I realised that building this backend for a mobile app with Serverless is inexpensive and scalable from day one and requires very little maintenance compared to a containerised solution or virtual machines. The Serverless approach is quite effective when the backend load cannot be predicted.

The pay per use model introduced with Serverless could be useful in validating a startup idea or a small project.

Only one thing disappointed me — as an iOS developer, I would have written it in my beloved language Swift but at that time it wasn't supported by AWS. So I handed over the PoC of the backend to a developer skilled in the other language and I developed the iOS app.

So I started research in my spare time to make my dream become reality…

A month ago, I came across some half-working solutions that all had a big issue: HTTPS calls were not working.

After I while I developed a working solution with HTTPS and made an open-source framework called swift-sprinter.

With this framework it’s possible to consume AWS services from the Lambda written in Swift 5.0 and 5.1. If you’re curious of how to use swift-sprinter to get an object from an S3 bucket, read this.


Demo HTTPS API Request from Swift Lambda

To keep the things simple, in this article, I’ll show how to write an AWS Lambda to query the dog-api.

The goal is to retrieve a JSON with a list of images URL from this API by passing our favourite breed:

https://dog.ceo/api/breed/hound/afghan/images

Then retrieving a JSON like this:

{
"message": [
"https://images.dog.ceo/breeds/hound-afghan/n02088094_1003.jpg",
"https://images.dog.ceo/breeds/hound-afghan/n02088094_1007.jpg"
],
"status": "success"
}

You need:

I suggest taking a look at the README on GitHub before you continue the reading to prepare your mac with the requirements.


Development Workflow

From the command line:

git clone https://github.com/swift-sprinter/aws-lambda-swift-sprinter.gitcd aws-lambda-swift-sprinter/Examples/HTTPSRequest

Generate the Xcode project and open it with Xcode:

swift package generate-xcodeproj

Open XCode and Navigate to the file main.swift and inspect it.

The Event is correct — we want to send a URL as an input event.

struct Event: Codable {
let url: String
}

The HTTPSRequest lambda example will give a Response with url and content when the execution is complete — this is not good for our purposes:

struct Response: Codable {
let url: String
let content: String
}

We change the response to reflect the JSON we want to receive:

struct Response: Codable {
let message: [String]
let status: String
}

We now receive message with an Array of String and a status with a String.

Now to return the Response we need fix the lambda code return type with the new one:

...  let decoder = JSONDecoder()
let output = try decoder.decode(Response.self, from: data)
return output
}

The previous code encodes the data received to Response and returns it as Lambda output.

This is the final output:

Now open aws-lambda-swift-sprinter/Makefile

cd ../../ && open Makefile

Comment the following lines:

# HelloWorld Example Configuration
# SWIFT_EXECUTABLE=HelloWorld
# SWIFT_PROJECT_PATH=Examples/HelloWorld
# LAMBDA_FUNCTION_NAME=HelloWorld
# LAMBDA_HANDLER=$(SWIFT_EXECUTABLE).helloWorld

Then un-comment the line after:

# HTTPSRequest Example Configuration
SWIFT_EXECUTABLE=HTTPSRequest
SWIFT_PROJECT_PATH=Examples/HTTPSRequest
LAMBDA_FUNCTION_NAME=HTTPSRequest
LAMBDA_HANDLER=$(SWIFT_EXECUTABLE).getHttps

Save and close the file.


Lambda Building

Lambda runs on a custom version of Amazon Linux. To build Lambdayou need a Swift custom docker image.

To build the image use this command:

make docker_build

Now test the build from the command line:

make build_lambda

This will take a few minutes.

Great! The code works on Swift docker too, that means it’s ready to be deployed.


AWS Deployment

To complete this step you must have the AWS Command Line interface installed and have registered your configuration and credentials.

Now we need to build the custom runtime:

make package_layer

We have to upload the lambda layer:

make upload_lambda_layer

Under the .build folder, list a zip file called swift-lambda-runtime-5.1.zip and a file called nio-swift-lambda-runtime-5-1-arn.txt.

make create_lambda

This command will create the Lambda on AWS after rebuilding the code.

After the command complete, go to the AWS console and inspect the HTTPSRequest lambda.

Lambda Invocation

To invoke the Lambda we need to set up the event:

open Examples/HTTPSRequest/event.json

Ùpdate it with this:

{"url": "https://dog.ceo/api/breed/hound/afghan/images"}

Now run the Lambda invocation:

make invoke_lambda

Better Programming

Advice for programmers.

Thanks to Zack Shapiro

Andrea Scuderi

Written by

Senior iOS Developer and Software Engineer @ BJSS. Swift and iOS Native advocate. https://www.linkedin.com/in/andreascuderi/

Better Programming

Advice for programmers.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade