Menu
AWS Mobile
Developer Guide

Add User Data Storage to Your Mobile App with Amazon S3

Overview

Enable your app to store and retrieve user files from cloud storage with the permissions model that suits your purpose. Mobile HubUser Data Storage deploys and configures cloud storage buckets using Amazon Simple Storage Service (Amazon S3).

The User Data Storage feature also uses Amazon Cognito Sync. This service enables your app to sync key/name pair app data, like user profiles, to the cloud and other devices.

Set Up Your Backend

  1. Complete the Get Started steps before your proceed.

    If you want to integrate an Amazon S3 bucket that you have already configured, go to Integrate an Existing Bucket.

  2. Enable User Data Storage: Open your project in Mobile Hub and choose the User Data Storage tile to enable the feature.

  3. When the operation is complete, an alert will pop up saying "Your Backend has been updated", prompting you to download the latest copy of the cloud configuration file. If you're done configuring the feature, choose the banner to return to the project details page.

  4. From the project detail page, every app that needs to be updated with the latest cloud configuration file will have a flashing Integrate button. Choose the button to enter the integrate wizard.

  5. Update your app with the latest copy of the cloud configuration file. Your app now references the latest version of your backend. Choose Next and follow the User Data Storage documentation below to connect to your backend.

Connect to your backend

Make sure to complete the add-aws-mobile-user-sign-in-backend-setup steps before using the integration steps on this page.

To add User Data Storage to your app

Android - JavaiOS - Swift
Android - Java

Set up AWS Mobile SDK components as follows:

  1. Add the following to app/build.gradle:

    dependencies { compile 'com.amazonaws:aws-android-sdk-s3:2.6.+' compile 'com.amazonaws:aws-android-sdk-cognito:2.6.+' }

    Perform a Gradle Sync to download the AWS Mobile SDK components into your app

  2. Add the following to AndroidManifest.xml:

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <application ... > <!- . . . -> <service android:name="com.amazonaws.mobileconnectors.s3.transferutility.TransferService" android:enabled="true" /> <!- . . . -> </application>
  3. For each Activity where you make calls to perform user data storage operations, import the following packages.

    import com.amazonaws.mobile.config.AWSConfiguration; import com.amazonaws.mobileconnectors.s3.transferutility.*;
  4. Add the following code to the onCreate method of your main or startup activity. This will establish a connection with AWS Mobile. AWSMobileClient is a singleton that will be an interface for your AWS services.

    import com.amazonaws.mobile.client.AWSMobileClient; public class YourMainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); AWSMobileClient.getInstance().initialize(this).execute(); } }
iOS - Swift

Set up AWS Mobile SDK components as follows:

  1. Add the following to Podfile that you configure to install the AWS Mobile SDK:

    platform :ios, '9.0' target :'YOUR-APP-NAME' do use_frameworks! pod 'AWSS3', '~> 2.6.6' # For file transfers pod 'AWSCognito', '~> 2.6.6' #For data sync # other pods end Run :code:`pod install --repo-update` before you continue.
  2. Add the following imports to the classes that perform user data storage operations:

    import AWSCore import AWSS3
  3. Add the following code to your AppDelegate to establish a run-time connection with AWS Mobile.

    import UIKit import AWSMobileClient @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { return AWSMobileClient.sharedInstance().interceptApplication(application, didFinishLaunchingWithOptions: launchOptions) } }

Upload a File

Android - JavaiOS - Swift
Android - Java

The following example shows how to upload a file to an Amazon S3 bucket.

Use AWSMobileClient to get the AWSConfiguration and AWSCredentialsProvider, then create the TransferUtility object.

