Skip to content

Commit

Permalink
Swift: S3 update (#6890)
Browse files Browse the repository at this point in the history
  • Loading branch information
meyertst-aws authored Sep 23, 2024
1 parent 85ef3b9 commit 376c52a
Show file tree
Hide file tree
Showing 11 changed files with 146 additions and 105 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,18 @@

// snippet-start:[s3.swift.deleteobjects.example]
// snippet-start:[s3.swift.deleteobjects.main.imports]
import ArgumentParser
import Foundation
import ServiceHandler
import ArgumentParser

// snippet-end:[s3.swift.deleteobjects.main.imports]

/// The command-line arguments and options available for this
/// example command.
// snippet-start:[s3.swift.deleteobjects.command]
struct ExampleCommand: ParsableCommand {
@Option(help: "AWS Region the bucket where the bucket is")
var region = "us-east-1"
var region: String?

@Argument(help: "Name of the S3 bucket to delete objects in")
var bucketName: String
Expand All @@ -37,17 +38,17 @@ struct ExampleCommand: ParsableCommand {
/// example.
// snippet-start:[s3.swift.deleteobjects.command.runasync]
func runAsync() async throws {
let serviceHandler = await ServiceHandler(region: region)

do {
try await serviceHandler.deleteObjects(bucket: bucketName,
keys: fileNames)
let serviceHandler = try await ServiceHandler(region: region)
try await serviceHandler.deleteObjects(bucket: bucketName,
keys: fileNames)
} catch {
print("*** Error. Unable to complete deleting the objects.")
}
}
// snippet-end:[s3.swift.deleteobjects.command.runasync]
}

// snippet-end:[s3.swift.deleteobjects.command]

//
Expand All @@ -65,7 +66,8 @@ struct Main {
} catch {
ExampleCommand.exit(withError: error)
}
}
}
}

// snippet-end:[s3.swift.deleteobjects.main]
// snippet-end:[s3.swift.deleteobjects.example]
// snippet-end:[s3.swift.deleteobjects.example]
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,52 @@
// SPDX-License-Identifier: Apache-2.0

/*
A class containing functions that interact with AWS services.
*/
A class containing functions that interact with AWS services.
*/

// snippet-start:[s3.swift.deleteobjects.handler]
// snippet-start:[s3.swift.deleteobjects.handler.imports]
import Foundation
import AWSS3
import ClientRuntime
import Foundation

// snippet-end:[s3.swift.deleteobjects.handler.imports]

/// Errors returned by `ServiceHandler` functions.
// snippet-start:[s3.swift.deleteobjects.enum.service-error]
public enum ServiceHandlerError: Error {
case deleteObjectsError
}

// snippet-end:[s3.swift.deleteobjects.enum.service-error]

