Skip to content

Commit 376c52a

Browse files
authored
Swift: S3 update (#6890)
1 parent 85ef3b9 commit 376c52a

File tree

11 files changed

+146
-105
lines changed

11 files changed

+146
-105
lines changed

swift/example_code/s3/DeleteObjects/Sources/DeleteObjects/DeleteObjects.swift

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,18 @@
88

99
// snippet-start:[s3.swift.deleteobjects.example]
1010
// snippet-start:[s3.swift.deleteobjects.main.imports]
11+
import ArgumentParser
1112
import Foundation
1213
import ServiceHandler
13-
import ArgumentParser
14+
1415
// snippet-end:[s3.swift.deleteobjects.main.imports]
1516

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

2324
@Argument(help: "Name of the S3 bucket to delete objects in")
2425
var bucketName: String
@@ -37,17 +38,17 @@ struct ExampleCommand: ParsableCommand {
3738
/// example.
3839
// snippet-start:[s3.swift.deleteobjects.command.runasync]
3940
func runAsync() async throws {
40-
let serviceHandler = await ServiceHandler(region: region)
41-
4241
do {
43-
try await serviceHandler.deleteObjects(bucket: bucketName,
44-
keys: fileNames)
42+
let serviceHandler = try await ServiceHandler(region: region)
43+
try await serviceHandler.deleteObjects(bucket: bucketName,
44+
keys: fileNames)
4545
} catch {
4646
print("*** Error. Unable to complete deleting the objects.")
4747
}
4848
}
4949
// snippet-end:[s3.swift.deleteobjects.command.runasync]
5050
}
51+
5152
// snippet-end:[s3.swift.deleteobjects.command]
5253

5354
//
@@ -65,7 +66,8 @@ struct Main {
6566
} catch {
6667
ExampleCommand.exit(withError: error)
6768
}
68-
}
69+
}
6970
}
71+
7072
// snippet-end:[s3.swift.deleteobjects.main]
71-
// snippet-end:[s3.swift.deleteobjects.example]
73+
// snippet-end:[s3.swift.deleteobjects.example]

swift/example_code/s3/DeleteObjects/Sources/ServiceHandler/ServiceHandler.swift

Lines changed: 20 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,47 +2,52 @@
22
// SPDX-License-Identifier: Apache-2.0
33

44
/*
5-
A class containing functions that interact with AWS services.
6-
*/
5+
A class containing functions that interact with AWS services.
6+
*/
77

88
// snippet-start:[s3.swift.deleteobjects.handler]
99
// snippet-start:[s3.swift.deleteobjects.handler.imports]
10-
import Foundation
1110
import AWSS3
1211
import ClientRuntime
12+
import Foundation
13+
1314
// snippet-end:[s3.swift.deleteobjects.handler.imports]
1415

1516
/// Errors returned by `ServiceHandler` functions.
1617
// snippet-start:[s3.swift.deleteobjects.enum.service-error]
1718
public enum ServiceHandlerError: Error {
1819
case deleteObjectsError
1920
}
21+
2022
// snippet-end:[s3.swift.deleteobjects.enum.service-error]
2123

