Amplify has re-imagined the way frontend developers build fullstack applications. Develop and deploy without the hassle.

Page updated May 1, 2024

Download files

The latest version of Amplify Storage supports specifying S3 objects as a paths.
We recommend using path instead of key to specify S3 objects.

Note: key parameter is deprecated and may be removed in next major version.

There are three ways of getting data that was previously uploaded:

Download data

You can download to in-memory buffer Data object with Amplify.Storage.downloadData:

With StoragePath

1let downloadTask = Amplify.Storage.downloadData(path: .fromString("public/example/path"))
2Task {
3 for await progress in await downloadTask.progress {
4 print("Progress: \(progress)")
5 }
6}
7let data = try await downloadTask.value
8print("Completed: \(data)")
1let downloadTask = Amplify.Storage.downloadData(path: .fromString("public/example/path"))
2let progressSink = downloadTask
3 .inProcessPublisher
4 .sink { progress in
5 print("Progress: \(progress)")
6 }
7
8let resultSink = downloadTask
9 .resultPublisher
10 .sink {
11 if case let .failure(storageError) = $0 {
12 print("Failed: \(storageError.errorDescription). \(storageError.recoverySuggestion)")
13 }
14 }
15 receiveValue: { data in
16 print("Completed: \(data)")
17 }

With Key (Deprecated)

1let downloadTask = Amplify.Storage.downloadData(key: "ExampleKey")
2Task {
3 for await progress in await downloadTask.progress {
4 print("Progress: \(progress)")
5 }
6}
7let data = try await downloadTask.value
8print("Completed: \(data)")
1let downloadTask = Amplify.Storage.downloadData(key: "ExampleKey")
2let progressSink = downloadTask
3 .inProcessPublisher
4 .sink { progress in
5 print("Progress: \(progress)")
6 }
7
8let resultSink = downloadTask
9 .resultPublisher
10 .sink {
11 if case let .failure(storageError) = $0 {
12 print("Failed: \(storageError.errorDescription). \(storageError.recoverySuggestion)")
13 }
14 }
15 receiveValue: { data in
16 print("Completed: \(data)")
17 }

Download to file

You can download to a file URL with Amplify.Storage.downloadFile:

With StoragePath

1let downloadToFileName = FileManager.default.urls(
2 for: .documentDirectory,
3 in: .userDomainMask
4)[0].appendingPathComponent("myFile.txt")
5
6let downloadTask = Amplify.Storage.downloadFile(
7 path: .fromString("public/example/path"),
8 local: downloadToFileName,
9 options: nil
10)
11Task {
12 for await progress in await downloadTask.progress {
13 print("Progress: \(progress)")
14 }
15}
16try await downloadTask.value
17print("Completed")
1let downloadToFileName = FileManager.default.urls(
2 for: .documentDirectory,
3 in: .userDomainMask
4)[0].appendingPathComponent("myFile.txt")
5
6let downloadTask = Amplify.Storage.downloadFile(
7 path: .fromString("public/example/path"),
8 local: downloadToFileName,
9 options: nil
10)
11let progressSink = downloadTask
12 .inProcessPublisher
13 .sink { progress in
14 print("Progress: \(progress)")
15 }
16
17let resultSink = downloadTask
18 .resultPublisher
19 .sink {
20 if case let .failure(storageError) = $0 {
21 print("Failed: \(storageError.errorDescription). \(storageError.recoverySuggestion)")
22 }
23 }
24 receiveValue: {
25 print("Completed")
26 }

With Key (Deprecated)

1let downloadToFileName = FileManager.default.urls(
2 for: .documentDirectory,
3 in: .userDomainMask
4)[0].appendingPathComponent("myFile.txt")
5
6let downloadTask = Amplify.Storage.downloadFile(
7 key: "myKey",
8 local: downloadToFileName,
9 options: nil
10)
11Task {
12 for await progress in await downloadTask.progress {
13 print("Progress: \(progress)")
14 }
15}
16try await downloadTask.value
17print("Completed")
1let downloadToFileName = FileManager.default.urls(
2 for: .documentDirectory,
3 in: .userDomainMask
4)[0].appendingPathComponent("myFile.txt")
5
6let downloadTask = Amplify.Storage.downloadFile(
7 key: "myKey",
8 local: downloadToFileName,
9 options: nil
10)
11let progressSink = downloadTask
12 .inProcessPublisher
13 .sink { progress in
14 print("Progress: \(progress)")
15 }
16
17let resultSink = downloadTask
18 .resultPublisher
19 .sink {
20 if case let .failure(storageError) = $0 {
21 print("Failed: \(storageError.errorDescription). \(storageError.recoverySuggestion)")
22 }
23 }
24 receiveValue: {
25 print("Completed")
26 }

Generate a download URL

You can also retrieve a URL for the object in storage:

1let url = try await Amplify.Storage.getURL(path: .fromString("public/example/path"))
2print("Completed: \(url)")
1let url = try await Amplify.Storage.getURL(key: "ExampleKey")
2print("Completed: \(url)")

When creating a downloadable URL, you can choose to check if the file exists by setting validateObjectExistence to true in AWSStorageGetURLOptions. If the file is inaccessible or does not exist, a StorageError is thrown. This allows you to check if an object exists during generating the presigned URL, which you can then use to download that object.

1let url = try await Amplify.Storage.getURL(
2 path: .fromString("public/example/path"),
3 options: .init(
4 pluginOptions: AWSStorageGetURLOptions(
5 validateObjectExistence: true
6 )
7 )
8)
1let url = try await Amplify.Storage.getURL(
2 key: "ExampleKey",
3 options: .init(
4 pluginOptions: AWSStorageGetURLOptions(
5 validateObjectExistence: true
6 )
7 )
8)

Cancel, Pause, Resume

Calls to downloadData or downloadFile return a reference to the task that is actually performing the download.

To cancel the download (for example, in response to the user pressing a Cancel button), you simply call cancel() on the download task.

1func cancelDownload() {
2 downloadTask.cancel()
3}

You can also pause and then resume the task.

1downloadTask.pause()
2downloadTask.resume()

Download tasks are run using URLSessionTask instances internally. You can learn more about them in Apple's official documentation.