/// A class containing all the code that interacts with the AWS SDK for Swift.
public class ServiceHandler {
public let client: S3Client
public var region: S3ClientTypes.BucketLocationConstraint?


/// Initialize and return a new ``ServiceHandler`` object, which is used
/// to drive the AWS calls
/// used for the example.
///
///
/// - Parameters:
/// - region: The AWS Region to access.
/// - region: The optional AWS Region to access.
///
/// - Returns: A new ``ServiceHandler`` object, ready to be called to
/// execute AWS operations.
// snippet-start:[s3.swift.deleteobjects.handler.init]
public init(region: String = "us-east-2") async {
self.region = S3ClientTypes.BucketLocationConstraint(rawValue: region)
public init(region: String? = nil) async throws {
do {
client = try S3Client(region: region)
let config = try await S3Client.S3ClientConfiguration()
if let region = region {
config.region = region
}
client = S3Client(config: config)
} catch {
print("ERROR: ", dump(error, name: "Initializing Amazon S3 client"))
exit(1)
throw error
}
}

// snippet-end:[s3.swift.deleteobjects.handler.init]

/// Deletes the specified objects from Amazon S3.
Expand All @@ -56,30 +61,19 @@ public class ServiceHandler {
let input = DeleteObjectsInput(
bucket: bucket,
delete: S3ClientTypes.Delete(
objects: keys.map({ S3ClientTypes.ObjectIdentifier(key: $0) }),
objects: keys.map { S3ClientTypes.ObjectIdentifier(key: $0) },
quiet: true
)
)

do {
let output = try await client.deleteObjects(input: input)

// As of the last update to this example, any errors are returned
// in the `output` object's `errors` property. If there are any
// errors in this array, throw an exception. Once the error
// handling is finalized in later updates to the AWS SDK for
// Swift, this example will be updated to handle errors better.

guard let errors = output.errors else {
return // No errors.
}
if errors.count != 0 {
throw ServiceHandlerError.deleteObjectsError
}
_ = try await client.deleteObjects(input: input)
} catch {
print("ERROR: deleteObjects:", dump(error))
throw error
}
}
// snippet-end:[s3.swift.deleteobjects.handler.DeleteObjects]
}

// snippet-end:[s3.swift.deleteobjects.handler]
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ final class DeleteObjectsTests: XCTestCase {
super.setUp()

Task() {
DeleteObjectsTests.serviceHandler = await ServiceHandler()
DeleteObjectsTests.serviceHandler = try await ServiceHandler()
DeleteObjectsTests.demoCleanup = await S3DemoCleanup()
tdSem.signal()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public class S3DemoCleanup {

init() async {
do {
self.client = try S3Client(region: "us-east-2")
self.client = try await S3Client()
} catch {
print("Error initializing S3 client for tracking and deleting Amazon S3 buckets and files created by the example:")
dump(error)
Expand Down Expand Up @@ -237,4 +237,4 @@ public class S3DemoCleanup {
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,8 @@ public extension ServiceHandler {
/// - name: Name of the bucket to create.
/// Throws an exception if an error occurs.
func createBucket(name: String) async throws {
let config = S3ClientTypes.CreateBucketConfiguration(
locationConstraint: self.region
)
let input = CreateBucketInput(
bucket: name,
createBucketConfiguration: config
bucket: name
)
_ = try await client.createBucket(input: input)
}
Expand Down Expand Up @@ -100,4 +96,4 @@ public extension ServiceHandler {
}

return names
}}
}}
60 changes: 39 additions & 21 deletions swift/example_code/s3/ListBuckets-Simple/Sources/entry.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,56 @@
/// Amazon Simple Storage Service (Amazon S3) function `ListBuckets`.

// snippet-start:[s3.swift.intro.imports]
import Foundation
import AWSS3
import AWSClientRuntime
import AWSS3
import Foundation

// snippet-end:[s3.swift.intro.imports]

// snippet-start:[s3.swift.intro.getbucketnames]
// Return an array containing the names of all available buckets.
//
// - Returns: An array of strings listing the buckets.
func getBucketNames() async throws -> [String] {
// Get an S3Client with which to access Amazon S3.
// snippet-start:[s3.swift.intro.client-init]
let client = try S3Client(region: "us-east-1")
// snippet-end:[s3.swift.intro.client-init]
do {
// Get an S3Client with which to access Amazon S3.
// snippet-start:[s3.swift.intro.client-init]
let configuration = try await S3Client.S3ClientConfiguration()
// configuration.region = "us-east-2" // Uncomment this to set the region programmatically.
let client = S3Client(config: configuration)
// snippet-end:[s3.swift.intro.client-init]

// snippet-start:[s3.swift.intro.listbuckets]
let output = try await client.listBuckets(
input: ListBucketsInput()
)
// snippet-end:[s3.swift.intro.listbuckets]

// Get the bucket names.
var bucketNames: [String] = []
// snippet-start:[s3.swift.intro.listbuckets]
// Use "Paginated" to get all the buckets.
// This lets the SDK handle the 'continuationToken' in "ListBucketsOutput".
let pages = client.listBucketsPaginated(
input: ListBucketsInput( maxBuckets: 10)
)
// snippet-end:[s3.swift.intro.listbuckets]

guard let buckets = output.buckets else {
return bucketNames
}
for bucket in buckets {
bucketNames.append(bucket.name ?? "<unknown>")
}
// 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
return bucketNames
} catch {
print("ERROR: listBuckets:", dump(error))
throw error
}
}
}

// snippet-end:[s3.swift.intro.getbucketnames]

// snippet-start:[s3.swift.intro.main]
Expand All @@ -61,4 +78,5 @@ struct Main {
}
}
}

// snippet-end:[s3.swift.intro.main]
Loading

0 comments on commit 376c52a

Please sign in to comment.