2224
/// A class containing all the code that interacts with the AWS SDK for Swift.
2325
public class ServiceHandler {
2426
public let client: S3Client
25-
public var region: S3ClientTypes.BucketLocationConstraint?
26-
27+
2728
/// Initialize and return a new ``ServiceHandler`` object, which is used
2829
/// to drive the AWS calls
2930
/// used for the example.
30-
///
31+
///
3132
/// - Parameters:
32-
/// - region: The AWS Region to access.
33+
/// - region: The optional AWS Region to access.
3334
///
3435
/// - Returns: A new ``ServiceHandler`` object, ready to be called to
3536
/// execute AWS operations.
3637
// snippet-start:[s3.swift.deleteobjects.handler.init]
37-
public init(region: String = "us-east-2") async {
38-
self.region = S3ClientTypes.BucketLocationConstraint(rawValue: region)
38+
public init(region: String? = nil) async throws {
3939
do {
40-
client = try S3Client(region: region)
40+
let config = try await S3Client.S3ClientConfiguration()
41+
if let region = region {
42+
config.region = region
43+
}
44+
client = S3Client(config: config)
4145
} catch {
4246
print("ERROR: ", dump(error, name: "Initializing Amazon S3 client"))
43-
exit(1)
47+
throw error
4448
}
4549
}
50+
4651
// snippet-end:[s3.swift.deleteobjects.handler.init]
4752

4853
/// Deletes the specified objects from Amazon S3.
@@ -56,30 +61,19 @@ public class ServiceHandler {
5661
let input = DeleteObjectsInput(
5762
bucket: bucket,
5863
delete: S3ClientTypes.Delete(
59-
objects: keys.map({ S3ClientTypes.ObjectIdentifier(key: $0) }),
64+
objects: keys.map { S3ClientTypes.ObjectIdentifier(key: $0) },
6065
quiet: true
6166
)
6267
)
6368

6469
do {
65-
let output = try await client.deleteObjects(input: input)
66-
67-
// As of the last update to this example, any errors are returned
68-
// in the `output` object's `errors` property. If there are any
69-
// errors in this array, throw an exception. Once the error
70-
// handling is finalized in later updates to the AWS SDK for
71-
// Swift, this example will be updated to handle errors better.
72-
73-
guard let errors = output.errors else {
74-
return // No errors.
75-
}
76-
if errors.count != 0 {
77-
throw ServiceHandlerError.deleteObjectsError
78-
}
70+
_ = try await client.deleteObjects(input: input)
7971
} catch {
72+
print("ERROR: deleteObjects:", dump(error))
8073
throw error
8174
}
8275
}
8376
// snippet-end:[s3.swift.deleteobjects.handler.DeleteObjects]
8477
}
78+
8579
// snippet-end:[s3.swift.deleteobjects.handler]

swift/example_code/s3/DeleteObjects/Tests/DeleteObjectsTests/DeleteObjectsTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ final class DeleteObjectsTests: XCTestCase {
3232
super.setUp()
3333

3434
Task() {
35-
DeleteObjectsTests.serviceHandler = await ServiceHandler()
35+
DeleteObjectsTests.serviceHandler = try await ServiceHandler()
3636
DeleteObjectsTests.demoCleanup = await S3DemoCleanup()
3737
tdSem.signal()
3838
}

swift/example_code/s3/DeleteObjects/Tests/DeleteObjectsTests/S3DemoCleanup.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public class S3DemoCleanup {
5454

5555
init() async {
5656
do {
57-
self.client = try S3Client(region: "us-east-2")
57+
self.client = try await S3Client()
5858
} catch {
5959
print("Error initializing S3 client for tracking and deleting Amazon S3 buckets and files created by the example:")
6060
dump(error)
@@ -237,4 +237,4 @@ public class S3DemoCleanup {
237237
}
238238
}
239239
}
240-
}
240+
}

swift/example_code/s3/DeleteObjects/Tests/DeleteObjectsTests/ServiceHandler_Ext.swift

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,8 @@ public extension ServiceHandler {
2020
/// - name: Name of the bucket to create.
2121
/// Throws an exception if an error occurs.
2222
func createBucket(name: String) async throws {
23-
let config = S3ClientTypes.CreateBucketConfiguration(
24-
locationConstraint: self.region
25-
)
2623
let input = CreateBucketInput(
27-
bucket: name,
28-
createBucketConfiguration: config
24+
bucket: name
2925
)
3026
_ = try await client.createBucket(input: input)
3127
}
@@ -100,4 +96,4 @@ public extension ServiceHandler {
10096
}
10197

10298
return names
103-
}}
99+
}}

swift/example_code/s3/ListBuckets-Simple/Sources/entry.swift

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,39 +7,56 @@
77
/// Amazon Simple Storage Service (Amazon S3) function `ListBuckets`.
88

99
// snippet-start:[s3.swift.intro.imports]
10-
import Foundation
11-
import AWSS3
1210
import AWSClientRuntime
11+
import AWSS3
12+
import Foundation
13+
1314
// snippet-end:[s3.swift.intro.imports]
1415

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

25-
// snippet-start:[s3.swift.intro.listbuckets]
26-
let output = try await client.listBuckets(
27-
input: ListBucketsInput()
28-
)
29-
// snippet-end:[s3.swift.intro.listbuckets]
30-
31-
// Get the bucket names.
32-
var bucketNames: [String] = []
29+
// snippet-start:[s3.swift.intro.listbuckets]
30+
// Use "Paginated" to get all the buckets.
31+
// This lets the SDK handle the 'continuationToken' in "ListBucketsOutput".
32+
let pages = client.listBucketsPaginated(
33+
input: ListBucketsInput( maxBuckets: 10)
34+
)
35+
// snippet-end:[s3.swift.intro.listbuckets]
3336

34-
guard let buckets = output.buckets else {
35-
return bucketNames
36-
}
37-
for bucket in buckets {
38-
bucketNames.append(bucket.name ?? "<unknown>")
39-
}
37+
// Get the bucket names.
38+
var bucketNames: [String] = []
39+
40+
do {
41+
for try await page in pages {
42+
guard let buckets = page.buckets else {
43+
print("Error: no buckets returned.")
44+
continue
45+
}
46+
47+
for bucket in buckets {
48+
bucketNames.append(bucket.name ?? "<unknown>")
49+
}
50+
}
4051

41-
return bucketNames
52+
return bucketNames
53+
} catch {
54+
print("ERROR: listBuckets:", dump(error))
55+
throw error
56+
}
57+
}
4258
}
59+
4360
// snippet-end:[s3.swift.intro.getbucketnames]
4461

4562
// snippet-start:[s3.swift.intro.main]
@@ -61,4 +78,5 @@ struct Main {
6178
}
6279
}
6380
}
81+
6482
// snippet-end:[s3.swift.intro.main]

0 commit comments

Comments
 (0)