import android.app.Activity; import android.util.Log; import com.amazonaws.mobile.client.AWSMobileClient; import com.amazonaws.mobileconnectors.s3.transferutility.TransferUtility; import com.amazonaws.mobileconnectors.s3.transferutility.TransferState; import com.amazonaws.mobileconnectors.s3.transferutility.TransferObserver; import com.amazonaws.mobileconnectors.s3.transferutility.TransferListener; import com.amazonaws.services.s3.AmazonS3Client; import java.io.File; public class YourActivity extends Activity { public void uploadData() { // Initialize AWSMobileClient if not initialized upon the app startup. // AWSMobileClient.getInstance().initialize(this).execute(); TransferUtility transferUtility = TransferUtility.builder() .context(getApplicationContext()) .awsConfiguration(AWSMobileClient.getInstance().getConfiguration()) .s3Client(new AmazonS3Client(AWSMobileClient.getInstance().getCredentialsProvider())) .build(); TransferObserver uploadObserver = transferUtility.upload( "s3Folder/s3Key.txt", new File("/path/to/file/localFile.txt")); uploadObserver.setTransferListener(new TransferListener() { @Override public void onStateChanged(int id, TransferState state) { if (TransferState.COMPLETED == state) { // Handle a completed upload. } } @Override public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) { float percentDonef = ((float)bytesCurrent/(float)bytesTotal) * 100; int percentDone = (int)percentDonef; Log.d("MainActivity", " ID:" + id + " bytesCurrent: " + bytesCurrent + " bytesTotal: " + bytesTotal + " " + percentDone + "%"); } @Override public void onError(int id, Exception ex) { // Handle errors } }); // If your upload does not trigger the onStateChanged method inside your // TransferListener, you can directly check the transfer state as shown here. if (TransferState.COMPLETED == uploadObserver.getState()) { // Handle a completed upload. } } }
iOS - Swift

The following example shows how to upload a file to an Amazon S3 bucket.

func uploadData() { let data: Data = Data() // Data to be uploaded let expression = AWSS3TransferUtilityUploadExpression() expression.progressBlock = {(task, progress) in DispatchQueue.main.async(execute: { // Do something e.g. Update a progress bar. }) } var completionHandler: AWSS3TransferUtilityUploadCompletionHandlerBlock? completionHandler = { (task, error) -> Void in DispatchQueue.main.async(execute: { // Do something e.g. Alert a user for transfer completion. // On failed uploads, `error` contains the error object. }) } let transferUtility = AWSS3TransferUtility.default() transferUtility.uploadData(data, bucket: "YourBucket", key: "YourFileName", contentType: "text/plain", expression: expression, completionHandler: completionHandler).continueWith { (task) -> AnyObject! in if let error = task.error { print("Error: \(error.localizedDescription)") } if let _ = task.result { // Do something with uploadTask. } return nil; } }

Download a File

Android - JavaiOS - Swift
Android - Java

The following example shows how to download a file from an Amazon S3 bucket. We use AWSMobileClient to get the AWSConfiguration and AWSCredentialsProvider to create the TransferUtility object.

import android.app.Activity; import android.util.Log; import com.amazonaws.mobile.client.AWSMobileClient; import com.amazonaws.mobileconnectors.s3.transferutility.TransferUtility; import com.amazonaws.mobileconnectors.s3.transferutility.TransferState; import com.amazonaws.mobileconnectors.s3.transferutility.TransferObserver; import com.amazonaws.mobileconnectors.s3.transferutility.TransferListener; import com.amazonaws.services.s3.AmazonS3Client; import java.io.File; public class YourActivity extends Activity { public void downloadData() { // Initialize AWSMobileClient if not initialized upon the app startup. // AWSMobileClient.getInstance().initialize(this).execute(); TransferUtility transferUtility = TransferUtility.builder() .context(getApplicationContext()) .awsConfiguration(AWSMobileClient.getInstance().getConfiguration()) .s3Client(new AmazonS3Client(AWSMobileClient.getInstance().getCredentialsProvider())) .build(); TransferObserver downloadObserver = transferUtility.download( "s3Folder/s3Key.txt", new File("/path/to/file/localFile.txt")); downloadObserver.setTransferListener(new TransferListener() { @Override public void onStateChanged(int id, TransferState state) { if (TransferState.COMPLETED == state) { // Handle a completed upload. } } @Override public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) { float percentDonef = ((float)bytesCurrent/(float)bytesTotal) * 100; int percentDone = (int)percentDonef; Log.d("MainActivity", " ID:" + id + " bytesCurrent: " + bytesCurrent + " bytesTotal: " + bytesTotal + " " + percentDone + "%"); } @Override public void onError(int id, Exception ex) { // Handle errors } }); } }
iOS - Swift

The following example shows how to download a file from an Amazon S3 bucket.

func downloadData() { let expression = AWSS3TransferUtilityDownloadExpression() expression.progressBlock = {(task, progress) in DispatchQueue.main.async(execute: { // Do something e.g. Update a progress bar. }) } var completionHandler: AWSS3TransferUtilityDownloadCompletionHandlerBlock? completionHandler = { (task, URL, data, error) -> Void in DispatchQueue.main.async(execute: { // Do something e.g. Alert a user for transfer completion. // On failed downloads, `error` contains the error object. }) } let transferUtility = AWSS3TransferUtility.default() transferUtility.downloadData( fromBucket: "YourBucket", key: "YourFileName", expression: expression, completionHandler: completionHandler ).continueWith { (task) -> AnyObject! in if let error = task.error { print("Error: \(error.localizedDescription)") } if let _ = task.result { // Do something with downloadTask. } return nil; } }

Save User Profile Data

The following shows how to load user settings and access those settings using Amazon Cognito Sync.

Android - JavaiOS - Swift
Android - Java
import java.util.List; import com.amazonaws.auth.CognitoCachingCredentialsProvider; import com.amazonaws.mobileconnectors.cognito.CognitoSyncManager; import com.amazonaws.mobileconnectors.cognito.Dataset; import com.amazonaws.mobileconnectors.cognito.exceptions.DataStorageException; import com.amazonaws.auth.CognitoCachingCredentialsProvider; public void saveProfileData() { CognitoSyncManager manager = new CognitoSyncManager(getApplicationContext(), (CognitoCachingCredentialsProvider)AWSMobileClient.getInstance().getCredentialsProvider(), AWSMobileClient.getInstance().getConfiguration()); Dataset dataset = manager.openOrCreateDataset("myDataset"); dataset.put("myKey", "myValue"); // synchronize dataset with the Cloud dataset.synchronize(new Dataset.SyncCallback() { public void onSuccess(Dataset dataset, List list) { } public boolean onConflict(Dataset dataset, List list) { return false; } public boolean onDatasetDeleted(Dataset dataset, String list) { return true; } public boolean onDatasetsMerged(Dataset dataset, List list) { return true; } public void onFailure(DataStorageException exception) { } }); }
iOS - Swift
import AWSCore import AWSCognito func loadSettings() { let syncClient: AWSCognito = AWSCognito.default() let userSettings: AWSCognitoDataset = syncClient.openOrCreateDataset("user_settings") userSettings.synchronize().continueWith { (task: AWSTask<AnyObject>) -> Any? in if let error = task.error as NSError? { print("loadSettings error: \(error.localizedDescription)") return nil; } let titleTextColorString = userSettings.string(forKey: "titleTextColorStringKey") let titleBarColorString = userSettings.string(forKey: "titleBarColorStringKey") let backgroundColorString = userSettings.string(forKey: "backgroundColorStringKey") return nil; } }

Next Steps