Get started with the AWS SDK for Swift
This chapter explores how to use the Swift Package Manager
Prerelease documentation
This is prerelease documentation for an SDK in preview release. It might be incomplete and is subject to change.
In addition, versions of the SDK earlier than version 1.0.0 might have flaws, and no guarantee is made about the API's stability. Changes can and will occur that break compatibility during the prerelease stage. These releases are not intended for use in production code!
Topics
Create a project using the AWS SDK for Swift
This chapter demonstrates how to create a small program that lists all the Amazon S3 buckets available on the default user account.
Goals for this project:
-
Create a project using Swift Package Manager.
-
Add the AWS SDK for Swift to the project.
-
Configure the project’s
Package.swift
file to describe the project and its dependencies. -
Write code that uses Amazon S3 to get a list of the buckets on the default AWS account, then prints them to the screen.
Before we begin, make sure to prepare your development environment as described in Set up. To make sure you're set up properly, use the following command. This makes sure that Swift is available and which version it is.
$
swift --version
On macOS, you should see output that looks like the following (with possibly different version and build numbers):
swift-driver version: 1.87.1 Apple Swift version 5.9 (swiftlang-5.9.0.128.108 clang-1500.0.40.1) Target: x86_64-apple-macosx14.0
On Linux, the output should look something like the following:
Swift version 5.9.0 (swift-5.9.0-RELEASE) Target: x86_64-unknown-linux-gnu
If Swift is not installed, or is older than version 5.9, follow the instructions in Set up the AWS SDK for Swift to install or reinstall the tools.
Get this example on GitHub
You can fork or download this example
Create the project
With the Swift tools installed, open a terminal session using your favorite terminal application (such as Terminal, iTerm, or the integrated terminal in your editor).
At the terminal prompt, go to the directory where you want to create the project. Then, enter the following series of commands to create an empty Swift project for a standard executable program.
$
mkdir ListBuckets$
cd ListBuckets$
swift package init --type executable$
mv Sources/main.swift Sources/entry.swift
This creates the directory for the examples project, moves into that
directory, and initializes that directory with the Swift Package
Manager. The result is the basic file system structure for a simple
executable program. The Swift source code file main.swift
is also renamed to entry.swift
to work around a bug in the
Swift tools that involves the use of asynchronous code in the main
function of a source file named main.swift
.
ListBuckets/ ├── Package.swift └── Sources/ └── entry.swift
Open your created project in your preferred text editor or IDE. On macOS, you can open the project in Xcode with the following:
$
xed .
As another example, you can open the project in Visual Studio Code with the following:
$
code .
Configure the package
After opening the project in your editor, open the
Package.swift
file. This is a Swift file that
defines an SPM Package
The first line of every Package.swift
file must
be a comment specifying the minimum version of the Swift toolchain
needed to build the project. This isn't only informational. The version
specified here can change the behavior of the tools for compatibility
purposes. The AWS SDK for Swift requires at least version
5.9
of the Swift
tools.
// swift-tools-version:5.9
Specify supported platforms
For projects whose target operating systems include any Apple
platform, add or update the platforms
property to include a list of the
supported Apple platforms and minimum required versions. This list
only specifies support for Apple platforms and doesn't preclude
building for other platforms.
// Let Xcode know the minimum Apple platforms supported. platforms: [ .macOS(.v11), .iOS(.v13) ],
In this excerpt, the supported Apple platforms are macOS (version 11.0 and higher) and iOS/iPadOS (version 13 and higher).
Set up dependencies
The package dependency list needs to include the AWS SDK for Swift. This tells the Swift compiler to fetch the SDK and its dependencies before attempting to build the project.
dependencies: [ // Dependencies declare other packages that this package depends on. .package( url: "https://github.com/awslabs/aws-sdk-swift", from: "1.0.0" ) ],
Configure the target
Now that the package depends on the AWS SDK for Swift, add a dependency
to the executable program's target. Indicate that it relies on Amazon S3,
which is offered by the SDK's AWSS3
product.
targets: [ // Targets are the basic building blocks of a package, defining a module or a test suite. // Targets can depend on other targets in this package and products from dependencies. .executableTarget( name: "ListBuckets-Simple", dependencies: [ .product(name: "AWSS3", package: "aws-sdk-swift") ], path: "Sources") ]
Access AWS services using Swift
The example program's Swift code is found in the
Source/entry.swift
file. This file begins by
importing the needed Swift modules, using the import
statement.
import AWSClientRuntime import AWSS3 import Foundation
-
Foundation
is the standard Apple Foundation package. -
ClientRuntime
is a module providing low-level and support features for the AWS SDK for Swift. -
AWSS3
is the SDK module that's used to access Amazon S3.
After you add the SDK for Swift to your project and import the service you want to use into your source code, you can create an instance of the client representing the service and use it to issue AWS service requests.
Create a service client object
Each AWS service is represented by a specific client class in
the AWS SDK for Swift. For example, while the Amazon DynamoDB client class is
called DynamoDBClient
, the class for Amazon Simple Storage Service is
S3Client
. To use Amazon S3 in this example, first create an
S3Client
object on which to call the SDK's Amazon S3
functions.
let configuration = try await S3Client.S3ClientConfiguration() // configuration.region = "us-east-2" // Uncomment this to set the region programmatically. let client = S3Client(config: configuration)
Issue AWS service requests
To issue a request to an AWS service, call the corresponding
function on the service's client object. Each function's inputs are
specified using a function-specific input structure as the value of
the function's input
parameter. For example, when
calling S3Client.listBuckets(input:)
, input
is
a structure of type ListBucketsInput
.
// Use "Paginated" to get all the buckets. // This lets the SDK handle the 'continuationToken' in "ListBucketsOutput". let pages = client.listBucketsPaginated( input: ListBucketsInput( maxBuckets: 10) )
Functions defined by the AWS SDK for Swift run asynchronously, so the
example uses await
to block the program's execution
until the result is available. If SDK functions encounter errors,
they throw them so your code can handle them using a
do
-catch
statement or by propagating them
back to the caller.
Get all bucket names
This example's main program calls getBucketNames()
to get an array containing all of the bucket names. That function is
defined as follows.
// Return an array containing the names of all available buckets. // // - Returns: An array of strings listing the buckets. func getBucketNames() async throws -> [String] { do { // Get an S3Client with which to access Amazon S3. let configuration = try await S3Client.S3ClientConfiguration() // configuration.region = "us-east-2" // Uncomment this to set the region programmatically. let client = S3Client(config: configuration) // Use "Paginated" to get all the buckets. // This lets the SDK handle the 'continuationToken' in "ListBucketsOutput". let pages = client.listBucketsPaginated( input: ListBucketsInput( maxBuckets: 10) ) // Get the bucket names. var bucketNames: [String] = [] do { for try await page in pages { guard let buckets = page.buckets else { print("Error: no buckets returned.") continue } for bucket in buckets { bucketNames.append(bucket.name ?? "<unknown>") } } return bucketNames } catch { print("ERROR: listBuckets:", dump(error)) throw error } } }
This function starts by creating an Amazon S3 client and calling its
listBuckets(input:)
function to request a list of
all of the available buckets. The list is returned asynchronously.
After it's returned, the bucket list is fetched from the output
structure's buckets
property. If it's nil
,
an empty array is immediately returned to the caller. Otherwise,
each bucket name is added to the array of bucket name strings, which
is then returned to the caller.
Add the example entry point
To allow the use of asynchronous functions from within
main()
, use Swift's @main
attribute
to create an object that contains a static async
function
called main()
. Swift will use this as the program
entry point.
/// The program's asynchronous entry point. @main struct Main { static func main() async { do { let names = try await getBucketNames() print("Found \(names.count) buckets:") for name in names { print(" \(name)") } } catch let error as AWSServiceError { print("An Amazon S3 service error occurred: \(error.message ?? "No details available")") } catch { print("An unknown error occurred: \(dump(error))") } } }
main()
calls
getBucketNames()
, then outputs the returned list
of names. Errors thrown by getBucketNames()
are
caught and handled. Errors of type ServiceError
, which
represent errors reported by the AWS service, are handled
specially.
Add the AWS SDK for Swift to an existing Xcode project
If you have an existing Xcode project, you can add the SDK for Swift to it. Open your project's main configuration pane and choose the Swift Packages tab at the right end of the tab bar. The following image shows how to do this for an Xcode project called "Supergame," which will use Amazon S3 to get game data from a server.
Swift Packages tab in Xcode
This shows a list of the Swift packages currently in use by your project. If you haven't added any Swift packages, the list will be empty, as shown in the preceding image. To add the AWS SDK for Swift package to your project, choose the + button under the package list.
Find and select packages to import
Next, specify the package or packages to add to your project. You
can choose from standard Apple-provided packages or enter the URL of a
custom package in the search box at the top of the window. Enter the
URL of the AWS SDK for Swift as follows: https://github.com/awslabs/aws-sdk-swift.git
.
After you enter the SDK URL, you can configure version requirements and other options for the SDK package import.
Configure dependency rules for the SDK for Swift package
Configure the dependency rule. Make sure that Add to Project is set to your project — "Supergame" in this case — and choose Add Package. You will see a progress bar while the SDK and all its dependencies are processed and retrieved.
Fetching the AWS SDK for Swift package and its product list
Next, select specific products from the
AWS SDK for Swift package to include in your project. Each product is
generally one AWS API or service. Each package is listed by package
name, starting with AWS
and followed by the shorthand
name of the service or toolkit.
For the Supergame project, select AWSS3
,
AWSDynamoDB
, and AWSGameLift
. Assign them to
the correct target (iOS in this example), and choose Add
Package.
Choose package products for specific AWS services and toolkits
Your project is now configured to import the AWS SDK for Swift package and to include the desired APIs in the build for that target. To see a list of the AWS libraries, open the target's General tab and scroll down to Frameworks, Libraries, and Embedded Content.
AWS SDK for Swift libraries in the Xcode target
If your project is a multi-platform project, you also need to add the AWS libraries to the other targets in your project. For each platform's target, navigate to the Frameworks, Libraries, and Embedded Content section under the General tab and choose + to open the library picker window.
Then, you can scroll to find and select all of the needed libraries and choose Add to add them all at once. Alternatively, you can search for and select each library, then choose Add to add them to the target one at a time.
Find and add SDK for Swift libraries using the Xcode library picker window
You're now ready to import the libraries and any needed dependencies into individual Swift source code files and start using the AWS services in your project. Build your project by using the Xcode Build option in the Product menu.
Build and run an SPM project
To build and run a Swift Package Manager project from a Linux or macOS terminal prompt, use the following commands.
Build a project
$
swift build
Run a project
$
swift run$
swift runexecutable-name
$
swift runexecutable-name
arg1, ...
If your project builds only one executable file, you can type swift run to build and run it. If your project outputs multiple executables, you can specify the file name of the executable you want to run. If you want to pass arguments to the program when you run it, you must specify the executable name before listing the arguments.
Get the built product output directory
$
swift build --show-bin-path /home/janice/MyProject/.build/x86_64-unknown-linux-gnu/debug
Delete build artifacts
$
swift package clean
Delete build artifacts and all build caches
$
swift package reset
Import AWS SDK for Swift libraries into source files
After the libraries are in place, you can use the Swift
import
directive to import the individual libraries into
each source file that needs them. To use the functions for a given
service, import its library from the AWS SDK for Swift package into your
source code file. Also import the ClientRuntime
library, which contains utility functions and type definitions.
import Foundation import ClientRuntime import AWSS3
The standard Swift library Foundation
is also
imported because it's used by many features of the AWS SDK for Swift.