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

let downloadTask = Amplify.Storage.downloadData(path: .fromString("public/example/path"))
Task {
for await progress in await downloadTask.progress {
print("Progress: \(progress)")
}
}
let data = try await downloadTask.value
print("Completed: \(data)")
let downloadTask = Amplify.Storage.downloadData(path: .fromString("public/example/path"))
let progressSink = downloadTask
.inProcessPublisher
.sink { progress in
print("Progress: \(progress)")
}
let resultSink = downloadTask
.resultPublisher
.sink {
if case let .failure(storageError) = $0 {
print("Failed: \(storageError.errorDescription). \(storageError.recoverySuggestion)")
}
}
receiveValue: { data in
print("Completed: \(data)")
}

With Key (Deprecated)

let downloadTask = Amplify.Storage.downloadData(key: "ExampleKey")
Task {
for await progress in await downloadTask.progress {
print("Progress: \(progress)")
}
}
let data = try await downloadTask.value
print("Completed: \(data)")
let downloadTask = Amplify.Storage.downloadData(key: "ExampleKey")
let progressSink = downloadTask
.inProcessPublisher
.sink { progress in
print("Progress: \(progress)")
}
let resultSink = downloadTask
.resultPublisher
.sink {
if case let .failure(storageError) = $0 {
print("Failed: \(storageError.errorDescription). \(storageError.recoverySuggestion)")
}
}
receiveValue: { data in
print("Completed: \(data)")
}

Download to file

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

With StoragePath

let downloadToFileName = FileManager.default.urls(
for: .documentDirectory,
in: .userDomainMask
)[0].appendingPathComponent("myFile.txt")
let downloadTask = Amplify.Storage.downloadFile(
path: .fromString("public/example/path"),
local: downloadToFileName,
options: nil
)
Task {
for await progress in await downloadTask.progress {
print("Progress: \(progress)")
}
}
try await downloadTask.value
print("Completed")
let downloadToFileName = FileManager.default.urls(
for: .documentDirectory,
in: .userDomainMask
)[0].appendingPathComponent("myFile.txt")
let downloadTask = Amplify.Storage.downloadFile(
path: .fromString("public/example/path"),
local: downloadToFileName,
options: nil
)
let progressSink = downloadTask
.inProcessPublisher
.sink { progress in
print("Progress: \(progress)")
}
let resultSink = downloadTask
.resultPublisher
.sink {
if case let .failure(storageError) = $0 {
print("Failed: \(storageError.errorDescription). \(storageError.recoverySuggestion)")
}
}
receiveValue: {
print("Completed")
}

With Key (Deprecated)

let downloadToFileName = FileManager.default.urls(
for: .documentDirectory,
in: .userDomainMask
)[0].appendingPathComponent("myFile.txt")
let downloadTask = Amplify.Storage.downloadFile(
key: "myKey",
local: downloadToFileName,
options: nil
)
Task {
for await progress in await downloadTask.progress {
print("Progress: \(progress)")
}
}
try await downloadTask.value
print("Completed")
let downloadToFileName = FileManager.default.urls(
for: .documentDirectory,
in: .userDomainMask
)[0].appendingPathComponent("myFile.txt")
let downloadTask = Amplify.Storage.downloadFile(
key: "myKey",
local: downloadToFileName,
options: nil
)
let progressSink = downloadTask
.inProcessPublisher
.sink { progress in
print("Progress: \(progress)")
}
let resultSink = downloadTask
.resultPublisher
.sink {
if case let .failure(storageError) = $0 {
print("Failed: \(storageError.errorDescription). \(storageError.recoverySuggestion)")
}
}
receiveValue: {
print("Completed")
}

Generate a download URL

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

let url = try await Amplify.Storage.getURL(path: .fromString("public/example/path"))
print("Completed: \(url)")
let url = try await Amplify.Storage.getURL(key: "ExampleKey")
print("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.

let url = try await Amplify.Storage.getURL(
path: .fromString("public/example/path"),
options: .init(
pluginOptions: AWSStorageGetURLOptions(
validateObjectExistence: true
)
)
)
let url = try await Amplify.Storage.getURL(
key: "ExampleKey",
options: .init(
pluginOptions: AWSStorageGetURLOptions(
validateObjectExistence: true
)
)
)

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.

func cancelDownload() {
downloadTask.cancel()
}

You can also pause and then resume the task.

downloadTask.pause()
downloadTask.resume()

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