Use client services with the AWS SDK for Swift
Each AWS service is exposed through a corresponding Swift class. Each class provides a number of functions that you can call to issue requests to AWS services, including Amazon S3, DynamoDB, IAM, and others. Functions that access the network are designed to operate in the background so that your application can continue to run while awaiting the response. The SDK then notifies you when the response arrives.
The process of sending requests to AWS services is as follows:
-
Create a service client object with the desired configuration, such as the specific AWS Region.
-
Create an input object with the values and data needed to make the request. For example, when sending a
GetObject
request to Amazon S3, you need to specify the bucket name and the key of the Amazon S3 object that you want to access. For a request method namedSomeOperation
, the input parameters object is created using a function calledSomeOperationInput()
. -
Call the service object method on the client object that sends the desired request, with the input object created in the previous step.
-
Use
await
to wait for the response, and handle thrown exceptions to appropriately handle error conditions. -
Examine the contents of the returned structure for the results you need. Every SDK function returns a structure with a type whose name is the same as the service action performed by the function, followed by the word
Output
. For example, when calling the Amazon S3 functionS3Client.createBucket(input:)
, the return type isCreateBucketOutput
.
Create and use AWS client objects
Before you can send requests to an AWS service, you must first
instantiate a client object corresponding to the service. These
client classes are helpfully named using the service name and the
word Client
. Examples include S3Client
and
IAMClient
.
After creating the client object, use it to make your requests. When you're done, release the object. If the service connection is open, it is closed for you automatically.
do { let s3 = try await S3Client() // ... } catch { dump(error) }
If an error occurs while trying to instantiate an AWS service —
or at any time while using the service — an exception is thrown.
Your catch
block should handle the error
appropriately.
Unless you are in a testing environment in which you expect a knowledgeable user to have configured reasonable default options, specify the appropriate service configuration when instantiating the client object. This is described in Configure a client.
Specify service client function parameters
When calling service client methods, you pass the input object
corresponding to that operation. For example, before calling the
getObject()
method on the Amazon S3 service class
S3Client
, you need to create the input parameter
object using the initializer GetObjectInput()
.
do { let s3 = try S3Client() let inputObject = GetObjectInput(bucket: "amzn-s3-demo-bucket", key: "keyName") let output = try await s3.getObject(input: inputObject) // ... } catch { dump(error) }
In this example, GetObjectInput()
is used to create an input object
for the getObject(input:)
method. The resulting input object
specifies that the desired data has the keyName
key and
should be fetched from the Amazon S3 bucket named
amzn-s3-demo-bucket
.
Call SDK functions
Nearly all AWS SDK for Swift functions are asynchronous and can be
called using Swift's async
/await
model.
To call one of the SDK's asynchronous functions from synchronous
code, call the function from a Swift Task
created and run from your synchronous code.
Call SDK functions asynchronously
The following function fetches and returns the content of a
file named text/motd.txt
from a bucket named amzn-s3-demo-bucket, using Amazon S3.
func getMOTD() async throws -> String? { let s3 = try S3Client() let motdInput = GetObjectInput(bucket: "amzn-s3-demo-bucket", key: "text/motd.txt") let output = try await s3.getObject(input: motdInput) guard let data = output.body?.toBytes().toData() else { return nil } return String(decoding: data, as: UTF8.self) }
The getMOTD()
function can only be called
from another async
function, and returns a string
that contains the text in the MOTD
file or
nil
if the file is empty. It throws an exception on
errors. Thus, you call the getMOTD()
function.
do { let motd = try await getMOTD() // ... } catch { dump(error) }
Here, the fetched "message of the day" text is available in
the variable motd
immediately following the
call to getMOTD()
. If an error occurs
attempting to fetch the text, an appropriate exception is
delivered to the catch
clause. The standard Swift
variable error
describes the problem that
occurred.
Call SDK functions from synchronous code
To call AWS SDK for Swift functions from synchronous code, enclose
the code that needs to run asynchronously in a
Task
. The Task
uses await
for each SDK function call that returns its results
asynchronously. You might need to use an atomic flag or other
means to know that the operation has finished.
Note
It's important to properly manage asynchronous requests.
Be sure that any operation that's dependent on a previous
result waits until that result is available before it
begins. When used properly, the
async
/await
model handles most of
this for you.
func updateMOTD() { Task() { var motd: String = "" do { let s3 = try S3Client() let motdInput = GetObjectInput(bucket: "amzn-s3-demo-bucket", key: "text/motd.txt") let output = try await s3.getObject(input: motdInput) if let bytes = output.body?.toBytes() { motd = String(decoding: bytes.toData(), as: UTF8.self) } } catch { motd = "" } setMOTD(motd) } }
In this example, the code inside the Task
block
runs asynchronously, returning no output value to the caller. It
fetches the contents of a text file with the key
text/motd.txt
and calls a function named
setMOTD()
, with the contents of the file decoded
into a UTF-8 string.
A do
/catch
block is used to capture
any thrown exceptions and set the motd
variable to
an empty string, which indicates that no message is
available.
A call to this updateMOTD()
function will spawn
the task and return immediately. In the background, the program
continues to run while the asynchronous task code fetches and
uses the text from the specified file on Amazon S3. When the task has
completed, the Task
automatically ends.