Set up Storage
In this guide, you will learn how to set up storage in your Amplify app. You will set up your backend resources, and enable listing, uploading, and downloading files.
If you have not yet created an Amplify app, visit the quickstart guide.
Amplify Storage seamlessly integrates file storage and management capabilities into frontend web and mobile apps, built on top of Amazon Simple Storage Service (Amazon S3). It provides intuitive APIs and UI components for core file operations, enabling developers to build scalable and secure file storage solutions without dealing with cloud service complexities.
Building your storage backend
First, create a file amplify/storage/resource.ts
. This file will be the location where you configure your storage backend. Instantiate storage using the defineStorage
function and providing a name
for your storage bucket. This name
is a friendly name to identify your bucket in your backend configuration. Amplify will generate a unique identifier for your app using a UUID, the name attribute is just for use in your app.
import { defineStorage } from '@aws-amplify/backend';
export const storage = defineStorage({ name: 'amplifyTeamDrive'});
Import your storage definition in your amplify/backend.ts
file that contains your backend definition. Add storage to defineBackend
.
import { defineBackend } from '@aws-amplify/backend';import { auth } from './auth/resource';import { storage } from './storage/resource';
defineBackend({ auth, storage});
Now when you run npx ampx sandbox
or deploy your app on Amplify, it will configure an Amazon S3 bucket where your files will be stored. Before files can be accessed in your application, you must configure storage access rules.
To deploy these changes, commit them to git and push the changes upstream. Amplify's CI/CD system will automatically pick up the changes and build and deploy the updates.
git commit -am "add storage backend"git push
Define File Path Access
By default, no users or other project resources have access to any files in the storage bucket. Access must be explicitly granted within defineStorage
using the access
callback.
The access callback returns an object where each key in the object is a file path and each value in the object is an array of access rules that apply to that path.
The following example shows you how you can set up your file storage structure for a generic photo sharing app. Here,
- Guests have access to see all profile pictures and only the users that uploaded the profile picture can replace or delete them. Users are identified by their Identity Pool ID in this case i.e. identityID.
- There's also a general pool where all users can submit pictures.
Learn more about customizing access to file path.
export const storage = defineStorage({ name: 'amplifyTeamDrive', access: (allow) => ({ 'profile-pictures/{entity_id}/*': [ allow.guest.to(['read']), allow.entity('identity').to(['read', 'write', 'delete']) ], 'picture-submissions/*': [ allow.authenticated.to(['read','write']), allow.guest.to(['read', 'write']) ], })});
Configure additional storage buckets
Amplify Storage gives you the flexibility to configure your backend to automatically provision and manage multiple storage resources.
You can define additional storage buckets by using the same defineStorage
function and providing a unique, descriptive name
to identify the storage bucket. You can pass this name
to the storage APIs to specify the bucket you want to perform the action to. Ensure that this name
attribute is unique across the defined storage buckets in order to reliably identify the correct bucket and prevent conflicts.
It's important to note that if additional storage buckets are defined one of them must be marked as default with the isDefault
flag.
export const firstBucket = defineStorage({ name: 'firstBucket', isDefault: true, // identify your default storage bucket (required)});
export const secondBucket = defineStorage({ name: 'secondBucket', access: (allow) => ({ 'private/{entity_id}/*': [ allow.entity('identity').to(['read', 'write', 'delete']) ] })})
Add additional storage resources to the backend definition.
import { defineBackend } from '@aws-amplify/backend';import { auth } from './auth/resource';import { firstBucket, secondBucket } from './storage/resource';
defineBackend({ auth, firstBucket, secondBucket});
Storage bucket client usage
Additional storage buckets can be referenced from application code by passing the bucket
option to Amplify Storage APIs. You can provide a target bucket's name assigned in Amplify Backend.
let downloadTask = Amplify.Storage.downloadData( path: .fromString("public/example/path"), options: .init( bucket: .fromOutputs(name: "secondBucket") ))
Alternatively, you can also directly specify the bucket name and region from the console. See each Amplify Storage API page for additional usage examples.
let downloadTask = Amplify.Storage.downloadData( path: .fromString("public/example/path"), options: .init( bucket: .fromBucketInfo(.init( bucketName: "another-bucket-name", region: "another-bucket-region") ) ))
Connect your app code to the storage backend
The Amplify Storage library provides client APIs that connect to the backend resources you defined.
Prerequisites
An application with Amplify libraries integrated and a minimum target of any of the following:
- iOS 13.0, using Xcode 14.1 or later.
- macOS 10.15, using Xcode 14.1 or later.
- tvOS 13.0, using Xcode 14.3 or later.
- watchOS 9.0, using Xcode 14.3 or later.
- visionOS 1.0, using Xcode 15 beta 2 or later. (Preview support - see below for more details.)
For a full example, please follow the project setup walkthrough.
Install Amplify library via Swift Package Manager
-
To install Amplify Libraries in your application, open your project in Xcode and select File > Add Packages....
-
Enter the Amplify Library for Swift GitHub repo URL (
https://github.com/aws-amplify/amplify-swift
) into the search bar and click Add Package.
- Lastly, choose AWSS3StoragePlugin, AWSCognitoAuthPlugin, and Amplify. Then click Add Package.
Configure Amplify in project
Initialize the Amplify Storage category by calling Amplify.add(plugin:)
. To complete initialization call Amplify.configure()
.
Add the following imports to the top of your App
scene and configure Amplify in the init
:
import Amplifyimport AWSCognitoAuthPluginimport AWSS3StoragePlugin
@mainstruct MyAmplifyApp: App { var body: some Scene { WindowGroup { ContentView() } }
init() { do { try Amplify.add(plugin: AWSCognitoAuthPlugin()) try Amplify.add(plugin: AWSS3StoragePlugin()) try Amplify.configure(with: .amplifyOutputs) print("Amplify configured with Auth and Storage plugins") } catch { print("Failed to initialize Amplify with \(error)") } }}
Add the following imports to the top of your AppDelegate.swift
file:
import Amplifyimport AWSCognitoAuthPluginimport AWSS3StoragePlugin
Add the following code to the application:didFinishLaunchingWithOptions
method:
func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { do { try Amplify.add(plugin: AWSCognitoAuthPlugin()) try Amplify.add(plugin: AWSS3StoragePlugin()) try Amplify.configure(with: .amplifyOutputs) print("Amplify configured with Auth and Storage plugins") } catch { print("Failed to initialize Amplify with \(error)") }
return true}
Upon building and running this application you should see the following in your console window:
Amplify configured with Auth and Storage plugins
Upload your first file
Next, let's a photo to the picture-submissions/
path.
import Amplifyimport SwiftUIimport PhotosUI
struct ContentView: View { @State private var selectedPhoto: PhotosPickerItem? @State private var image: Image?
var body: some View { NavigationStack { VStack { image? .resizable() .scaledToFit() } .padding() PhotosPicker( selection: $selectedPhoto ) { Text("Select a photo to upload") } .task(id: selectedPhoto) { if let imageData = try? await selectedPhoto?.loadTransferable(type: Data.self) { if let uiImage = UIImage(data: imageData) { image = Image(uiImage: uiImage) } let uploadTask = Amplify.Storage.uploadData( path: .fromString("picture-submissions/myPhoto.png"), data: imageData ) } } } }}
Manage files in Amplify console
After successfully publishing your storage backend and connecting your project with client APIs, you can manage files and folders in the Amplify console. You can perform on-demand actions like upload, download, copy, and more under the Storage tab in the console. Refer to Manage files in Amplify Console guide for additional information.
Conclusion
Congratulations! You finished the Set up Amplify Storage guide. In this guide, you set up and connected to backend resources, customized your file paths and access definitions, and connected your application to the backend to implement features like file uploads and downloads.
Next steps
Now that you have completed setting up storage in your Amplify app, you can proceed to add file management features to your app. You can use the following guides to implement upload and download functionality, or you can access more capabilities from the side navigation.