Page updated Feb 15, 2024

Upload files

Upload data

To upload to S3 from a data object, specify the key and the data object to be uploaded.

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

Upload file

When you have a file that you want to upload, you can specify the url to the file in the local parameter. If a file with the same key already exists in S3, the existing S3 file will be overwritten.

1let dataString = "My Data"
2let fileNameKey = "myFile.txt"
3guard let filename = FileManager.default.urls(
4 for: .documentDirectory,
5 in: .userDomainMask
6).first?.appendingPathComponent(fileNameKey)
7else { return }
8
9try dataString.write(
10 to: filename,
11 atomically: true,
12 encoding: .utf8
13)
14
15let uploadTask = Amplify.Storage.uploadFile(
16 key: fileNameKey,
17 local: filename
18)
19
20Task {
21 for await progress in await uploadTask.progress {
22 print("Progress: \(progress)")
23 }
24}
25let data = try await uploadTask.value
26print("Completed: \(data)")
1let dataString = "My Data"
2let fileNameKey = "myFile.txt"
3guard let filename = FileManager.default.urls(
4 for: .documentDirectory,
5 in: .userDomainMask
6).first?.appendingPathComponent(fileNameKey)
7else { return }
8
9try dataString.write(
10 to: filename,
11 atomically: true,
12 encoding: .utf8
13)
14
15let uploadTask = Amplify.Storage.uploadFile(
16 key: fileNameKey,
17 local: filename
18)
19progressSink = uploadTask
20 .inProcessPublisher
21 .sink { progress in
22 print("Progress: \(progress)")
23 }
24
25resultSink = uploadTask
26 .resultPublisher
27 .sink {
28 if case let .failure(storageError) = $0 {
29 print("Failed: \(storageError.errorDescription). \(storageError.recoverySuggestion)")
30 }
31 }
32 receiveValue: { data in
33 print("Completed: \(data)")
34 }

Working with Security Scoped Resources (from iCloud)

Security scoped resources refer to files that are retrieved from iCloud or other cloud storage providers. You're likely to run into these file types when using system components that provide access to files stored in iCloud, e.g. UIDocumentBrowserViewController.

To upload security scoped resources, you'll need to:

  1. use startAccessingSecurityScopedResource() and stopAccessingSecurityScopedResource() to access the data within security scoped files
  2. temporarily persist the data from the security scoped files in your app's sandbox
  3. upload files using the temporary URLs
  4. delete temporarily persisted files (optional)
1struct ScopedResourceFile {
2 let name: String
3 let data: Data
4}
5
6func getTempUrls(securityScopedUrls: [URL]) -> [URL] {
7 // 1. get the content of security scoped resources into ScopedResourceFile struct
8 let fileContents = securityScopedUrls.compactMap { url -> ScopedResourceFile? in
9 let startAccess = url.startAccessingSecurityScopedResource()
10 guard startAccess else {
11 print("Issue accessing security scoped resource at :\(url)")
12 return nil
13 }
14 defer { url.stopAccessingSecurityScopedResource() }
15 do {
16 let data = try Data(contentsOf: url)
17 let fileName = url.lastPathComponent
18 return ScopedResourceFile(name: fileName, data: data)
19 } catch {
20 print("Couldn't create Data from contents of file at url: \(url)")
21 return nil
22 }
23 }
24
25 // 2. write the file contents to temporary files and return the URLs of the temp files
26 let localFileURLs = persistTemporaryFiles(fileContents)
27
28 // 3. Now you have local URLs for the files you'd like to upload.
29 return localFileURLs
30}

Cancel, Pause, Resume

Calls to uploadData or uploadFile return a reference to the task that is actually performing the upload.

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

1func cancelUpload() {
2 uploadTask.cancel()
3}

You can also pause then resume the task.

1uploadTask.pause()
2uploadTask.resume()

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

MultiPart upload

Amplify will automatically perform a S3 multipart upload for objects that are larger than 5MB. For more information about S3's multipart upload, see Uploading and copying objects using multipart upload