diff --git a/android/add-aws-mobile-user-sign-in-customize.md b/android/add-aws-mobile-user-sign-in-customize.md
new file mode 100755
index 00000000000..e1c74f730a2
--- /dev/null
+++ b/android/add-aws-mobile-user-sign-in-customize.md
@@ -0,0 +1,115 @@
+# Customize the SDK Sign-In UI
+
+By default, the SDK presents sign-in UI for each sign in provider you enable in your Mobile Hub project (Email and Password, Facebook, Google) with a default look and feel. It knows which provider(s) you chose by reading the :file:`awsconfiguration.json` file you integrated with your app.
+
+To override the defaults, and modify the behavior, look, and feel of the sign-in UI, create an `AuthUIConfiguration` object and set the appropriate properties.
+
+Android - Java
+
+Create and configure an `AuthUIConfiguration` object and set its properties.
+
+* To present the Email and Password user `SignInUI`, set `userPools` to `true`.
+
+* To present Facebook or Google user `SignInUI`, add `signInButton(FacebookButton.class)` or `signInButton(GoogleButton.class)`.
+
+* To change the logo, use the `logoResId`.
+
+* To change the background color, use `backgroundColor`.
+
+* To cancel the sign-in flow, set `.canCancel(true)`.
+
+* To change the font in the sign-in views, use the `fontFamily` method and pass in the string that represents a font family.
+
+* To draw the `backgroundColor` full screen, use `fullScreenBackgroundColor`.
+
+```java
+ import android.app.Activity;
+ import android.graphics.Color;
+ import android.os.Bundle;
+
+ import com.amazonaws.mobile.auth.facebook.FacebookButton;
+ import com.amazonaws.mobile.auth.google.GoogleButton;
+ import com.amazonaws.mobile.auth.ui.AuthUIConfiguration;
+ import com.amazonaws.mobile.auth.ui.SignInUI;
+
+ import com.amazonaws.mobile.client.AWSMobileClient;
+ import com.amazonaws.mobile.client.AWSStartupHandler;
+ import com.amazonaws.mobile.client.AWSStartupResult;
+
+ public class YourMainActivity extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ AWSMobileClient.getInstance().initialize(this, new AWSStartupHandler() {
+ @Override
+ public void onComplete(final AWSStartupResult awsStartupResult) {
+ AuthUIConfiguration config =
+ new AuthUIConfiguration.Builder()
+ .userPools(true) // true? show the Email and Password UI
+ .signInButton(FacebookButton.class) // Show Facebook button
+ .signInButton(GoogleButton.class) // Show Google button
+ .logoResId(R.drawable.mylogo) // Change the logo
+ .backgroundColor(Color.BLUE) // Change the backgroundColor
+ .isBackgroundColorFullScreen(true) // Full screen backgroundColor the backgroundColor full screenff
+ .fontFamily("sans-serif-light") // Apply sans-serif-light as the global font
+ .canCancel(true)
+ .build();
+ SignInUI signinUI = (SignInUI) AWSMobileClient.getInstance().getClient(YourMainActivity.this, SignInUI.class);
+ signinUI.login(YourMainActivity.this, YourNextActivity.class).authUIConfiguration(config).execute();
+ }
+ }).execute();
+ }
+ }
+```
+Android - Kotlin
+Create and configure an `AuthUIConfiguration` object and set its properties.
+
+* To present the Email and Password user `SignInUI`, set `userPools` to `true`.
+
+* To present Facebook or Google user `SignInUI`, add `signInButton(FacebookButton.class)` or `signInButton(GoogleButton.class)`.
+
+* To change the logo, use the `logoResId`.
+
+* To change the background color, use `backgroundColor`.
+
+* To cancel the sign-in flow, set `.canCancel(true)`.
+
+* To change the font in the sign-in views, use the `fontFamily` method and pass in the string that represents a font family.
+
+* To draw the `backgroundColor` full screen, use `fullScreenBackgroundColor`.
+
+```java
+ import android.app.Activity;
+ import android.graphics.Color;
+ import android.os.Bundle;
+
+ import com.amazonaws.mobile.auth.facebook.FacebookButton;
+ import com.amazonaws.mobile.auth.google.GoogleButton;
+ import com.amazonaws.mobile.auth.ui.AuthUIConfiguration;
+ import com.amazonaws.mobile.auth.ui.SignInUI;
+
+ import com.amazonaws.mobile.client.AWSMobileClient;
+ import com.amazonaws.mobile.client.AWSStartupHandler;
+ import com.amazonaws.mobile.client.AWSStartupResult;
+
+ class MainActivity : AppCompatActivity() {
+ override fun onCreate(savedInstanceState : Bundle?) {
+ super.onCreate()
+ AWSMobileClient.getInstance().initialize(this) {
+ val config = AuthUIConfiguration.Builder()
+ .userPools(true) // show the Email and Password UI
+ .signInButton(FacebookButton.class) // Show Facebook
+ .signInButton(GoogleButton.class) // Show Google
+ .logoResId(R.drawable.mylogo) // Change the logo
+ .backgroundColor(Color.BLUE) // Change the background color
+ .isBackgroundColorFullScreen(true) // Full screen background color
+ .fontFamily("sans-serif-light") // font
+ .canCancel(true) // Add a cancel/back button
+ .build()
+ val signInUI = AWSMobileClient.getInstance().getClient(this@MainActivity, SignInUI::class.java) as SignInUI
+ signInUI.login(this@MainActivity, NextActivity::class.java).authUIConfiguration(config).execute()
+ }.execute()
+ }
+ }
+```
diff --git a/android/analytics.md b/android/analytics.md
new file mode 100755
index 00000000000..8c9e81d836b
--- /dev/null
+++ b/android/analytics.md
@@ -0,0 +1,197 @@
+# Add Analytics to Your Mobile App with Amazon Pinpoint
+
+## Pinpoint
+
+Gather the data that helps improve your app's usability, monetization, and engagement with your users. The CLI deploys your analytics backend using [Amazon Pinpoint](http://docs.aws.amazon.com/pinpoint/latest/developerguide/welcome.html).
+
+### Set Up Your Backend
+
+1. Complete the [Get Started TODO link](asdf) steps before you proceed.
+
+2. Use the CLI to add analytics to your cloud-enabled backend and app.
+
+ In a terminal window, navigate to your project folder (the folder that typically contains your project level `build.gradle`), and add the SDK to your app.
+
+ ```bash
+ $ cd ./YOUR_PROJECT_FOLDER
+ $ amplify add analytics
+ ```
+
+ In a terminal window, navigate to your project folder (the folder contains your app :file:`.xcodeproj` file), and add the SDK to your app.
+
+ ```bash
+ $ cd ./YOUR_PROJECT_FOLDER
+ $ amplify add analytics
+ ```
+
+3. When configuration for analytics is complete, a message appears confirming that you have configured local CLI metadata for this category. You can confirm this by viewing status.
+
+ ```bash
+ $ amplify status
+ | Category | Resource name | Operation | Provider plugin |
+ | --------- | --------------- | --------- | ----------------- |
+ | Auth | cognitoabcd0123 | Create | awscloudformation |
+ | Analytics | yourprojectname | Create | awscloudformation |
+ ```
+
+4. To create your backend AWS resources run the following:
+
+ ```bash
+ $ amplify push
+ ```
+
+### Connect to Your Backend
+
+Use the following steps to add analytics to your mobile app and monitor the results through Amazon Pinpoint.
+
+#### Add Analytics
+
+1. Set up AWS Mobile SDK components by including the following libraries in your `app/build.gradle` dependencies list.
+
+ ```groovy
+ dependencies {
+ implementation 'com.amazonaws:aws-android-sdk-pinpoint:2.6.+'
+ implementation ('com.amazonaws:aws-android-sdk-mobile-client:2.6.+@aar') { transitive = true }
+ }
+ ```
+
+ * `aws-android-sdk-pinpoint` library enables sending analytics to Amazon Pinpoint.
+ * `aws-android-sdk-mobile-client` library gives access to the AWS credentials provider and configurations.
+
+2. Add required permissions to your app manifest.
+
+ The AWS Mobile SDK requires the `INTERNET` and `ACCESS_NETWORK_STATE` permissions. These are defined in the `AndroidManifest.xml` file.
+
+ ```xml
+
+
+ ```
+
+3. Add calls to capture session starts and stops. A session is one use of an app by the user. A session begins when an app is launched (or brought to the foreground), and ends when the app is terminated (or goes to the background). To accommodate for brief interruptions, like a text message, an inactivity period of up to 5 seconds is not counted as a new session. :guilabel:`Total daily sessions` shows the number of sessions your app has each day. :guilabel:`Average sessions per daily active user` shows the mean number of sessions per user per day.
+
+ The following are typical places where you can instrument your app session start and stop:
+
+ * Start a session in the :code:`Application.onCreate()` method.
+
+ * Start a session in the :code:`onCreate()` method of the app's first activity.
+
+ * Start or stop a session in the `ActivityLifecycleCallbacks `__ class.
+
+ The following example shows how to start a session in the :code:`OnCreate` event of :code:`MainActivity`.
+
+ ```java
+ import android.support.v7.app.AppCompatActivity;
+ import android.os.Bundle;
+
+ import com.amazonaws.mobileconnectors.pinpoint.PinpointManager;
+ import com.amazonaws.mobileconnectors.pinpoint.PinpointConfiguration;
+ import com.amazonaws.mobile.client.AWSMobileClient;
+
+ public class MainActivity extends AppCompatActivity {
+ private static final String TAG = MainActivity.class.getSimpleName();
+
+ public static PinpointManager pinpointManager;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ // Initialize the AWS Mobile Client
+ AWSMobileClient.getInstance().initialize(this, new AWSStartupHandler() {
+ @Override
+ public void onComplete(AWSStartupResult awsStartupResult) {
+ Log.d(TAG, "AWSMobileClient is instantiated and you are connected to AWS!");
+ }
+ }).execute();
+
+ PinpointConfiguration config = new PinpointConfiguration(
+ MainActivity.this,
+ AWSMobileClient.getInstance().getCredentialsProvider(),
+ AWSMobileClient.getInstance().getConfiguration()
+ );
+ pinpointManager = new PinpointManager(config);
+ pinpointManager.getSessionClient().startSession();
+ }
+ }
+ ```
+
+ To stop the session, use :code:`stopSession()` and :code:`submitEvents()` at the last point in the session you want to capture. In this example, we are using a single Activity, so the session will stop when the MainActivity is destroyed. :code:`onDestroy()` is usually called when the back button is pressed while in the activity.
+
+ ```java
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+
+ pinpointManager.getSessionClient().stopSession();
+ pinpointManager.getAnalyticsClient().submitEvents();
+ }
+ ```
+
+#### Monitor Analytics
+
+Build and run your app to see usage metrics in Amazon Pinpoint. When you run the previous code samples, the console shows a logged Session.
+
+1. To see visualizations of the analytics coming from your app, open your project in the Amazon Pinpoint console by running the following:
+
+ ```bash
+ $ amplify console analytics
+ ```
+
+2. Choose `Analytics` from the icons on the left of the console, and view the graphs of your app's usage. It may take up to 15 minutes for metrics to become visible.
+
+ 
+
+ [Learn more about Amazon Pinpoint](http://docs.aws.amazon.com/pinpoint/latest/developerguide/welcome.html).
+
+### Enable Custom App Analytics
+
+Instrument your code to capture app usage event information, including attributes you define. Use graphs of your custom usage event data in the Amazon Pinpoint console. Visualize how your users' behavior aligns with a model you design using [Amazon Pinpoint Funnel Analytics](https://docs.aws.amazon.com/pinpoint/latest/userguide/analytics-funnels.html), or use [stream the data](https://docs.aws.amazon.com/pinpoint/latest/userguide/analytics-streaming.html) for deeper analysis.
+
+Use the following steps to implement Amazon Pinpoint custom analytics for your app.
+
+```java
+import com.amazonaws.mobileconnectors.pinpoint.analytics.AnalyticsEvent;
+
+/**
+* Call this method to log a custom event to the analytics client.
+*/
+public void logEvent() {
+ final AnalyticsEvent event =
+ pinpointManager.getAnalyticsClient().createEvent("EventName")
+ .withAttribute("DemoAttribute1", "DemoAttributeValue1")
+ .withAttribute("DemoAttribute2", "DemoAttributeValue2")
+ .withMetric("DemoMetric1", Math.random());
+
+ pinpointManager.getAnalyticsClient().recordEvent(event);
+}
+```
+
+Build, run, and use your app. Then, view your custom events on the `Events` tab of the Amazon Pinpoint console (choose `Analytics`>`Events`). Look for the name of your event in the `Events` menu.
+
+### Enable Revenue Analytics
+
+Amazon Pinpoint supports the collection of monetization event data. Use the following steps to place
+and design analytics related to purchases through your app.
+
+```java
+import com.amazonaws.mobileconnectors.pinpoint.analytics.monetization.AmazonMonetizationEventBuilder;
+
+/**
+* Call this method to log a monetized event to the analytics client.
+*/
+public void logMonetizationEvent() {
+ final AnalyticsEvent event =
+ AmazonMonetizationEventBuilder.create(pinpointManager.getAnalyticsClient())
+ .withCurrency("USD")
+ .withItemPrice(10.00)
+ .withProductId("DEMO_PRODUCT_ID")
+ .withQuantity(1.0)
+ .withProductId("DEMO_TRANSACTION_ID").build();
+
+ pinpointManager.getAnalyticsClient().recordEvent(event);
+}
+```
+
+## Kinesis
+
diff --git a/android/api-apigw.md b/android/api-apigw.md
new file mode 100755
index 00000000000..b74d38a46c0
--- /dev/null
+++ b/android/api-apigw.md
@@ -0,0 +1,188 @@
+# Add Cloud APIs to Your Mobile App with Amazon API Gateway and AWS Lambda
+
+# Overview
+
+Add RESTful APIs handled by your serverless |LAM| functions. The CLI deploys your APIs and handlers using [Amazon API Gateway](http://docs.aws.amazon.com/apigateway/latest/developerguide/) and [AWS Lambda](http://docs.aws.amazon.com/lambda/latest/dg/).
+
+## Set Up Your Backend
+
+1. Complete the [Get Started](./get-started) steps before you proceed.
+
+2. Use the CLI to add api to your cloud-enabled backend and app.
+
+ In a terminal window, navigate to your project folder (the folder that typically contains your project level `build.gradle`), and add the SDK to your app. Note that the friendly name that specified for the `api` category will be the package name of the generated code.
+
+ ```bash
+ $ cd ./YOUR_PROJECT_FOLDER
+ $ amplify add api
+ ```
+
+3. Choose `> REST` as your API service.
+
+4. Choose `> Create a new Lambda function`.
+
+5. Choose the `> Serverless express function` template.
+
+6. Restrict API access? Choose `Yes`
+
+7. Who should have access? Choose `Authenticated and Guest users`
+
+8. When configuration of your API is complete, the CLI displays a message confirming that you have configured local CLI metadata for this category. You can confirm this by viewing status.
+
+ ```bash
+ $ amplify status
+ | Category | Resource name | Operation | Provider plugin |
+ | --------- | --------------- | --------- | ----------------- |
+ | Function | lambda01234567 | Create | awscloudformation |
+ | Api | api012345678 | Create | awscloudformation |
+ ```
+
+9. To create your backend AWS resources run:
+
+ ```bash
+ $ amplify push
+ ```
+
+ Use the steps in the next section to connect your app to your backend.
+
+## Connect to Your Backend
+
+Use the following steps to add Cloud Logic to your app.
+
+1. Add the following to your `app/build.gradle`:
+
+ ```groovy
+ dependencies {
+ implementation 'com.amazonaws:aws-android-sdk-apigateway-core:2.6.+'
+ implementation ('com.amazonaws:aws-android-sdk-mobile-client:2.6.+@aar') { transitive = true }
+ implementation ('com.amazonaws:aws-android-sdk-auth-userpools:2.6.+@aar') { transitive = true }
+ }
+ ```
+
+2. Get your API client name.
+
+ The CLI generates a client code file for each API you add. The API client name is the name of that file, without the extension.
+
+ The path of the client code file is `./src/main/java/YOUR_API_RESOURCE_NAME/YOUR_APP_NAME_XXXXClient.java`.
+
+ So, for an app named `useamplify` with an API resource named `xyz123`, the path of the code file will be `./src/main/java/xyz123/useamplifyabcdClient.java`. The API client name will be `useamplifyabcdClient`.
+
+ - Find the resource name of your API by running `amplify status`.
+ - Copy your API client name to use when invoking the API in the following step.
+
+3. Invoke a Cloud Logic API.
+
+ The following code shows how to invoke a Cloud Logic API using your API's client class,
+ model, and resource paths.
+
+ ```java
+ import android.support.v7.app.AppCompatActivity;
+ import android.os.Bundle;
+ import android.util.Log;
+
+ import com.amazonaws.http.HttpMethodName;
+ import com.amazonaws.mobile.client.AWSMobileClient;
+ import com.amazonaws.mobile.client.AWSStartupHandler;
+ import com.amazonaws.mobile.client.AWSStartupResult;
+ import com.amazonaws.mobileconnectors.apigateway.ApiClientFactory;
+ import com.amazonaws.mobileconnectors.apigateway.ApiRequest;
+ import com.amazonaws.mobileconnectors.apigateway.ApiResponse;
+ import com.amazonaws.util.IOUtils;
+ import com.amazonaws.util.StringUtils;
+
+ import java.io.InputStream;
+ import java.util.HashMap;
+ import java.util.Map;
+
+ // TODO Replace this with your api friendly name and client class name
+ import YOUR_API_RESOURCE_NAME.YOUR_APP_NAME_XXXXClient;
+
+ public class MainActivity extends AppCompatActivity {
+ private static final String TAG = MainActivity.class.getSimpleName();
+
+ // TODO Replace this with your client class name
+ private YOUR_APP_NAME_XXXXClient apiClient;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ // Initialize the AWS Mobile Client
+ AWSMobileClient.getInstance().initialize(this, new AWSStartupHandler() {
+ @Override
+ public void onComplete(AWSStartupResult awsStartupResult) {
+ Log.d(TAG, "AWSMobileClient is instantiated and you are connected to AWS!");
+ }
+ }).execute();
+
+
+ // Create the client
+ apiClient = new ApiClientFactory()
+ .credentialsProvider(AWSMobileClient.getInstance().getCredentialsProvider())
+ .build(YOUR_API_CLIENT_NAME.class);
+
+ callCloudLogic();
+ }
+
+ public void callCloudLogic() {
+ // Create components of api request
+ final String method = "GET";
+ final String path = "/items";
+
+ final String body = "";
+ final byte[] content = body.getBytes(StringUtils.UTF8);
+
+ final Map parameters = new HashMap<>();
+ parameters.put("lang", "en_US");
+
+ final Map headers = new HashMap<>();
+
+ // Use components to create the api request
+ ApiRequest localRequest =
+ new ApiRequest(apiClient.getClass().getSimpleName())
+ .withPath(path)
+ .withHttpMethod(HttpMethodName.valueOf(method))
+ .withHeaders(headers)
+ .addHeader("Content-Type", "application/json")
+ .withParameters(parameters);
+
+ // Only set body if it has content.
+ if (body.length() > 0) {
+ localRequest = localRequest
+ .addHeader("Content-Length", String.valueOf(content.length))
+ .withBody(content);
+ }
+
+ final ApiRequest request = localRequest;
+
+ // Make network call on background thread
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ Log.d(TAG,
+ "Invoking API w/ Request : " +
+ request.getHttpMethod() + ":" +
+ request.getPath());
+
+ final ApiResponse response = apiClient.execute(request);
+
+ final InputStream responseContentStream = response.getContent();
+
+ if (responseContentStream != null) {
+ final String responseData = IOUtils.toString(responseContentStream);
+ Log.d(TAG, "Response : " + responseData);
+ }
+
+ Log.d(TAG, response.getStatusCode() + " " + response.getStatusText());
+
+ } catch (final Exception exception) {
+ Log.e(TAG, exception.getMessage(), exception);
+ exception.printStackTrace();
+ }
+ }
+ }).start();
+ }
+ }
+ ```
diff --git a/android/auth-facebook-setup.md b/android/auth-facebook-setup.md
new file mode 100755
index 00000000000..dac5a360e3c
--- /dev/null
+++ b/android/auth-facebook-setup.md
@@ -0,0 +1,92 @@
+# Set Up Facebook Authentication
+
+To use the following Facebook service configuration steps to federate Facebook as a user sign-in provider for AWS services called in your app, try the AWS Amplify `User Sign-in feature `.
+
+You must first register your application with Facebook by using the [Facebook Developers portal] (https://developers.facebook.com/).
+
+AWS Amplify generates code that enables you to use Facebook to provide federated authentication for your mobile app users. This topic explains how to set up Facebook as an identity provider for your app.
+
+If you already have a Facebook app ID, copy and paste it into the `Facebook App ID` field
+when configuring authentication using the AWS Amplify CLI.
+
+**To get a Facebook app ID**
+
+1. In the [Facebook Developers portal] (https://developers.facebook.com/), sign in with your
+ Facebook credentials.
+
+2. From `Create App`, choose `Add a New App` (note: this menu label will be
+ `My Apps` if you have previously created an app.
+
+
+
+3. If asked, choose the platform of your app that will use Facebook sign-in, and `basic
+ setup`.
+
+4. Type a display name for your app, select a category for your app from the `Category`
+ drop-down list, and then choose `Create App ID`.
+
+
+
+
+5. Complete the `Security Check` that appears. Your new app then appears in the
+ `Dashboard`.
+
+
+
+6. Copy the App ID and paste it into the `Facebook App ID` field in the Mobile Hub console.
+
+
+
+7. In the Facebook Developer portal's left hand navigation list, choose `Settings`, then
+ choose `+ Add Platform`.
+
+
+
+8. Choose your platform and provide information about your app that Facebook will use for
+ integration during credential validation.
+
+ `For Android:`
+
+ 1. Provide your app's `Google Play Package Name`. (ie. :code:`com.yourprojectname`).
+
+ 2. Provide your `Class Name` that handles deep links (ie.
+ :code:`com.yourprojectname.MainActivity`).
+
+
+
+ 3. Provide your app's Facebook development `Key Hashes`. This is a value that you
+ generate via a terminal in your development environment, and is unique to that environment.
+
+ To generate a development key for your Android environment on Mac, run the following command
+ line.
+
+ ```bash
+ keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 -binary | openssl base64
+ ```
+
+ To generate a development key for your Android environment on Windows, run the following
+ command line.
+
+ ```bash
+ keytool -exportcert -alias androiddebugkey -keystore %HOMEPATH%\.android\debug.keystore | openssl sha1 -binary | openssl base64
+ ```
+
+ For more information, choose the `Quick Start` button in the upper left of the
+ Facebook Developer Portal Add Platform dialog.
+
+9. In the Facebook Developers portal, choose `Save changes`, then `Use this
+ package name` if a dialog appears saying that Google Play has an issue with your package name.
+
+10. Only users with roles assigned in the Facebook portal will be able to authenticate through your
+ app while it is in development (not yet published).
+
+ To authorize users, in the Facebook Developer portal's left hand navigation list, choose
+ `Roles`, then `Add Testers`. Provide a valid Facebook ID.
+
+
+
+
+11. In the Mobile Hub console, choose `Save changes`.
+
+For more information about integrating with Facebook Login, see the [Facebook Getting Started Guide]
+(https://developers.facebook.com/docs/facebook-login).
diff --git a/android/auth-google-setup.md b/android/auth-google-setup.md
new file mode 100755
index 00000000000..4ca571f906e
--- /dev/null
+++ b/android/auth-google-setup.md
@@ -0,0 +1,13 @@
+# Set Up Google Authentication
+
+To use the following Google service configuration steps to federate Google as a user sign-in provider for AWS services called in your app, try the AWS Amplify `User Sign-in feature `.
+
+With AWS Amplify, you can configure a working Google Sign-In feature for both Android and iOS apps. To fully integrate Google Sign-In with your app, AWS Amplify needs information that comes from Google's setup process.
+
+The following pages detail the Google Sign-In requirements ans steps to integrate Google Sign-In for both iOS and Android apps.
+
+* `auth-google-create-google-project` (required for `all apps` regardless of platform)
+
+* `auth-google-create-oauth-android-clientid` (required for all Android apps)
+
+* `auth-google-create-oauth-ios-clientid` (required for all iOS apps)
diff --git a/android/authentiation.md b/android/authentiation.md
new file mode 100755
index 00000000000..e3504b2e3c3
--- /dev/null
+++ b/android/authentiation.md
@@ -0,0 +1,364 @@
+# Add User Sign-in to Your Mobile App with Amazon Cognito
+
+Enable your users to sign-in using credentials from Facebook, Google, or your own custom user directory. The CLI deploys [Amazon Cognito identity pool](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-identity.html) and [user pools](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools.html) to create your backend.
+
+## Set Up Your Backend
+
+**Prerequisite** Complete the [Get Started](./get-started) steps before you proceed.
+
+## Email & Password
+
+This default auth configuration sets up a custom user pool for your app.
+
+**To set up email and password sign-in**
+
+1. In a terminal window, navigate to the root of your app files and add the auth category to your app. The CLI will prompt you for configuration parameters.
+
+ ```bash
+ $ cd ./YOUR_PROJECT_FOLDER
+ $ amplify add auth
+ ```
+
+2. Choose the default configuration.
+
+ ```
+ ❯ Yes, use the default configuration.
+ ```
+
+3. When configuration for email and password sign-in is complete, a message appears confirming that you have configured local CLI metadata for this category. You can confirm this by viewing status.
+
+ ```bash
+ $ amplify status
+ | Category | Resource name | Operation | Provider plugin |
+ | -------- | --------------- | --------- | ----------------- |
+ | Auth | cognitoabcd0123 | Create | awscloudformation |
+ ```
+
+4. To create your backend AWS resources run the following:
+
+ ```bash
+ $ amplify push
+ ```
+
+5. Follow the [Set up Email & Password Login](#set-up-email-and-password) steps to connect to your backend from your app.
+
+## Facebook
+
+**To set up Facebook sign-in**
+
+1. In a terminal window, navigate to the root of your app files and add the auth category to your app. The CLI prompts you for configuration parameters.
+
+ ```bash
+ $ cd ./YOUR_PROJECT_FOLDER
+ $ amplify add auth
+ ```
+
+2. Choose to set up your own configuration.
+
+ ```
+ ❯ No, I will set up my own configuration.
+ ```
+
+3. Choose to set up authentication flow using AWS IAM access controls.
+
+ ```
+ ❯ User Sign-Up, Sign-In, connected with AWS IAM controls
+ ```
+
+4. Choose yes, to: `? Allow unauthenticated logins?`.
+
+5. Choose yes, to: `? Do you want to enable 3rd party authentication providers in your identity pool?`.
+
+6. Choose Facebook and then provide your Facebook app ID. To retrieve or create your Facebook app ID, see [Setting Up Facebook Authentication](http://docs.aws.amazon.com/aws-mobile/latest/developerguide/auth-facebook-setup.html).
+
+7. When configuration for Facebook sign-in is complete, the CLI displays a message confirming that you have configured local CLI metadata for this category. You can confirm this by viewing status.
+
+ ```
+ $ amplify status
+ | Category | Resource name | Operation | Provider plugin |
+ | --------- | --------------- | --------- | ----------------- |
+ | Auth | cognitoa7cbb553 | Create | awscloudformation |
+ ```
+
+8. To create your backend AWS resources run the following:
+
+```
+$ amplify push
+```
+
+9. Follow the steps at [Set Up Facebook Login](#set-up-facebook) to connect to your backend from your app.
+
+## Google
+
+**To set up Google sign-in**
+
+1. In a terminal window, navigate to the root of your app files and add the auth category to your app. The CLI prompts you for configuration parameters.
+
+ ```
+ $ cd ./YOUR_APP_ROOT
+ $ amplify add auth
+ ```
+
+2. Choose to set up your own configuration.
+
+ ```
+ ❯ No, I will set up my own configuration.
+ ```
+
+3. Choose to set up authentication flow using AWS IAM access controls.
+
+ ```
+ ❯ User Sign-Up, Sign-In, connected with AWS IAM controls ...
+ ```
+
+4. Choose yes, to: `? Allow unauthenticated logins?`.
+
+5. Choose yes, to: `? Do you want to enable 3rd party authentication providers in your identity pool?`.
+
+6. Choose Google and then provide your Google client ID. To retrieve or create your Google app ID, see [Setting Up Google Authentication](http://docs.aws.amazon.com/aws-mobile/latest/developerguide/auth-google-setup.html).
+
+7. When configuration for Google sign-in is complete, the CLI displays a message confirming that you have configured local CLI metadata for this category. You can confirm this by viewing status.
+
+ ```
+ $ amplify status
+ | Category | Resource name | Operation | Provider plugin |
+ | --------- | --------------- | --------- | ----------------- |
+ | Auth | cognitoa7cbb553 | Create | awscloudformation |
+ ```
+
+8. To create your backend AWS resources run the following:
+
+ ```
+ $ amplify push
+ ```
+
+9. Follow the steps at [Set Up Google Login](#set-up-google) to connect to your backend from your app.
+
+Note that the CLI allows you to select more than one identity provider for your app. You can also run `amplify auth update` to add an identity provider to an existing auth configuration.
+
+## Set Up Email and Password Login in Your Mobile App
+
+> **Use Android API level 23 or higher** The AWS Mobile SDK library for Android sign-in (`aws-android-sdk-auth-ui`) provides the activity and view for presenting a `SignInUI` for the sign-in providers you configure. This library depends on the Android SDK API Level 23 or higher.
+
+1. Add the following permissions to the `AndroidManifest.xml` file:
+
+ ```xml
+
+
+ ```
+
+2. Add the following dependencies to the `app/build.gradle` file:
+
+ ```groovy
+ dependencies {
+ // Mobile Client for initializing the SDK
+ implementation ('com.amazonaws:aws-android-sdk-mobile-client:2.6.+@aar') { transitive = true }
+
+ // Cognito UserPools for SignIn
+ implementation 'com.android.support:support-v4:24.+'
+ implementation ('com.amazonaws:aws-android-sdk-auth-userpools:2.6.+@aar') { transitive = true }
+
+ // Sign in UI Library
+ implementation 'com.android.support:appcompat-v7:24.+'
+ implementation ('com.amazonaws:aws-android-sdk-auth-ui:2.6.+@aar') { transitive = true }
+ }
+ ```
+
+ Note: When you add the dependencies, make sure that the major version of appcompat and support libraries match. In the previous example, we're using version 24.
+
+3. Create an activity that will present your sign-in screen.
+
+ In Android Studio, choose `File > New > Activity > Basic Activity` and type an activity name, such as `AuthenticatorActivity`. If you want to make this your starting activity, move the intent filter block containing `.LAUNCHER` to the `AuthenticatorActivity` in your app's `AndroidManifest.xml`.
+
+ ```xml
+
+
+
+
+
+
+ ```
+
+## Set Up Facebook Login in Your Mobile App
+
+1. Add or update your AWS backend configuration file to incorporate your new sign-in. For details, see the last steps in the :ref:`Get Started: Set Up Your Backend ` section.
+
+2. Add the following permissions and Activity to your `AndroidManifest.xml` file:
+
+ ```xml
+
+
+ ```
+
+ ```xml
+
+
+
+
+
+
+
+
+ ```
+
+ ```xml
+
+ ```
+
+3. Add the following dependencies to your `app/build.gradle` file:
+
+ ```
+ dependencies {
+ // Mobile Client for initializing the SDK
+ implementation ('com.amazonaws:aws-android-sdk-mobile-client:2.6.+@aar') { transitive = true }
+
+ // Facebook SignIn
+ implementation 'com.android.support:support-v4:24.+'
+ implementation ('com.amazonaws:aws-android-sdk-auth-facebook:2.6.+@aar') { transitive = true }
+
+ // Sign in UI
+ implementation 'com.android.support:appcompat-v7:24.+'
+ implementation ('com.amazonaws:aws-android-sdk-auth-ui:2.6.+@aar') { transitive = true }
+ }
+ ```
+
+ > Note: When you add the dependencies, make sure that the major version of appcompat and support libraries match. In the previous example, we're using version 24.
+
+4. In `strings.xml`, add string definitions for your Facebook app ID and login protocol scheme. The value for app_id is your Facebook app ID and the value for logic_protocol_scheme should be your Facebook app ID prefixed with `fb`.
+
+ ```xml
+ 1231231231232123123
+ fb1231231231232123123
+ ```
+5. Create an activity that will present your sign-in screen.
+
+ In Android Studio, choose `File > New > Activity > Basic Activity` and type an activity name, such as `AuthenticatorActivity`. If you want to make this your starting activity, move the intent filter block containing `.LAUNCHER` to the `AuthenticatorActivity` in your app's `AndroidManifest.xml`.
+
+ ```xml
+
+
+
+
+
+
+ ```
+
+## Set Up Google Login in Your Mobile App
+
+> **Use Android API level 23 or higher** The AWS Mobile SDK library for Android sign-in (`aws-android-sdk-auth-ui`) provides the activity and view for presenting a `SignInUI` for the sign-in providers you configure. This library depends on the Android SDK API Level 23 or higher.
+
+1. Add or update your AWS backend configuration file to incorporate your new sign-in. For details, see the last steps in the :ref:`Get Started: Set Up Your Backend ` section.
+
+2. Add the following permissions to your `AndroidManifest.xml` file:
+
+ ```xml
+
+
+ ```
+3. Add the following dependencies to your `app/build.gradle` file:
+
+ ```java
+ dependencies {
+ // Mobile Client for initializing the SDK
+ implementation ('com.amazonaws:aws-android-sdk-mobile-client:2.6.+@aar') { transitive = true }
+
+ // Google SignIn
+ implementation 'com.android.support:support-v4:24.+'
+ implementation ('com.amazonaws:aws-android-sdk-auth-google:2.6.+@aar') { transitive = true }
+
+ // Sign in UI Library
+ implementation 'com.android.support:appcompat-v7:24.+'
+ implementation ('com.amazonaws:aws-android-sdk-auth-ui:2.6.+@aar') { transitive = true }
+ }
+ ```
+
+4. Create an activity that will present your sign-in screen.
+
+ In Android Studio, choose `File > New > Activity > Basic Activity` and type an activity name, such as `AuthenticatorActivity`. If you want to make this your starting activity, move the intent filter block containing `.LAUNCHER` to the `AuthenticatorActivity` in your app's `AndroidManifest.xml`.
+
+ ```xml
+
+
+
+
+
+
+ ```
+
+## Launch your sign-in screen
+
+5. Update the `onCreate` function of your `AuthenticatorActivity` to call `AWSMobileClient`. This component provides the functionality to resume a signed-in authentication session. It makes a network call to retrieve the AWS credentials that allow users to access your AWS resources and registers a callback for when that transaction is complete.
+
+ If the user is already signed in, the app switches to the `NextActivity`. If the user is not signed in, the user is presented with the AWS Mobile configurable sign-in UI. After the user is authenticated, the app continues to the `NextActivity`.
+
+ ```java
+ import android.app.Activity;
+ import android.os.Bundle;
+
+ import com.amazonaws.mobile.auth.ui.SignInUI;
+ import com.amazonaws.mobile.client.AWSMobileClient;
+ import com.amazonaws.mobile.client.AWSStartupHandler;
+ import com.amazonaws.mobile.client.AWSStartupResult;
+
+ public class AuthenticatorActivity extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_authenticator);
+
+ // Add a call to initialize AWSMobileClient
+ AWSMobileClient.getInstance().initialize(this, new AWSStartupHandler() {
+ @Override
+ public void onComplete(AWSStartupResult awsStartupResult) {
+ SignInUI signin = (SignInUI) AWSMobileClient.getInstance().getClient(AuthenticatorActivity.this, SignInUI.class);
+ signin.login(AuthenticatorActivity.this, MainActivity.class).execute();
+ }
+ }).execute();
+ }
+ }
+ ```
+ Choose the run icon (|play|) in Android Studio to build your app and run it on your device/emulator. You should see our ready made sign-in UI for your app. Check out the next steps to learn how to :ref:`customize your UI `.
+
+> Note: If you get an exception which mentions `Developer Error`, it is likely due to missing SHA1 value from the Google configuration console. Create an Android client app from the Google console and add your machine's SHA1 keys there. [Reference Link](https://stackoverflow.com/questions/37273145/error-statusstatuscode-developer-error-resolution-null)
+
+## API Reference
+* [AWSMobileClient](https://docs.aws.amazon.com/AWSAndroidSDK/latest/javadoc/com/amazonaws/mobile/client/AWSMobileClient.html)
+A library that initializes the SDK, constructs CredentialsProvider and AWSConfiguration objects, fetches the AWS credentials, and creates a SDK SignInUI client instance.
+* [Auth UserPools](https://docs.aws.amazon.com/AWSAndroidSDK/latest/javadoc/com/amazonaws/mobile/auth/userpools/CognitoUserPoolsSignInProvider.html)
+A wrapper library for Amazon Cognito user pools that provides a managed email/password sign-in UI.
+* [Auth Core](https://docs.aws.amazon.com/AWSAndroidSDK/latest/javadoc/com/amazonaws/mobile/auth/core/IdentityManager.html)
+A library that caches and federates a login provider authentication token using Amazon Cognito federated identities, caches the federated AWS credentials, and handles the sign-in flow.
+
+## Enable Sign-out
+
+To enable a user to sign-out of your app, register a callback for sign-in events by adding a `SignInStateChangeListener` to `IdentityManager`. The listener captures both `onUserSignedIn` and `onUserSignedOut` events.
+
+```java
+IdentityManager.getDefaultIdentityManager().addSignInStateChangeListener(new SignInStateChangeListener() {
+ @Override
+ // Sign-in listener
+ public void onUserSignedIn() {
+ Log.d(TAG, "User Signed In");
+ }
+
+ // Sign-out listener
+ @Override
+ public void onUserSignedOut() {
+ Log.d(TAG, "User signed out");
+ }
+});
+```
+
+To initiate a sign-out, call the `signOut` method of `IdentityManager`.
+
+```java
+IdentityManager.getDefaultIdentityManager().signOut();
+```
+
+### Next Steps
+
+ * `Customize the UI `
+ * `Import Your Existing Amazon Cognito Identity Pool `
+ * `Amazon Cognito Developer Guide `__
diff --git a/android/getting-started.md b/android/getting-started.md
new file mode 100755
index 00000000000..6e9fc1d089a
--- /dev/null
+++ b/android/getting-started.md
@@ -0,0 +1,87 @@
+# Get Started
+
+Get started building a cloud-powered Android app using the AWS Amplify CLI and the AWS SDK for Android. This page guides you through setting up an initial backend and integrating the SDK into your app.
+
+## Step 1: Set Up Your Development Environment
+
+We strongly recommend that you use the Amplify CLI for building the serverless backend for your app. If you have already installed the CLI, skip ahead to `Step 2 `.
+
+* `Sign up for an [AWS Account](https://portal.aws.amazon.com/billing/signup?redirect_url=https%3A%2F%2Faws.amazon.com%2Fregistration-confirmation#/start).
+
+* Install `Node.js `__ and npm (if they are not already installed).
+
+> Verify that you are running at least Node.js version 8.x or greater and npm version 5.x or greater by running :code:`node -v` and :code:`npm -v` in a terminal/console window. Older versions aren't supported and might generate errors.
+
+To install and configure the Amplify CLI globally, run the following commands in a terminal window.
+
+.. code-block:: bash
+
+ $ npm install -g @aws-amplify/cli
+
+ $ amplify configure
+
+Minimum requirements for your development environment are as follows.
+
+* Choose the Android Java app project you want to integrate with an AWS backend.
+
+* `Install Android Studio `__ version 2.33 or higher.
+
+* Install Android SDK for API level 23 (Android SDK 6.0).
+
+## Step 2: Set Up Your Backend
+
+1. The CLI prompts you for configuration parameters.
+
+ In a terminal window, navigate to your project folder (the folder that typically contains your project level :file:`build.gradle`), and add the SDK to your app.
+
+ ```bash
+ $ cd ./YOUR_PROJECT_FOLDER
+ $ amplify init
+ ```
+
+2. To create your backend AWS resources and add a configuration file to your app, run the following:
+
+ ```bash
+ $ amplify push
+ ```
+
+3. To verify that the CLI is set up for your app, run the following command. The CLI displays a status table with no resources listed. As you add categories to your app, backend resources created for your app are listed in this table.
+
+ ```bash
+ $ amplify status
+ | Category | Resource name | Operation | Provider plugin |
+ | -------- | ------------- | --------- | --------------- |
+ ```
+
+ Use the steps in the next section to configure the connection between your app and the serverless backend.
+
+## Step 3: Connect to Your Backend
+
+Perform the following steps to set up a connection to AWS services that you'll use in the Get Started section of this guide.
+
+1. Add dependencies to your :file:`app/build.gradle`, and then choose :guilabel:`Sync Now` on the upper-right side of Android Studio. These libraries enable basic AWS functions, like credentials and analytics.
+
+ ```groovy
+ dependencies {
+ implementation 'com.amazonaws:aws-android-sdk-core:2.6.+'
+ }
+ ```
+
+2. Your :file:`AndroidManifest.xml` must contain the following:
+
+ ```xml
+
+
+ ```
+
+ Your app is now ready for you to add cloud-powered features. We recommend [adding analytics](./analytics) as your first feature.
+
+## Next Steps
+
+* [Add Analytics](./analytics)
+* [Add User Sign-in](./authentication)
+* [Add Push Notification](./push-notifications)
+* [Add User File Storage](./storage)
+* [Add Serverless Backend](./api)
+* [Add Cloud Logic](./api)
+* [Add Messaging](./messaging)
diff --git a/android/how-to-android-kinesis-data-stream.md b/android/how-to-android-kinesis-data-stream.md
new file mode 100755
index 00000000000..3b21c8e6d3a
--- /dev/null
+++ b/android/how-to-android-kinesis-data-stream.md
@@ -0,0 +1,280 @@
+# Android: Process Data Streams with Kinesis
+
+## Overview
+
+Amazon Kinesis is a fully managed service for real-time processing of streaming data at massive scale.
+Kinesis can collect and process hundreds of terabytes of data per hour from hundreds of thousands of
+sources, so you can write applications that process information in real-time. With Kinesis
+applications, you can build real-time dashboards, capture exceptions and generate alerts, drive
+recommendations, and make other real-time business or operational decisions. You can also easily
+send data to other services such as Amazon Simple Storage Service, Amazon DynamoDB, and Amazon Redshift.
+
+The AWS Mobile SDK for Android provides simple, high-level clients designed to help you interface with Kinesis. The
+Kinesis clients let you store streaming data on disk and then send them all at once. This is useful
+because many mobile applications that use Kinesis will create multiple data requests per second.
+Sending one data request for each action could adversely impact battery life. Moreover, the requests
+could be lost if the device goes offline. Thus, using the high-level Kinesis client for batching can
+preserve both battery life and data.
+
+For information about Kinesis Region availability, see [AWS Service Region Availability]
+(http://aws.amazon.com/about-aws/global-infrastructure/regional-product-services/).
+
+To get started using the Amazon Kinesis mobile client, you'll need to integrate the SDK for Android
+into your app, set the appropriate permissions, and import the necessary libraries.
+
+
+### What is Kinesis Data Firehose?
+
+Amazon Kinesis Data Firehose is a fully managed service for delivering real-time streaming data to destinations such
+as |S3| and |RS|. With Kinesis Data Firehose, you do not need to write any applications or manage any resources. You
+configure your data producers to send data to Firehose and it automatically delivers the data to the
+destination that you specified.
+
+`KinesisFirehoseRecorder` is the high level client for Kinesis Data Firehose. Its usage is very similar to
+that of `KinesisRecorder`.
+
+For more information about Kinesis Data Firehose, see [Amazon Kinesis Firehose]
+(http://docs.aws.amazon.com/firehose/latest/dev/what-is-this-service.html).
+
+You can also learn more about how the Kinesis services work together on the following page: [Amazon
+Kinesis services] (http://aws.amazon.com/kinesis/).
+
+## Getting Started
+
+### Create an Identity Pool
+
+To use AWS services in your mobile application, you must obtain AWS Credentials using |COGID| as
+your credential provider. Using a credentials provider allows you to access AWS services without
+having to embed your private credentials in your application. This also allows you to set
+permissions to control which AWS services your users have access to.
+
+The identities of your application's users are stored and managed by an identity pool, which is a
+store of user identity data specific to your account. Every identity pool has roles that specify
+which AWS resources your users can access. Typically, a developer will use one identity pool per
+application. For more information on identity pools, see the [Cognito Developer Guide]
+(http://docs.aws.amazon.com/cognito/devguide/identity/identity-pools/).
+
+To create an identity pool for your application:
+
+1. Log in to the `Cognito Console ` and click `Create new identity
+ pool`.
+
+2. Enter a name for your Identity Pool and check the check box to enable access to unauthenticated
+ identities. Click `Create Pool` to create your identity pool.
+
+3. Click `Allow` to create the roles associated with your identity pool.
+
+The next page displays code that creates a credentials provider so you can easily integrate |COGID|
+in your Android application.
+
+For more information on Cognito Identity, see `how-to-cognito-integrate-an-existing-identity-pool`.
+
+### Set IAM Permissions (Amazon Kinesis)
+
+To use Amazon Kinesis in an application, you must set the correct permissions. The following IAM
+policy allows the user to submit records to a Kinesis stream identified by `ARN
+`:
+
+```json
+{
+ "Statement": [{
+ "Effect": "Allow",
+ "Action": "kinesis:PutRecords",
+ "Resource": "arn:aws:kinesis:us-west-2:111122223333:stream/mystream"
+ }]
+}
+```
+This policy should be applied to roles assigned to the Cognito identity pool, but you need to
+replace the `Resource` value with the correct ARN for your Kinesis stream. You can apply
+policies at the [IAM console] (https://console.aws.amazon.com/iam/)
+
+
+### Set IAM Permissions (Amazon Kinesis Firehose)
+
+Amazon Kinesis Firehose needs slightly different permission. The following IAM policy allows the
+user to submit records to an Amazon Kinesis Firehose stream identified by the Amazon Resource Name
+(ARN):
+
+```json
+{
+ "Statement": [{
+ "Effect": "Allow",
+ "Action": "firehose:PutRecordBatch",
+ "Resource": "arn:aws:firehose:us-west-2:111122223333:deliverystream/mystream"
+ }]
+}
+```
+For more information about ARN formatting and example policies, see [Amazon Resource Names for
+Amazon Kinesis]
+(http://docs.aws.amazon.com/kinesis/latest/dev/kinesis-using-iam.html#kinesis-using-iam-arn-format).
+
+To learn more about Kinesis-specific policies, see
+[Controlling Access to Amazon Kinesis Resources with IAM]
+(http://docs.aws.amazon.com/kinesis/latest/dev/kinesis-using-iam.html).
+
+To learn more about IAM policies, see [Using IAM]
+(http://docs.aws.amazon.com/IAM/latest/UserGuide/IAM_Introduction.html).
+
+### Include the SDK in Your Project
+
+Follow the instructions on the [Set Up the SDK for Android]
+(http://docs.aws.amazon.com/mobile/sdkforandroid/developerguide/setup.html) page to include the
+proper JAR files for this service and set the appropriate permissions.
+
+#### Set Permissions in Your Android Manifest
+
+In your :file:`AndroidManifest.xml` file, add the following permission:
+
+```java
+
+```
+#### Add Import Statements
+
+Add the following imports to the main activity of your app.
+
+```java
+import com.amazonaws.mobileconnectors.kinesis.kinesisrecorder.*;
+import com.amazonaws.auth.CognitoCachingCredentialsProvider;
+import com.amazonaws.regions.Regions;
+```
+
+## Instantiate a Kinesis Recorder
+
+Once you've imported the necessary libraries and have your credentials object, you can instantiate `KinesisRecorder`. `KinesisRecorder` is a high-level client meant for storing PutRecord requests on an Android device. Storing requests on the device lets you retain data when the device is offline, and it can also increase performance and battery efficiency since the network doesn't need to be awakened as frequently.
+
+`KinesisRecorder` uses synchronous calls, so you shouldn't call :code:`KinesisRecorder` methods on the main thread.
+
+When you create the :code:`KinesisRecorder` client, you'll pass in a directory and an AWS region. The directory should be empty the first time you instantiate `KinesisRecorder`; it should be private to your application; and, to prevent collision, it should be used only by `KinesisRecorder`. The following snippet creates a directory and instantiates the `KinesisRecorder` client, passing in a Cognito credentials object (`cognitoProvider`), a region enum, and the directory.
+
+```java
+String kinesisDirectory = "YOUR_UNIQUE_DIRECTORY";
+KinesisRecorder recorder = new KinesisRecorder(
+ myActivity.getDir(kinesisDirectory, 0),
+ Regions.US_WEST_2,
+ credentialsProvider
+);
+```
+You'll use `KinesisRecorder` to save records and then send them in a batch.
+
+```java
+recorder.saveRecord("MyData".getBytes(),"MyStreamName");
+recorder.submitAllRecords();
+```
+For the `saveRecord()` request above to work, you would have to have created a stream named `MyStreamName`. You can create new streams in the [Amazon Kinesis console] (https://console.aws.amazon.com/kinesis).
+
+If `submitAllRecords()` is called while the app is online, requests will be sent and removed from the disk. If `submitAllRecords()` is called while the app is offline, requests will be kept on disk until `submitAllRecords()` is called while online. This applies even if you lose your internet connection midway through a submit. So if you save ten requests, call `submitAllRecords()`, send five, and then lose the Internet connection, you have five requests left on disk. These remaining five will be sent the next time `submitAllRecords()` is invoked online.
+
+To see how much space the :code:`KinesisRecorder` client is allowed to use, you can call :code:`getDiskByteLimit()`.
+
+```java
+Long byteLimit = recorder.getDiskByteLimit();
+// Do something with byteLimit
+```
+Alternatively, you can retrieve the same information by getting the :code:`KinesisRecorderConfig` object for the recorder and calling :code:`getMaxStorageSize():`
+
+```java
+KinesisRecorderConfig kinesisRecorderConfig = recorder.getKinesisRecorderConfig();
+Long maxStorageSize = kinesisRecorderConfig.getMaxStorageSize();
+// Do something with maxStorageSize
+```
+```kotlin
+val recorder = KinesisRecorder(
+ myActivity.getDir("YOUR_UNIQUE_DIRECTORY", 0),
+ Regions.US_WEST_2,
+ credentialsProvider)
+```
+You'll use `KinesisRecorder` to save records and then send them in a batch.
+
+```kotlin
+recorder.saveRecord("MyData".getBytes(), "MyStreamName")
+recorder.submitAllRecords()
+```
+For the :code:`saveRecord()` request above to work, you would have to have created a stream named `MyStreamName`. You can create new streams in the [Amazon Kinesis console] (https://console.aws.amazon.com/kinesis).
+
+If `submitAllRecords()` is called while the app is online, requests will be sent and removed from the disk. If `submitAllRecords()` is called while the app is offline, requests will be kept on disk until `submitAllRecords()` is called while online. This applies even if you lose your internet connection midway through a submit. So if you save ten requests, call `submitAllRecords()`, send five, and then lose the Internet connection, you have five requests left on disk. These remaining five will be sent the next time `submitAllRecords()` is invoked online.
+
+To see how much space the :code:`KinesisRecorder` client is allowed to use, you can call `getDiskByteLimit()`.
+
+```kotlin
+val byteLimit = recorder.diskByteLimit
+// Do something with byteLimit
+```
+Alternatively, you can retrieve the same information by getting the :code:`KinesisRecorderConfig` object for the recorder and calling :code:`getMaxStorageSize():`
+```kotlin
+ val maxStorageSize = recorder.kinesisRecorderConfig.maxStorageSize
+ // Do something with maxStorageSize
+```
+### Storage limits
+
+If you exceed the storage limit for `KinesisRecorder`, requests will not be saved or sent. `KinesisRecorderConfig` has a default `maxStorageSize` of 8 MiB. You can configure the maximum allowed storage via the `withMaxStorageSize()` method of `KinesisRecorderConfig`.
+
+To check the number of bytes currently stored in the directory passed in to the `KinesisRecoder` constructor, call `getDiskBytesUsed()`:
+
+```Java
+Long bytesUsed = recorder.getDiskBytesUsed();
+// Do something with bytesUsed
+```
+
+```kotlin
+ val bytesUsed = recorder.diskBytesUsed
+ // Do something with bytesUsed
+```
+To learn more about working with Amazon Kinesis, see [Amazon Kinesis Developer Resources] (http://aws.amazon.com/kinesis/developer-resources/). To learn more about the Kinesis classes, see the [API Reference for the Android SDK] (http://docs.aws.amazon.com/AWSAndroidSDK/latest/javadoc/).
+
+
+## Use KinesisFirehoseRecorder
+
+To use `KinesisFirehoseRecorder`, you need to pass the object in a directory where streaming data is saved. We recommend you use an app private directory because the data is not encrypted.
+
+```java
+// Gets a working directory for the recorder
+File directory = context.getCachedDir();
+// Sets Firehose region
+Regions region = Regions.US_WEST_2;
+// Initialize a credentials provider to access Amazon Kinesis Firehose
+AWSCredentialsProvider provider = new CognitoCachingCredentialsProvider(
+ context, "identityPoolId",
+ Regions.US_EAST_1); // region of your Amazon Cognito identity pool
+KinesisFirehoseRecorder firehoseRecorder = new KinesisFirehoseRecorder(
+ directory, region, provider);
+
+// Start to save data, either a String or a byte array
+firehoseRecorder.saveRecord("Hello world!\n");
+firehoseRecorder.saveRecord("Streaming data to Amazon S3 via Amazon Kinesis Firehose is easy.\n");
+
+// Send previously saved data to Amazon Kinesis Firehose
+// Note: submitAllRecords() makes network calls, so wrap it in an AsyncTask.
+new AsyncTask() {
+ @Override
+ protected Void doInBackground(Void... v) {
+ try {
+ firehoseRecorder.submitAllRecords();
+ } catch (AmazonClientException ace) {
+ // handle error
+ }
+ }
+}.execute();
+```
+```kotlin
+val firehose = KinesisFirehoseRecorder(
+ context.getCachedDir(), // Working directory for recorder
+ Regions.US_WEST_2, // Region that Kinesis is provisioned in
+ credentialsProvider) // AWS Credentials provider
+
+// Start to save data, either a String or a byte array
+firehose.saveRecord("Hello world!\n");
+firehose.saveRecord("Streaming data to Amazon S3 via Amazon Kinesis Firehose is easy.\n");
+
+// Send previously saved data to Amazon Kinesis Firehose
+// Note: submitAllRecords() makes network calls.
+thread(start = true) {
+ try {
+ firehose.submitAllRecords()
+ } catch (ex: AmazonClientException) {
+ Log.e(TAG, "Error submitting records")
+ }
+}
+```
+To learn more about working with Amazon Kinesis Firehose, see `Amazon Kinesis Firehose `__.
+
+To learn more about the Kinesis Firehose classes, see the `API Reference for the Android SDK `__.
diff --git a/android/how-to-android-lex.md b/android/how-to-android-lex.md
new file mode 100755
index 00000000000..2fe19e3b208
--- /dev/null
+++ b/android/how-to-android-lex.md
@@ -0,0 +1,249 @@
+# Android: Use Natural Language with Amazon Lex
+
+## Overview
+
+Amazon Lex is an AWS service for building voice and text conversational interfaces into applications. With Amazon Lex, the same natural language understanding engine that powers Amazon Alexa is now available to any
+developer, enabling you to build sophisticated, natural language chatbots into your new and existing
+applications.
+
+The AWS Mobile SDK for Android provides an optimized client for interacting with Amazon Lex runtime APIs,
+which support both voice and text input and can return either voice or text. Amazon Lex has built-in
+integration with AWS Lambda to allow insertion of custom business logic into your Amazon Lex processing flow, including all of the extension to other services that Lambda makes possible.
+
+For information on Amazon Lex concepts and service configuration, see
+[How it Works] (http://docs.aws.amazon.com/lex/latest/dg/how-it-works.html) in the *Lex Developer Guide*.
+
+For information about Region availability, see [AWS Service Region Availability] (http://aws.amazon.com/about-aws/global-infrastructure/regional-product-services/).
+
+To get started using the Amazon Lex mobile client, integrate the SDK for Android
+into your app, set the appropriate permissions, and import the necessary libraries.
+
+
+## Setting Up
+
+### Include the SDK in Your Project
+
+Follow the instructions at :doc:`setup-legacy` to include the JAR files for this service and set the appropriate
+permissions.
+
+
+#### Set Permissions in Your Android Manifest
+
+ In your :file:`AndroidManifest.xml` file, add the following permission:
+
+ ```xml
+
+
+
+ ```
+
+#### Declare Amazon Lex as a Gradle dependency
+
+ Make sure the following Gradle build dependency is declared in the :file:`app/build.gradle` file.
+
+ ```groovy
+ implementation 'com.amazonaws:aws-android-sdk-lex:2.3.8@aar'
+ ```
+
+### Set IAM Permissions for Amazon Lex
+
+To use Amazon Lex in an application, create a role and attach policies as described in Step 1 of
+[Getting Started] (http://docs.aws.amazon.com/lex/latest/dg/gs-bp-prep.html) in the *Lex Developer Guide*.
+
+To learn more about IAM policies, see [Using IAM] (http://docs.aws.amazon.com/IAM/latest/UserGuide/IAM_Introduction.html).
+
+### Configure a Bot
+
+Use the [Amazon Lex console] (https://console.aws.amazon.com/lex/)__ console to configure a bot that interacts with your mobile app features. To learn more, see [Amazon Lex Developer Guide] (https://docs.aws.amazon.com/lex/latest/dg/what-is.html). For a quickstart, see [Getting Started] (https://alpha-docs-aws.amazon.com/lex/latest/dg/getting-started.html).
+
+Amazon Lex also supports model building APIs, which allow creation of bots, intents, and slots at runtime. This SDK does not currently offer additional support for interacting with Amazon Lex model building APIs.
+
+## Implement Text and Voice Interaction with Amazon Lex
+
+### Get AWS User Credentials
+
+Both text and voice API calls require validated AWS credentials. To establish Amazon Cognito as the credentials provider,
+include the following code in the function where you initialize your Amazon Lex interaction objects.
+
+```java
+CognitoCredentialsProvider credentialsProvider =
+ new CognitoCredentialsProvider(
+ appContext.getResources().getString(R.string.identity_id_test),
+ Regions.fromName(appContext.getResources().getString(R.string.aws_region))
+ );
+```
+```kotlin
+val region = applicationContext.resources.getString(R.string.aws_region)
+val credentialsProvider = CognitoCredentialsProvider
+ applicationContext.resources.getString(R.string.identity_id_test),
+ Regions.fromName(region))
+```
+
+### Integrate Lex Interaction Client
+
+Perform the following tasks to implement interaction with Lex in your Android app.
+
+#### Initialize Your Lex Interaction Client
+
+ Instantiate an `InteractionClient`, providing the following parameters.
+
+ - The application context, credentials provider, and AWS Region
+ - `bot_name` - name of the bot as it appears in the Amazon Lex console
+ - `bot_alias` - the name associated with selected version of your bot
+ - `InteractionListener` - your app's receiver for text responses from Amazon Lex
+ - `AudioPlaybackListener` - your app's receiver for voice responses from Amazon Lex
+
+ ```java
+ // Create Lex interaction client.
+ lexInteractionClient = new InteractionClient(getApplicationContext(),
+ credentialsProvider,
+ Regions.US_EAST_1,
+ ,
+ );
+ lexInteractionClient.setAudioPlaybackListener(audioPlaybackListener);
+ lexInteractionClient.setInteractionListener(interactionListener);
+ ```
+
+ ```kotlin
+ // Create Lex interaction client.
+ val lexInteractionClient = InteractionClient(applicationContext,
+ credentialsProvider,
+ Regions.US_EAST_1,
+ ,
+ )
+ lexInteractionClient.audioPlaybackListener = audioPlaybackListener
+ lexInteractionClient.interactionListener = interactionListener
+ ```
+#### Begin or Continue a Conversation
+
+ To begin a new conversation with Amazon Lex, we recommend that you clear any history of previous text interactions, and that
+ you maintain a `inConversation` flag to make your app aware of when a conversation is in progress.
+
+ If `inConversation` is false when user input is ready to be sent as Amazon Lex input, then make a call using the
+ `textInForTextOut`, `textInForAudioOut`, `audioInForTextOut`, or `audioInForAudioOut` method
+ of an `InteractionClient` instance. These calls are in the form of:
+ ```java
+ lexInteractionClient.textInForTextOut(
+ String text,
+ Map sessionAttributes)
+ ```
+
+ ```kotlin
+ lexInteractionClient.textInForTextOut(
+ text: String,
+ sessionAttributes: Map)
+ ```
+
+ If `inConversation` is true, then the input should be passed to an instance of `LexServiceContinuation`
+ using the `continueWithTextInForTextOut`, `continueWithTextInForAudioOut`, `continueWithAudioInForTextOut`,
+ `continueWithAudioInForAudioOut` method. Continuation enables Amazon Lex to persist the state and metadata of an ongoing conversation across multiple interactions.
+
+#### Interaction Response Events
+
+ `InteractionListener` captures a set of Amazon Lex response events that include:
+
+ - `onReadyForFulfillment(final Response response)`
+
+ This response means that Lex has the information it needs to co fulfill the intent of the user and considers the
+ transaction complete. Typically, your app would set your `inConversation` flag to false when this response arrives.
+
+ - `promptUserToRespond(final Response response, final LexServiceContinuation continuation)`
+
+ This response means that Amazon Lex is providing the next piece of information needed in the conversation flow. Typically
+ your app would pass the received continuation on to your Amazon Lex client.
+
+ - `onInteractionError(final Response response, final Exception e)`
+
+ This response means that Amazon Lex is providing an identifier for the exception that has occurred.
+
+#### Microphone Events
+
+ `MicrophoneListener` captures events related to the microphone used for interaction with Amazon Lex that include:
+
+ - `startedRecording()`
+
+ This event occurs when the user has started recording their voice input to Amazon Lex.
+
+ - `onRecordingEnd()`
+
+ This event occurs when the user has finished recording their voice input to Amazon Lex.
+
+ - `onSoundLevelChanged(double soundLevel)`
+
+ This event occurs when the volume level of audio being recorded changes.
+
+ - `onMicrophoneError(Exception e)`
+
+ The event returns an exception when an error occurs while recording sound through the microphone.
+
+#### Audio Playback Events
+
+ `AudioPlaybackListener` captures a set of events related to Amazon Lex voice responses that include:
+
+ - `onAudioPlaybackStarted()`
+
+ This event occurs when playback of a Amazon Lex voice response starts.
+
+ - `onAudioPlayBackCompleted()`
+
+ This event occurs when playback of a Amazon Lex voice response finishes.
+
+ - `onAudioPlaybackError(Exception e)`
+
+ This event returns an exception when an error occurs during playback of an Amazon Lex voice response.
+
+
+### Add Voice Interactions
+
+Perform the following tasks to implement voice interaction with Amazon Lex in your Android app.
+
+`InteractiveVoiceView` simplifies the acts of receiving and playing voice responses from Lex by internally
+using the `InteractionClient` methods and both `MicrophoneListener` and Amazon Lex`AudioPlaybackListener` events
+described in the preceding sections. You can use those interfaces directly instead of instantiating
+`InteractiveVoiceView`.
+
+#### Add a `voice-component` Layout Element to Your Activity
+
+ In the layout for your activity class that contains the voice interface for your app, include the following element.
+
+ ```xml
+
+ ```
+#### Initialize Your Voice Activity
+
+ In your activity class that contains the voice interface for your app, have the base class implement
+ `InteractiveVoiceView.InteractiveVoiceListener`.
+
+ The following code shows initialization of `InteractiveVoiceView`.
+
+ ```java
+ private void init() {
+ appContext = getApplicationContext();
+ voiceView = (InteractiveVoiceView) findViewById(R.id.voiceInterface);
+ voiceView.setInteractiveVoiceListener(this);
+ CognitoCredentialsProvider credentialsProvider = new CognitoCredentialsProvider(
+ ,
+ Regions.fromName()));
+ voiceView.getViewAdapter().setCredentialProvider(credentialsProvider);
+ voiceView.getViewAdapter().setInteractionConfig(
+ new InteractionConfig(), ));
+ voiceView.getViewAdapter().setAwsRegion());
+ }
+ ```
+
+ ```Kotlin
+ private fun init() {
+ val voiceView = voiceInterface as InteractiveVoiceView
+ val cp = CognitoCredentialsProvider(IDENTITY_POOL_ID, REGION)
+ with (voiceView.viewAdapter) {
+ credentialsProvider = cp
+ setInteractionConfig(InteractionConfig(), )
+ setAwsRegion(REGION)
+ }
+ }
+ ```
diff --git a/android/how-to-android-sdk-setup.md b/android/how-to-android-sdk-setup.md
new file mode 100755
index 00000000000..2ec9570cd55
--- /dev/null
+++ b/android/how-to-android-sdk-setup.md
@@ -0,0 +1,246 @@
+# Android: Setup Options for the SDK
+
+**Just Getting Started?** | [Use streamlined steps] (./getting-started) to install the SDK and integrate features.
+------------ | -------------
+
+
+*Or, use the options on this page if your app integrates existing AWS services.*
+
+To get started with the AWS Mobile SDK for Android, you can set up the SDK and start building a new project, or
+you can integrate the SDK with an existing project. You can also clone and run the [samples]
+(https://github.com/awslabs/aws-sdk-android-samples) to get a sense of how the SDK works.
+
+## Prerequisites
+
+Before you can use the AWS Mobile SDK for Android, you need the following:
+
+- An [AWS Account] (http://aws.amazon.com)
+
+- Android 2.3.3 (API Level 10) or higher (for more information about the Android platform, see
+ [Android Developers] (http://developer.android.com/index.html)
+
+- [Android Studio] (https://developer.android.com/sdk/index.html) or [Android Development Tools for
+ Eclipse] (http://developer.android.com/sdk/eclipse-adt.html)
+
+After completing the prerequisites, you need to do the following to get started:
+
+1. Get the AWS Mobile SDK for Android.
+2. Set permissions in your `AndroidManifest.xml` file.
+3. Obtain AWS credentials using Amazon Cognito.
+
+## Step 1: Get the AWS Mobile SDK for Android
+
+There are three ways to get the AWS Mobile SDK for Android.
+
+### Option 1: Using Gradle with Android Studio
+
+If you are using Android Studio, add the `aws-android-sdk-core` dependency to your
+`app/build.gradle` file, along with the dependencies for the individual services
+that your project will use, as shown below.
+
+```groovy
+dependencies {
+ implementation 'com.amazonaws:aws-android-sdk-core:2.6.+'
+ implementation 'com.amazonaws:aws-android-sdk-s3:2.6.+'
+ implementation 'com.amazonaws:aws-android-sdk-ddb:2.6.+'
+}
+```
+
+A full list of dependencies are listed below. For dependencies ending in "`@aar`" use a compile statement in the following form.
+
+```groovy
+implementation ('com.amazonaws:aws-android-sdk-cognitoauth:2.6.+@aar') { transitive = true }
+```
+Dependency | Build.gradle Value
+------------ | -------------
+"Amazon API Gateway" | "aws-android-sdk-apigateway-core:2.6.+"
+"AWS Auth Core" | "aws-android-sdk-auth-core:2.6.+@aar"
+"AWS Facebook SignIn Provider" | "aws-android-sdk-auth-facebook:2.6.+@aar"
+"AWS Google SignIn Provider" | "aws-android-sdk-auth-google:2.6.+@aar"
+"AWS Auth UI" | "aws-android-sdk-auth-ui:2.6.+@aar"
+"AWS Cognito User Pools SignIn Provider" | "aws-android-sdk-auth-userpools:2.6.+@aar"
+"Amazon Auto Scaling" | "aws-android-sdk-autoscaling:2.6.+"
+"Amazon CloudWatch" | "aws-android-sdk-cloudwatch:2.6.+"
+"Amazon Cognito Auth" | "aws-android-sdk-cognitoauth:2.6.+@aar"
+"Amazon Cognito Identity Provider" | "aws-android-sdk-cognitoidentityprovider:2.6.+"
+"AWS Core" | "aws-android-sdk-core:2.6.+"
+"Amazon DynamoDB Document Model" | "aws-android-sdk-ddb-document:2.6.+"
+"Amazon DynamoDB Object Mapper" | "aws-android-sdk-ddb-mapper:2.6.+"
+"Amazon DynamoDB" | "aws-android-sdk-ddb:2.6.+"
+"Amazon Elastic Compute Cloud" | "aws-android-sdk-ec2:2.6.+"
+"Amazon Elastic Load Balancing" | "aws-android-sdk-elb:2.6.+"
+"AWS IoT" | "aws-android-sdk-iot:2.6.+"
+"Amazon Kinesis" | "aws-android-sdk-kinesis:2.6.+"
+"Amazon Kinesis Video" | "aws-android-sdk-kinesisvideo:2.6.+@aar"
+"Amazon Key Management Service (KMS)" | "aws-android-sdk-kms:2.6.+"
+"AWS Lambda" | "aws-android-sdk-lambda:2.6.+"
+"Amazon Lex" | "aws-android-sdk-lex:2.6.+@aar"
+"Amazon CloudWatch Logs" | "aws-android-sdk-logs:2.6.+"
+"Amazon Machine Learning" | "aws-android-sdk-machinelearning:2.6.+"
+"AWS Mobile Client" | "aws-android-sdk-mobile-client:2.6.+@aar"
+"Amazon Mobile Analytics" | "aws-android-sdk-mobileanalytics:2.6.+"
+"Amazon Pinpoint" | "aws-android-sdk-pinpoint:2.6.+"
+"Amazon Polly" | "aws-android-sdk-polly:2.6.+"
+"Amazon Rekognition" | "aws-android-sdk-rekognition:2.6.+"
+"Amazon Simple Storage Service (S3)" | "aws-android-sdk-s3:2.6.+"
+"Amazon Simple DB (SDB)" | "aws-android-sdk-sdb:2.6.+"
+"Amazon SES" | "aws-android-sdk-ses:2.6.+"
+"Amazon SNS" | "aws-android-sdk-sns:2.6.+"
+"Amazon SQS" | "aws-android-sdk-sqs:2.6.+"
+
+
+### Option 2: Import the JAR Files
+
+To obtain the JAR files, download the SDK from http://aws.amazon.com/mobile/sdk. The SDK is stored
+in a compressed file named `aws-android-sdk-#-#-#`, where #-#-# represents the version number.
+Source code is available on [GitHub] (https://github.com/aws/aws-sdk-android).
+
+**If using Android Studio:**
+
+In the Project view, drag `aws-android-sdk-#-#-#-core.jar` plus the AWS Mobile SDK for Android`.jar` files for the individual services
+your project will use into the `apps/libs` folder. They'll be included on the build path
+automatically. Then, sync your project with the Gradle file.
+
+**If using Eclipse:**
+
+Drag the `aws-android-sdk-#-#-#-core.jar` file
+plus the `.jar` files for the individual services your project will use, into the `libs`
+folder. They'll be included on the build path automatically.
+
+### Option 3: Using Maven
+
+The AWS Mobile SDK for Android supports Apache Maven, a dependency management and build automation tool. A Maven
+project contains a `pom.xml` file where you can specify the Amazon Web Services that you want
+to use in your app. Maven then includes the services in your project, so that you don't have to
+download the entire AWS Mobile SDK and manually include JAR files.
+
+Maven is supported in AWS Mobile SDK for Android v. 2.1.3 and onward. Older versions of the SDK are not available
+via Maven. If you're new to Maven and you'd like to learn more about it, see the [Maven
+documentation] (http://maven.apache.org/what-is-maven.html).
+
+
+#### pom.xml Example
+
+Here's an example of how you can add [Amazon Cognito Identity] (http://aws.amazon.com/cognito/),
+[Amazon S3] (http://aws.amazon.com/s3/), and [Amazon Mobile Analytics]
+(http://aws.amazon.com/mobileanalytics/) to your project:
+
+```xml
+
+
+ com.amazonaws
+ aws-android-sdk-core
+ [2.2.0, 2.3)
+
+
+ com.amazonaws
+ aws-android-sdk-s3
+ [2.2.0, 2.3)
+
+
+ com.amazonaws
+ aws-android-sdk-mobileanalytics
+ [2.2.0, 2.3)
+
+
+```
+
+As shown above, the groupId for the AWS Mobile SDK for Android is ``com.amazonaws``. For each additional service,
+include a ```` element following the model above, and use the appropriate artifactID
+from the table below. The ```` element specifies the version of the AWS Mobile SDK for Android. The
+example above demonstrates Maven's ability to use a range of acceptable versions for a given
+dependency. To review available versions of the SDK for Android, see the [Release Notes]
+(https://aws.amazon.com/releasenotes/Android).
+
+The AWS Mobile `artifactId` values are as follows:
+Service/Feature | artifactID
+------------ | -------------
+"Amazon API Gateway" | "aws-android-sdk-apigateway-core"
+"AWS Auth Core" | "aws-android-sdk-auth-core"
+"AWS Facebook SignIn Provider" | "aws-android-sdk-auth-facebook"
+"AWS Google SignIn Provider" | "aws-android-sdk-auth-google"
+"AWS Auth UI" | "aws-android-sdk-auth-ui"
+"AWS Cognito User Pools SignIn Provider" | "aws-android-sdk-auth-userpools"
+"Amazon Auto Scaling" | "aws-android-sdk-autoscaling"
+"Amazon CloudWatch" | "aws-android-sdk-cloudwatch"
+"Amazon Cognito Auth" | "aws-android-sdk-cognitoauth"
+"Amazon Cognito Identity Provider" | "aws-android-sdk-cognitoidentityprovider"
+"AWS Core" | "aws-android-sdk-core"
+"Amazon DynamoDB Document Model" | "aws-android-sdk-ddb-document"
+"Amazon DynamoDB Object Mapper" | "aws-android-sdk-ddb-mapper"
+"Amazon DynamoDB" | "aws-android-sdk-ddb"
+"Amazon Elastic Compute Cloud" | "aws-android-sdk-ec2"
+"Amazon Elastic Load Balancing" | "aws-android-sdk-elb"
+"AWS IoT" | "aws-android-sdk-iot"
+"Amazon Kinesis" | "aws-android-sdk-kinesis"
+"Amazon Kinesis Video" | "aws-android-sdk-kinesisvideo"
+"Amazon Key Management Service (KMS)" | "aws-android-sdk-kms"
+"AWS Lambda" | "aws-android-sdk-lambda"
+"Amazon Lex" | "aws-android-sdk-lex"
+"Amazon CloudWatch Logs" | "aws-android-sdk-logs"
+"Amazon Machine Learning" | "aws-android-sdk-machinelearning"
+"AWS Mobile Client" | "aws-android-sdk-mobile-client"
+"Amazon Mobile Analytics" | "aws-android-sdk-mobileanalytics"
+"Amazon Pinpoint" | "aws-android-sdk-pinpoint"
+"Amazon Polly" | "aws-android-sdk-polly"
+"Amazon Rekognition" | "aws-android-sdk-rekognition"
+"Amazon Simple Storage Service (S3)" | "aws-android-sdk-s3"
+"Amazon Simple DB (SDB)" | "aws-android-sdk-sdb"
+"Amazon SES" | "aws-android-sdk-ses"
+"Amazon SNS" | "aws-android-sdk-sns"
+"Amazon SQS" | "aws-android-sdk-sqs"
+
+
+## Step 2: Set Permissions in Your Manifest
+
+Add the following permission to your `AndroidManifest.xml`::
+
+```xml
+
+```
+
+## Step 3: Get AWS Credentials
+
+To use AWS services in your mobile application, you must obtain AWS Credentials using Amazon Cognito
+Identity as your credential provider. Using a credentials provider allows your app to access AWS
+services without having to embed your private credentials in your application. This also allows you
+to set permissions to control which AWS services your users have access to.
+
+To get started with Amazon Cognito, you must create an identity pool. An identity pool is a store of
+user identity data specific to your account. Every identity pool has configurable IAM roles that
+allow you to specify which AWS services your application's users can access. Typically, a developer
+will use one identity pool per application. For more information on identity pools, see the [Amazon
+Cognito Developer Guide] (http://docs.aws.amazon.com/cognito/devguide/identity/identity-pools/).
+
+To create an identity pool for your application:
+
+1. Log in to the [Amazon Cognito Console] (https://console.aws.amazon.com/cognito/home) and click
+ `Manage Federated Identities`, then `Create new identity pool`.
+
+2. Enter a name for your Identity Pool and check the check box to enable access to unauthenticated
+ identities. Click `Create Pool` to create your identity pool.
+
+3. Click `Allow` to create the two default roles associated with your identity pool
+ |mdash| one for unauthenticated users and one for authenticated users.
+
+The next page displays code that creates a credentials provider so you can easily integrate Cognito
+Identity with your Android application. You pass the credentials provider object to the constructor
+of the AWS client you are using. The credentials provider looks like this::
+
+ CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
+ getApplicationContext(), /* get the context for the application */
+ "COGNITO_IDENTITY_POOL", /* Identity Pool ID */
+ Regions.MY_REGION /* Region for your identity pool--US_EAST_1 or EU_WEST_1*/
+ );
+
+## Next Steps
+
+- **Run the demos**: View our [sample Android apps]
+ (https://github.com/awslabs/aws-sdk-android-samples) that demonstrate common use cases. To run
+ the sample apps, set up the SDK for Android as described above, and then follow the instructions
+ contained in the README files of the individual samples.
+
+- **Read the API Reference**: View the [API Reference]
+ (https://docs.aws.amazon.com/AWSAndroidSDK/latest/javadoc/) for the AWS Mobile SDK for Android.
+
+- **Ask questions**: Post questions on the `AWS Mobile SDK Forums <88>`.
diff --git a/android/how-to-cognito-integrate-an-existing-identity-pool-android.md b/android/how-to-cognito-integrate-an-existing-identity-pool-android.md
new file mode 100755
index 00000000000..54bc282b3fa
--- /dev/null
+++ b/android/how-to-cognito-integrate-an-existing-identity-pool-android.md
@@ -0,0 +1,228 @@
+# How to Integrate Your Existing Identity Pool
+
+
+**Just Getting Started?** | `Use streamlined steps ` to install the SDK and integrate Amazon Cognito.
+------------ | -------------
+
+The `Get Started ` section of this guide allows you to create new resources and complete the steps described on this page in minutes. If you want to import existing resources or create them from scratch, this page will walk you through the following steps:
+
+ * Set up short-lived credentials for accessing your AWS resources using a [Cognito Identity Pool] (http://docs.aws.amazon.com/cognito/latest/developerguide/identity-pools.html).
+
+ * Create an AWS Mobile configuration file that ties your app code to the identity pool that enables users to access your AWS resources.
+
+ * Make small adjustments to your app code to install the SDK and retrieve AWS credentials for your user.
+
+
+## Set Up Your Backend
+
+### Import or Create a New Identity Pool
+
+* If you already have an Amazon Cognito Identity Pool and know its ID and region, you can skip to :ref:`how-to-auth-connect-to-your-backend`.
+
+To create a new identity pool:
+
+1. Go to [Amazon Cognito Console] (https://console.aws.amazon.com/cognito) and choose `Manage Federated Identities`.
+
+2. Choose `Create new Identity pool` on the top left of the console.
+
+3. Type a name for the Identity pool, select `Enable access to unauthenticated identities` under the `Unauthenticated Identities` section, and then choose `Create pool` on the bottom right.
+
+4. Expand the `View Details` section to see the two roles that are to be created to enable access to your bucket. Copy and keep both the Authenticated and Unauthenticated role names, in the form of :code:`Cognito_Auth_Role` and :code:`Cognito_Unauth_Role`. In many cases, you will modify the permissions policy of these roles to control access to AWS resources that you add to your app.
+
+5. Choose `Allow` on the bottom right.
+
+6. In the code snippet labeled `Get AWSCredentials` displayed by the console, copy the Identity Pool ID and the Region for use in a following configuration step. You will use these values to connect your backend to your app.
+
+## Connect to Your Backend
+
+Take the following steps to connect your app to its backend.
+
+
+### Create the awsconfiguration.json file
+
+1. Create a file with name `awsconfiguration.json` with the following contents:
+
+```json
+ {
+ "Version": "1.0",
+ "CredentialsProvider": {
+ "CognitoIdentity": {
+ "Default": {
+ "PoolId": "COGNITO-IDENTITY-POOL-ID",
+ "Region": "COGNITO-IDENTITY-POOL-REGION"
+ }
+ }
+ },
+ "IdentityManager" : {
+ "Default" : {
+
+ }
+ }
+ }
+```
+
+2. Make the following changes to the configuration file.
+
+* Replace the `COGNITO-IDENTITY-POOL-ID` with the identity pool ID.
+
+* Replace the `COGNITO-IDENTITY-POOL-REGION` with the region the identity pool was created in.
+
+
+ - Need to find your pool's ID and region?
+
+ - Go to [Amazon Cognito Console] (https://console.aws.amazon.com/cognito) and choose `Manage Federated Identities`, then choose your pool and choose `Edit identity pool`. Copy the value of `Identity pool ID`.
+
+ Insert this region value into the following form to create the value you need for this integration.
+
+ ```bash
+
+ "Region": "REGION-PREFIX-OF-YOUR-POOL-ID".
+ ```
+ For example, if your pool ID is :code:`us-east-1:01234567-yyyy-0123-xxxx-012345678901`, then your integration region value would be:
+ ```bash
+
+ "Region": "us-east-1".
+ ```
+
+### Add the awsconfiguration.json file to your app
+
+Android - Java
+
+In the Android Studio Project Navigator, right-click your app's `res` folder, and then choose `New > Directory`. Type `raw` as the directory name and then choose `OK`.
+
+
+
+Drag the `awsconfiguration.json` you created into the `res/raw` folder. Android gives a resource ID to any arbitrary file placed in this folder, making it easy to reference in the app.
+
+Android - Kotlin
+
+In the Android Studio Project Navigator, right-click your app's `res` folder, and then choose `New > Directory`. Type :userinput:`raw` as the directory name and then choose `OK`.
+
+
+
+Drag the `awsconfiguration.json` you created into the `res/raw` folder. Android gives a resource ID to any arbitrary file placed in this folder, making it easy to reference in the app.
+
+
+### Add the SDK to your App
+
+Android - Java
+
+Set up AWS Mobile SDK components as follows:
+
+1. Add the following to `app/build.gradle`:
+
+```ruby
+ dependencies {
+ implementation ('com.amazonaws:aws-android-sdk-mobile-client:2.6.+@aar') { transitive = true }
+
+ // other dependencies . . .
+ }
+```
+
+2. Perform a Gradle sync to download the AWS Mobile SDK components into your app.
+
+3. 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.
+
+ Once the network call to retrieve the user's AWS identity ID has succeeded, you can get the users identity using `getCachedUserID()` from the `AWSIdentityManager`.
+
+```java
+import com.amazonaws.auth.AWSCredentialsProvider;
+import com.amazonaws.mobile.auth.core.IdentityHandler;
+import com.amazonaws.mobile.auth.core.IdentityManager;
+import com.amazonaws.mobile.client.AWSMobileClient;
+import com.amazonaws.mobile.client.AWSStartupHandler;
+import com.amazonaws.mobile.client.AWSStartupResult;
+
+public class MainActivity extends AppCompatActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ AWSMobileClient.getInstance().initialize(this, new AWSStartupHandler() {
+ @Override
+ public void onComplete(AWSStartupResult awsStartupResult) {
+
+ //Make a network call to retrieve the identity ID
+ // using IdentityManager. onIdentityId happens UPon success.
+ IdentityManager.getDefaultIdentityManager().getUserID(new IdentityHandler() {
+
+ @Override
+ public void onIdentityId(String s) {
+
+ //The network call to fetch AWS credentials succeeded, the cached
+ // user ID is available from IdentityManager throughout your app
+ Log.d("MainActivity", "Identity ID is: " + s);
+ Log.d("MainActivity", "Cached Identity ID: " + IdentityManager.getDefaultIdentityManager().getCachedUserID());
+ }
+
+ @Override
+ public void handleError(Exception e) {
+ Log.e("MainActivity", "Error in retrieving Identity ID: " + e.getMessage());
+ }
+ });
+ }
+ }).execute();
+ }
+}
+```
+
+When you run your app, you shouldn't see a behavior change. To verify success, look for the message `"Welcome to AWS!"` in your debug output.
+
+Android - Kotlin
+
+Set up AWS Mobile SDK components as follows:
+
+1. Add the following to `app/build.gradle`:
+
+```ruby
+dependencies {
+ implementation ('com.amazonaws:aws-android-sdk-mobile-client:2.6.+@aar') { transitive = true }
+
+ // other dependencies . . .
+}
+```
+
+2. Perform a Gradle sync to download the AWS Mobile SDK components into your app.
+
+3. Add the following code to the :code:`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.
+
+ Once the network call to retrieve the user's AWS identity ID has succeeded, you can get the users identity using `getCachedUserID()` from the `AWSIdentityManager`.
+
+```kotlin
+import com.amazonaws.auth.AWSCredentialsProvider;
+import com.amazonaws.mobile.auth.core.IdentityHandler;
+import com.amazonaws.mobile.auth.core.IdentityManager;
+import com.amazonaws.mobile.client.AWSMobileClient;
+import com.amazonaws.mobile.client.AWSStartupHandler;
+import com.amazonaws.mobile.client.AWSStartupResult;
+
+class MainActivity : AppCompatActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_main)
+
+ AWSMobileClient.getInstance().initialize(this) {
+ IdentityManager.defaultIdentityManager.getUserID(
+ object : IdentityHandler() {
+ override fun onIdentityId(s: String) {
+ // The network call to fetch AWS credentials succeeded
+ Log.d(TAG, "Identity ID is: ${s}")
+ }
+
+ override fun handleError(ex: Exception) {
+ Log.e(TAG, "Error: ${ex.message}")
+ }
+ }
+ )
+ }.execute()
+ }
+}
+```
+
+When you run your app, you shouldn't see a behavior change. To verify success, look for the message `"Welcome to AWS!"` in your debug output.
+
+## Next Steps
+
+* For further information, see [Amazon Cognito Developer Guide] (https://docs.aws.amazon.com/cognito/latest/developerguide/what-is-amazon-cognito.html).
diff --git a/android/how-to-polly.md b/android/how-to-polly.md
new file mode 100755
index 00000000000..4b0b6a0939f
--- /dev/null
+++ b/android/how-to-polly.md
@@ -0,0 +1,13 @@
+# Convert Text to Speech with Amazon Polly
+
+Amazon Polly is a service that turns text into lifelike speech, making it easy to develop mobile applications that use high-quality speech to increase engagement and accessibility. With Amazon Polly you can quickly build speech-enabled apps that work in multiple geographies.
+
+Using the following resources, you can integrate Amazon Polly with your iOS app to add text to speech transformation. No deep knowledge of either AWS services or natural language computing is needed.
+
+For information on Amazon Polly concepts and service configuration, see [How it Works] (http://docs.aws.amazon.com/polly/latest/dg/how-text-to-speech-works.html) in the Amazon Polly Developer Guide.
+
+## ANDROID
+
+* For sample Android integration code, see the [Android Amazon Polly Example] (https://docs.aws.amazon.com/polly/latest/dg/examples-android.html).
+
+* For end to end sample apps using Amazon Polly see the [AWS SDK for Android samples] (https://github.com/awslabs/aws-sdk-android-samples/).
diff --git a/android/how-to-transfer-files-with-transfer-utility.md b/android/how-to-transfer-files-with-transfer-utility.md
new file mode 100755
index 00000000000..84b2d688318
--- /dev/null
+++ b/android/how-to-transfer-files-with-transfer-utility.md
@@ -0,0 +1,1448 @@
+# Transfer Files and Data Using TransferUtility and Amazon S3
+
+**Just Getting Started?** | [Use streamlined steps] (./add-aws-mobile-user-data-storage) to install the SDK and integrate Amazon S3.
+------------ | -------------
+
+*Or, use the contents of this page if your app will integrate existing AWS services.*
+
+This page explains how to implement upload and download functionality and a number of additional storage use cases.
+
+The examples on this page assume you have added the AWS Mobile SDK to your mobile app. To create a new cloud storage backend for your app, see [Add User File Storage] (./add-aws-mobile-user-data-storage).
+
+**Best practice** | If you use the transfer utility multipart upload feature, take advantage of automatic cleanup features by setting up the [AbortIncompleteMultipartUpload] (https://docs.aws.amazon.com/AmazonS3/latest/dev/intro-lifecycle-rules.html) action in your Amazon S3 bucket life cycle configuration.
+------------ | -------------
+
+## Upload a File
+
+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. AWSMobileClient expects an activity context for resuming an authenticated session and creating the credentials provider.
+
+The following example shows using the transfer utility in the context of an Activity. If you are creating transfer utility from an application context, you can construct the CredentialsProvider and
+AWSConfiguration object and pass it into TransferUtility. The TransferUtility will check the size of file being uploaded and will automatically switch over to using multi part uploads if the file size exceeds 5 MB.
+
+```java
+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 {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ AWSMobileClient.getInstance().initialize(this).execute();
+ uploadWithTransferUtility();
+ }
+
+ private void uploadWithTransferUtility() {
+
+ 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"));
+
+ // Attach a listener to the observer to get state update and progress notifications
+ 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("YourActivity", "ID:" + id + " bytesCurrent: " + bytesCurrent
+ + " bytesTotal: " + bytesTotal + " " + percentDone + "%");
+ }
+
+ @Override
+ public void onError(int id, Exception ex) {
+ // Handle errors
+ }
+
+ });
+
+ // If you prefer to poll for the data, instead of attaching a
+ // listener, check for the state and progress in the observer.
+ if (TransferState.COMPLETED == uploadObserver.getState()) {
+ // Handle a completed upload.
+ }
+
+ Log.d("YourActivity", "Bytes Transferred: " + uploadObserver.getBytesTransferred());
+ Log.d("YourActivity", "Bytes Total: " + uploadObserver.getBytesTotal());
+ }
+}
+```
+
+Android - Kotlin
+
+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. AWSMobileClient expects an activity context for resuming an authenticated session and creating the credentials provider.
+
+The following example shows using the transfer utility in the context of an Activity. If you are creating transfer utility from an application context, you can construct the CredentialsProvider and
+AWSConfiguration object and pass it into TransferUtility. The TransferUtility will check the size of file being uploaded and will automatically switch over to using multi part uploads if the file size exceeds 5 MB.
+
+```java
+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;
+
+class MainActivity : Activity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate()
+ AWSMobileClient.getInstance().initialize(this).execute()
+ uploadWithTransferUtility(
+ "s3Folder/s3Key.txt"
+ File("/path/to/file/localfile.txt")
+ )
+ }
+
+ private fun uploadWithTransferUtility(remote: String, local: File) {
+ val txUtil = TransferUtility.builder()
+ .context(getApplicationContext)
+ .awsConfiguration(AWSMobileClient.getInstance().configuration)
+ .s3Client(AmazonS3Client(AWSMobileClient.getInstance().credentialsProvider))
+ .build()
+
+ val txObserver = txUtil.upload(remote, local)
+ txObserver.transferListener = object : TransferListener() {
+ override fun onStateChanged(id: Int, state: TransferState) {
+ if (state == TransferState.COMPLETED) {
+ // Handle a completed upload
+ }
+ }
+
+ override fun onProgressChanged(id: Int, current: Long, total: Long) {
+ val done = (((current / total) * 100.0) as Float) as Int
+ Log.d(TAG, "ID: $id, percent done = $done")
+ }
+
+ override fun onError(id: Int, ex: Exception) {
+ // Handle errors
+ }
+ }
+
+ // If you prefer to poll for the data, instead of attaching a
+ // listener, check for the state and progress in the observer.
+ if (txObserver.state == TransferState.COMPLETED) {
+ // Handle a completed upload.
+ }
+ }
+}
+```
+
+iOS - Swift
+ The transfer utility provides methods for both single-part and multipart uploads. When a transfer uses multipart upload, the data is chunked into a number of 5 MB parts which are transferred in parallel for increased speed.
+
+ The following example shows how to upload a file to an Amazon S3 bucket.
+
+```swift
+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;
+ }
+}
+```
+
+The following example shows how to upload a file to an Amazon S3 bucket using multipart uploads.
+
+```swift
+func uploadData() {
+
+ let data: Data = Data() // Data to be uploaded
+
+ let expression = AWSS3TransferUtilityMultiPartUploadExpression()
+ expression.progressBlock = {(task, progress) in
+ DispatchQueue.main.async(execute: {
+ // Do something e.g. Update a progress bar.
+ })
+ }
+
+ var completionHandler: AWSS3TransferUtilityMultiPartUploadCompletionHandlerBlock
+ 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.uploadUsingMultiPart(data: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 - 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. AWSMobileClient expects an activity context for resuming an authenticated session and creating the credentials provider.
+
+This example shows using the transfer utility in the context of an Activity. If you are creating transfer utility from an application context, you can construct the CredentialsProvider and
+AWSConfiguration object and pass it into TransferUtility.
+
+```java
+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 {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ AWSMobileClient.getInstance().initialize(this).execute();
+ downloadWithTransferUtility();
+ }
+
+ public void downloadWithTransferUtility() {
+
+ 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"));
+
+ // Attach a listener to the observer to get notified of the
+ // updates in the state and the progress
+ 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
+ }
+
+ });
+
+ // If you do not want to attach a listener and poll for the data
+ // from the observer, you can check for the state and the progress
+ // in the observer.
+ if (TransferState.COMPLETED == downloadObserver.getState()) {
+ // Handle a completed upload.
+ }
+
+ Log.d("YourActivity", "Bytes Transferred: " + downloadObserver.getBytesTransferred());
+ Log.d("YourActivity", "Bytes Total: " + downloadObserver.getBytesTotal());
+ }
+}
+```
+
+Android - Kotlin
+
+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. AWSMobileClient expects an activity context for resuming an authenticated session and creating the credentials provider.
+
+This example shows using the transfer utility in the context of an Activity. If you are creating transfer utility from an application context, you can construct the CredentialsProvider and
+AWSConfiguration object and pass it into TransferUtility.
+
+```java
+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;
+
+class MainActivity : Activity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate()
+ AWSMobileClient.getInstance().initialize(this).execute()
+ downloadWithTransferUtility(
+ "s3Folder/s3Key.txt"
+ File("/path/to/file/localfile.txt")
+ )
+ }
+
+ private fun downloadWithTransferUtility(remote: String, local: File) {
+ val txUtil = TransferUtility.builder()
+ .context(getApplicationContext)
+ .awsConfiguration(AWSMobileClient.getInstance().configuration)
+ .s3Client(AmazonS3Client(AWSMobileClient.getInstance().credentialsProvider))
+ .build()
+
+ val txObserver = txUtil.download(remote, local)
+ txObserver.transferListener = object : TransferListener() {
+ override fun onStateChanged(id: Int, state: TransferState) {
+ if (state == TransferState.COMPLETED) {
+ // Handle a completed upload
+ }
+ }
+
+ override fun onProgressChanged(id: Int, current: Long, total: Long) {
+ val done = (((current / total) * 100.0) as Float) as Int
+ Log.d(TAG, "ID: $id, percent done = $done")
+ }
+
+ override fun onError(id: Int, ex: Exception) {
+ // Handle errors
+ }
+ }
+
+ // If you prefer to poll for the data, instead of attaching a
+ // listener, check for the state and progress in the observer.
+ if (txObserver.state == TransferState.COMPLETED) {
+ // Handle a completed upload.
+ }
+ }
+}
+```
+
+iOS - Swift
+
+The following example shows how to download a file from an Amazon S3 bucket.
+
+```swift
+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;
+ }
+}
+```
+
+## Track Transfer Progress
+
+Android - Java
+
+With the `TransferUtility`, the download() and upload() methods return a `TransferObserver` object. This object gives access to:
+
+1. The state, as an `enum`
+2. The total bytes currently transferred
+3. The total bytes remaining to transfer, to aid in calculating progress bars
+4. A unique ID that you can use to keep track of distinct transfers
+
+Given the transfer ID, the `TransferObserver` object can be retrieved from anywhere in your app, even if the app was terminated during a transfer. It also lets you create a `TransferListener`, which will be updated on state or progress change, as well as when an error occurs.
+
+To get the progress of a transfer, call `setTransferListener()` on your `TransferObserver`. This requires you to implement `onStateChanged`, `onProgressChanged`, and `onError`. For example:
+
+You can also query for `TransferObservers` with either the `getTransfersWithType(transferType)` or `getTransfersWithTypeAndState(transferType, transferState)` method. You can use `TransferObservers` to determine what transfers are underway, what are paused and handle the transfers as necessary.
+
+```java
+
+TransferObserver transferObserver = download(MY_BUCKET, OBJECT_KEY, MY_FILE);
+transferObserver.setTransferListener(new TransferListener(){
+
+ @Override
+ public void onStateChanged(int id, TransferState state) {
+ // do something
+ }
+
+ @Override
+ public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) {
+ int percentage = (int) (bytesCurrent/bytesTotal * 100);
+ //Display percentage transferred to user
+ }
+
+ @Override
+ public void onError(int id, Exception ex) {
+ // do something
+ }
+});
+```
+
+The transfer ID can be retrieved from the `TransferObserver` object that is returned from upload or download function.
+
+```java
+// Gets id of the transfer.
+int transferId = transferObserver.getId();
+```
+
+Android - Kotlin
+
+With the `TransferUtility`, the download() and upload() methods return a `TransferObserver` object. This object gives access to:
+
+1. The state, as an `enum`
+2. The total bytes currently transferred
+3. The total bytes remaining to transfer, to aid in calculating progress bars
+4. A unique ID that you can use to keep track of distinct transfers
+
+Given the transfer ID, the `TransferObserver` object can be retrieved from anywhere in your app, even if the app was terminated during a transfer. It also lets you create a `TransferListener`, which will be updated on state or progress change, as well as when an error occurs.
+
+To get the progress of a transfer, call `setTransferListener()` on your `TransferObserver`. This requires you to implement `onStateChanged`, `onProgressChanged`, and `onError`. For example:
+
+You can also query for `TransferObservers` with either the `getTransfersWithType(transferType)` or `getTransfersWithTypeAndState(transferType, transferState)` method. You can use `TransferObservers` to determine what transfers are underway, what are paused and handle the transfers as necessary.
+
+```kotlin
+val transferObserver = download(MY_BUCKET, OBJECT_KEY, MY_FILE);
+transferObserver.transferListener = object : TransferListener() {
+ override fun onStateChanged(id: Int, state: TransferState) {
+ // Do something
+ }
+
+ override fun onProgressChanged(id: int, current: Long, total: Long) {
+ int percent = ((current / total) * 100.0) as Int
+ // Display percent transferred
+ }
+
+ override fun onError(id: Int, ex: Exception) {
+ // Do something
+ }
+}
+```
+
+The transfer ID can be retrieved from the `TransferObserver` object that is returned from upload or download function.
+
+```kotlin
+// Gets id of the transfer.
+val transferId = transferObserver.id;
+```
+
+iOS - Swift
+
+Implement progress and completion actions for transfers by passing a `progressBlock` and `completionHandler` blocks to the call to `AWSS3TransferUtility` that initiates the transfer.
+
+The following example of initiating a data upload, shows how progress and completion handling is typically done for all transfers. The `AWSS3TransferUtilityUploadExpression`, `AWSS3TransferUtilityMultiPartUploadExpression` and `AWSS3TransferUtilityDownloadExpression` contains the `progressBlock` that gives you the progress of the transfer which you can use to update the progress bar.
+
+```swift
+// For example, create a progress bar
+let progressView: UIProgressView! = UIProgressView()
+progressView.progress = 0.0;
+
+let data = Data() // The data to upload
+
+let expression = AWSS3TransferUtilityUploadExpression()
+expression.progressBlock = {(task, progress) in DispatchQueue.main.async(execute: {
+ // Update a progress bar.
+ progressView.progress = Float(progress.fractionCompleted)
+ })
+}
+
+let completionHandler: AWSS3TransferUtilityUploadCompletionHandlerBlock = { (task, error) -> Void in DispatchQueue.main.async(execute: {
+ if let error = error {
+ NSLog("Failed with error: \(error)")
+ }
+ else if(self.progressView.progress != 1.0) {
+ NSLog("Error: Failed.")
+ } else {
+ NSLog("Success.")
+ }
+ })
+}
+
+var refUploadTask: AWSS3TransferUtilityTask?
+let transferUtility = AWSS3TransferUtility.default()
+transferUtility.uploadData(data,
+ bucket: "S3BucketName",
+ key: "S3UploadKeyName",
+ contentType: "text/plain",
+ expression: expression,
+ completionHandler: completionHandler).continueWith { (task) -> AnyObject! in
+ if let error = task.error {
+ print("Error: \(error.localizedDescription)")
+ }
+
+ if let uploadTask = task.result {
+ // Do something with uploadTask.
+ // The uploadTask can be used to pause/resume/cancel the operation, retrieve task specific information
+ refUploadTask = uploadTask
+ }
+
+ return nil;
+ }
+```
+
+## Pause a Transfer
+
+Android - Java
+
+Transfers can be paused using the `pause(transferId)` method. If your app is terminated, crashes, or loses Internet connectivity, transfers are automatically paused.
+
+The `transferId` can be retrieved from the `TransferObserver` object as described in :ref:`native-track-progress-and-completion-of-a-transfer`.
+
+To pause a single transfer:
+```java
+transferUtility.pause(idOfTransferToBePaused);
+```
+
+To pause all uploads:
+
+```java
+transferUtility.pauseAllWithType(TransferType.UPLOAD);
+```
+
+To pause all downloads:
+
+```java
+transferUtility.pauseAllWithType(TransferType.DOWNLOAD);
+```
+
+To pause all transfers of any type:
+
+```java
+transferUtility.pauseAllWithType(TransferType.ANY);
+```
+
+Android - Kotlin
+
+Transfers can be paused using the `pause(transferId)` method. If your app is terminated, crashes, or loses Internet connectivity, transfers are automatically paused.
+
+The `transferId` can be retrieved from the `TransferObserver` object as described in :ref:`native-track-progress-and-completion-of-a-transfer`.
+
+To pause a single transfer:
+
+```kotlin
+transferUtility.pause(idOfTransferToBePaused);
+```
+
+To pause all uploads:
+
+```kotlin
+transferUtility.pauseAllWithType(TransferType.UPLOAD);
+```
+
+To pause all downloads:
+
+```kotlin
+transferUtility.pauseAllWithType(TransferType.DOWNLOAD);
+```
+
+To pause all transfers of any type:
+
+```kotlin
+transferUtility.pauseAllWithType(TransferType.ANY);
+```
+
+iOS - Swift
+
+To pause or suspend a transfer, retain references to `AWSS3TransferUtilityUploadTask`, `AWSS3TransferUtilityMultiPartUploadTask` or `AWSS3TransferUtilityDownloadTask` .
+
+As described in the previous section :ref:`native-track-progress-and-completion-of-a-transfer`, the variable `refUploadTask` is a reference to the `UploadTask` object that is retrieved from the `continueWith` block of an upload operation that is invoked through `transferUtility.uploadData`.
+
+To pause a transfer, use the `suspend` method:
+
+```swift
+refUploadTask.suspend()
+```
+
+## Resume a Transfer
+
+Android - Java
+
+In the case of a loss in network connectivity, transfers will automatically resume when network connectivity is restored. If the app crashed or was terminated by the operating system, transfers can be resumed with the `resume(transferId)` method.
+
+The `transferId` can be retrieved from the `TransferObserver` object as described in :ref:`native-track-progress-and-completion-of-a-transfer`.
+
+To resume a single transfer:
+
+```java
+transferUtility.resume(idOfTransferToBeResumed);
+```
+To resume all uploads:
+
+```java
+transferUtility.resumeAllWithType(TransferType.UPLOAD);
+```
+
+To resume all downloads:
+
+```java
+transferUtility.resumeAllWithType(TransferType.DOWNLOAD);
+```
+
+To resume all transfers of any type:
+
+```java
+transferUtility.resumeAllWithType(TransferType.ANY);
+```
+
+Android - Kotlin
+
+In the case of a loss in network connectivity, transfers will automatically resume when network connectivity is restored. If the app crashed or was terminated by the operating system, transfers can be resumed with the `resume(transferId)` method.
+
+The `transferId` can be retrieved from the `TransferObserver` object as described in :ref:`native-track-progress-and-completion-of-a-transfer`.
+
+To resume a single transfer:
+
+```kotlin
+transferUtility.resume(idOfTransferToBeResumed);
+```
+
+To resume all uploads:
+
+```kotlin
+
+transferUtility.resumeAllWithType(TransferType.UPLOAD);
+```
+
+To resume all downloads:
+
+```kotlin
+
+transferUtility.resumeAllWithType(TransferType.DOWNLOAD);
+```
+
+To resume all transfers of any type:
+
+```kotlin
+
+transferUtility.resumeAllWithType(TransferType.ANY);
+```
+
+iOS - Swift
+
+To resume an upload or a download operation, retain references to `AWSS3TransferUtilityUploadTask`, `AWSS3TransferUtilityMultiPartUploadTask` or `AWSS3TransferUtilityDownloadTask`.
+
+As described in the previous section :ref:`native-track-progress-and-completion-of-a-transfer`, the variable `refUploadTask` is a reference to the `UploadTask` object that is retrieved from the `continueWith` block of an upload operation that is invoked through `transferUtility.uploadData`.
+
+To resume a transfer, use the `resume` method:
+
+```swift
+
+refUploadTask.resume()
+```
+
+## Cancel a Transfer
+
+Android - Java
+To cancel an upload, call cancel() or cancelAllWithType() on the `TransferUtility` object.
+
+The `transferId` can be retrieved from the `TransferObserver` object as described in :ref:`native-track-progress-and-completion-of-a-transfer`.
+
+To cancel a single transfer, use:
+
+```java
+
+transferUtility.cancel(idToBeCancelled);
+```
+
+To cancel all transfers of a certain type, use:
+
+```java
+
+transferUtility.cancelAllWithType(TransferType.DOWNLOAD);
+```
+Android - Kotlin
+
+To cancel an upload, call cancel() or cancelAllWithType() on the `TransferUtility` object.
+
+The `transferId` can be retrieved from the `TransferObserver` object as described in :ref:`native-track-progress-and-completion-of-a-transfer`.
+
+To cancel a single transfer, use:
+
+```kotlin
+
+transferUtility.cancel(idToBeCancelled);
+```
+To cancel all transfers of a certain type, use:
+
+```kotlin
+
+transferUtility.cancelAllWithType(TransferType.DOWNLOAD);
+```
+
+iOS - Swift
+
+To cancel an upload or a download operation, retain references to `AWSS3TransferUtilityUploadTask`, `AWSS3TransferUtilityMultiPartUploadTask` and `AWSS3TransferUtilityDownloadTask`.
+
+As described in the previous section :ref:`native-track-progress-and-completion-of-a-transfer`, the variable `refUploadTask` is a reference to the `UploadTask` object that is retrieved from the `continueWith` block of an upload operation that is invoked through `transferUtility.uploadData`.
+
+To cancel a transfer, use the `cancel` method:
+
+```swift
+
+refUploadTask.cancel()
+```
+
+## Background Transfers
+
+The SDK supports uploading to and downloading from Amazon S3 while your app is running in the background.
+
+Android - Java
+No additional work is needed to use this feature. As long as your app is present in the background a transfer that is in progress will continue.
+
+Android - Kotlin
+No additional work is needed to use this feature. As long as your app is present in the background a transfer that is in progress will continue.
+
+iOS - Swift
+**Configure the Application Delegate**
+
+The `TransferUtility` for iOS uses NSURLSession background transfers to continue data transfers even when your app moves to the background. Call the following method in the `- application:handleEventsForBackgroundURLSession: completionHandler:` of your application delegate.
+When the app moves the foreground, the delegate enables iOS to notify TransferUtility that a transfer has completed.
+
+```swift
+
+func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {
+ // Store the completion handler.
+ AWSS3TransferUtility.interceptApplication(application, handleEventsForBackgroundURLSession: identifier, completionHandler: completionHandler)
+}
+```
+
+**Manage a Transfer with the App in the Foreground**
+
+To manage transfers for an app that has moved from the background to the foreground, retain references to `AWSS3TransferUtilityUploadTask`, `AWSS3TransferUtilityMultiPartUploadTask` and `AWSS3TransferUtilityDownloadTask`. Call suspend, resume, or cancel methods on those task references. The following example shows how to suspend a transfer when the app is about to be terminated.
+
+```swift
+transferUtility.uploadFile(fileURL,
+ bucket: S3BucketName,
+ key: S3UploadKeyName,
+ contentType: "image/png",
+ expression: nil,
+ completionHandler: nil).continueWith {
+ (task) -> AnyObject! in if let error = task.error {
+ print("Error: \(error.localizedDescription)")
+ }
+
+ if let uploadTask = task.result {
+ uploadTask.suspend()
+ }
+
+ return nil;
+ }
+```
+
+**Manage a Transfer when a Suspended App Returns to the Foreground**
+
+When an app that has initiated a transfer becomes suspended and then returns to the foreground, the transfer may still be in progress or may have completed. In both cases, use the following code to reestablish the progress and completion handler blocks of the app.
+
+This code example is for downloading a file but the same pattern can be used for upload:
+
+You can get a reference to the `AWSS3TransferUtilityUploadTask`, `AWSS3TransferUtilityMultiPartUploadTask` and `AWSS3TransferUtilityDownloadTask` objects from the task.result in continueWith block when you initiate the upload and download respectively. These tasks have a property called taskIdentifier, which uniquely identifies the transfer task object within the `AWSS3TransferUtility`. Your app should persist the identifier through closure and relaunch, so that you can uniquely identify the task objects when the app comes back into the foreground.
+
+```swift
+
+let transferUtility = AWSS3TransferUtility.default()
+
+var uploadProgressBlock: AWSS3TransferUtilityProgressBlock? = {(task: AWSS3TransferUtilityTask, progress: Progress) in
+ DispatchQueue.main.async {
+ // Handle progress feedback, e.g. update progress bar
+ }
+}
+
+
+var downloadProgressBlock: AWSS3TransferUtilityProgressBlock? = {
+ (task: AWSS3TransferUtilityTask, progress: Progress) in DispatchQueue.main.async {
+ // Handle progress feedback, e.g. update progress bar
+ }
+}
+var completionBlockUpload:AWSS3TransferUtilityUploadCompletionHandlerBlock? = {
+ (task, error) in DispatchQueue.main.async {
+ // perform some action on completed upload operation
+ }
+}
+var completionBlockDownload:AWSS3TransferUtilityDownloadCompletionHandlerBlock? = {
+ (task, url, data, error) in DispatchQueue.main.async {
+ // perform some action on completed download operation
+ }
+}
+
+
+
+transferUtility.enumerateToAssignBlocks(forUploadTask: {
+ (task, progress, completion) -> Void in
+
+ let progressPointer = AutoreleasingUnsafeMutablePointer(& uploadProgressBlock)
+
+ let completionPointer = AutoreleasingUnsafeMutablePointer(&completionBlockUpload)
+
+ // Reassign your progress feedback
+ progress?.pointee = progressPointer.pointee
+
+ // Reassign your completion handler.
+ completion?.pointee = completionPointer.pointee
+
+}, downloadTask: {
+ (task, progress, completion) -> Void in
+
+ let progressPointer = AutoreleasingUnsafeMutablePointer(&downloadProgressBlock)
+
+ let completionPointer = AutoreleasingUnsafeMutablePointer(&completionBlockDownload)
+
+ // Reassign your progress feedback
+ progress?.pointee = progressPointer.pointee
+
+ // Reassign your completion handler.
+ completion?.pointee = completionPointer.pointee
+})
+
+ if let downloadTask = task.result {
+ // Do something with downloadTask.
+}
+```
+
+## Advanced Transfer Methods
+
+### Transfer with Object Metadata
+
+Android - Java
+
+To upload a file with metadata, use the `ObjectMetadata` object. Create a `ObjectMetadata` object and add in the metadata headers and pass it to the upload function.
+
+```java
+
+import com.amazonaws.services.s3.model.ObjectMetadata;
+
+ObjectMetadata myObjectMetadata = new ObjectMetadata();
+
+//create a map to store user metadata
+Map userMetadata = new HashMap();
+userMetadata.put("myKey","myVal");
+
+//call setUserMetadata on our ObjectMetadata object, passing it our map
+myObjectMetadata.setUserMetadata(userMetadata);
+```
+
+Then, upload an object along with its metadata:
+
+```java
+
+TransferObserver observer = transferUtility.upload(
+ MY_BUCKET, /* The bucket to upload to */
+ OBJECT_KEY, /* The key for the uploaded object */
+ MY_FILE, /* The file where the data to upload exists */
+ myObjectMetadata /* The ObjectMetadata associated with the object*/
+);
+```
+
+To download the meta, use the S3 `getObjectMetadata` method. For more information, see the [API Reference] (http://docs.aws.amazon.com/AWSAndroidSDK/latest/javadoc/com/amazonaws/services/s3/AmazonS3Client.html#getObjectMetadata%28com.amazonaws.services.s3.model.GetObjectMetadataRequest%29).
+
+Android - Kotlin
+
+To upload a file with metadata, use the `ObjectMetadata` object. Create a `ObjectMetadata` object and add in the metadata headers and pass it to the upload function.
+
+```kotlin
+
+import com.amazonaws.services.s3.model.ObjectMetadata;
+
+val myObjectMetadata = new ObjectMetadata()
+myObjectMetadata.userMetadata = mapOf("myKey" to "myVal")
+```
+
+Then, upload an object along with its metadata:
+
+```kotlin
+
+val observer = transferUtility.upload(
+ MY_BUCKET, /* The bucket to upload to */
+ OBJECT_KEY, /* The key for the uploaded object */
+ MY_FILE, /* The file where the data to upload exists */
+ myObjectMetadata /* The ObjectMetadata associated with the object*/
+)
+```
+
+To download the meta, use the S3 `getObjectMetadata` method. For more information, see the [API Reference] (http://docs.aws.amazon.com/AWSAndroidSDK/latest/javadoc/com/amazonaws/services/s3/AmazonS3Client.html#getObjectMetadata%28com.amazonaws.services.s3.model.GetObjectMetadataRequest%29).
+
+iOS - Swift
+
+`AWSS3TransferUtilityUploadExpression` and `AWSS3TransferUtilityMultiPartUploadExpression` contain the method `setValue:forRequestHeader` where you can pass in metadata to Amazon S3. This example demonstrates passing in the Server-side Encryption Algorithm as a request header in uploading data to S3 using MultiPart.
+
+```swift
+
+let data: Data = Data() // The data to upload
+
+let uploadExpression = AWSS3TransferUtilityMultiPartUploadExpression()
+uploadExpression.setValue("AES256", forRequestHeader: "x-amz-server-side-encryption-customer-algorithm")
+uploadExpression.progressBlock = {(task, progress) in DispatchQueue.main.async(execute: {
+ // Do something e.g. Update a progress bar.
+ })
+}
+
+let transferUtility = AWSS3TransferUtility.default()
+
+transferUtility.uploadUsingMultiPart(data:data,
+ bucket: "S3BucketName",
+ key: "S3UploadKeyName",
+ contentType: "text/plain",
+ expression: uploadExpression,
+ completionHandler: nil).continueWith { (task) -> AnyObject! in
+ if let error = task.error {
+ print("Error: \(error.localizedDescription)")
+ }
+
+ return nil;
+ }
+```
+
+### Transfer with Access Control List
+
+Android - Java
+
+To upload a file with Access Control List, use the `CannedAccessControlList` object. The [CannedAccessControlList] (http://docs.aws.amazon.com/AWSAndroidSDK/latest/javadoc/com/amazonaws/services/s3/model/CannedAccessControlList.html) specifies the constants defining a canned access control list. For example, if you use [CannedAccessControlList.PublicRead] (http://docs.aws.amazon.com/AWSAndroidSDK/latest/javadoc/com/amazonaws/services/s3/model/CannedAccessControlList.html#PublicRead) , this specifies the owner is granted `Permission.FullControl` and the `GroupGrantee.AllUsers` group grantee is granted Permission.Read access.
+
+Then, upload an object along with its ACL:
+
+```java
+
+TransferObserver observer = transferUtility.upload(
+ MY_BUCKET, /* The bucket to upload to */
+ OBJECT_KEY, /* The key for the uploaded object */
+ MY_FILE, /* The file where the data to upload exists */
+ CannedAccessControlList.PublicRead /* Specify PublicRead ACL for the object in the bucket. */
+);
+```
+
+Android - Kotlin
+
+To upload a file with Access Control List, use the `CannedAccessControlList` object. The [CannedAccessControlList] (http://docs.aws.amazon.com/AWSAndroidSDK/latest/javadoc/com/amazonaws/services/s3/model/CannedAccessControlList.html) specifies the constants defining a canned access control list. For example, if you use [CannedAccessControlList.PublicRead] (http://docs.aws.amazon.com/AWSAndroidSDK/latest/javadoc/com/amazonaws/services/s3/model/CannedAccessControlList.html#PublicRead) , this specifies the owner is granted `Permission.FullControl` and the `GroupGrantee.AllUsers` group grantee is granted Permission.Read access.
+
+Then, upload an object along with its ACL:
+
+```kotlin
+
+val observer = transferUtility.upload(
+ MY_BUCKET, /* The bucket to upload to */
+ OBJECT_KEY, /* The key for the uploaded object */
+ MY_FILE, /* The file where the data to upload exists */
+ CannedAccessControlList.PublicRead /* Specify PublicRead ACL for the object in the bucket. */
+)
+```
+
+iOS - Swift
+
+To upload a file and specify permissions for it, you can use predefined grants, also known as canned ACLs. The following code shows you how to setup a file with publicRead access using the AWSS3 client.
+
+
+```swift
+//Create a AWSS3PutObjectRequest object and setup the content, bucketname, key on it.
+//use the .acl method to specify the ACL for the file
+let s3: AWSS3 = AWSS3.default()
+
+let putObjectRequest: AWSS3PutObjectRequest! = AWSS3PutObjectRequest()
+let content = "testObjectData"
+putObjectRequest.acl = AWSS3ObjectCannedACL.publicRead
+putObjectRequest.bucket = "bucket name"
+putObjectRequest.key = "file name"
+putObjectRequest.body = content
+putObjectRequest.contentLength = content.count as NSNumber
+putObjectRequest.contentType = "text/plain";
+
+s3.putObject(putObjectRequest, completionHandler: { (putObjectOutput:AWSS3PutObjectOutput? , error: Error? ) in
+ if let output = putObjectOutput {
+ print (output)
+ }
+
+ if let error = error {
+ print (error)
+ }
+})
+```
+
+### Transfer Utility Options
+
+Android - Java
+You can use the `TransferUtilityOptions` object to customize the operations of the `TransferUtility`.
+
+**TransferThreadPoolSize**
+This parameter will let you specify the number of threads in the thread pool for transfers. By increasing the number of threads, you will be able to increase the number of parts of a multi-part upload that will be uploaded in parallel. By default, this is set to 2 * (N + 1), where N is the number of available processors on the mobile device. The minimum allowed value is 2.
+
+```java
+TransferUtilityOptions options = new TransferUtilityOptions();
+options.setTransferThreadPoolSize(8);
+
+TransferUtility transferUtility = TransferUtility.builder()
+ // Pass-in S3Client, Context, AWSConfiguration/DefaultBucket Name
+ .transferUtilityOptions(options)
+ .build();
+```
+
+**TransferServiceCheckTimeInterval**
+The `TransferUtility` monitors each on-going transfer by checking its status periodically. If a stalled transfer is detected, it will be automatically resumed by the `TransferUtility`. The TransferServiceCheckTimeInterval option allows you to set the time interval
+between the status checks. It is specified in milliseconds and set to 60,000 by default.
+
+```java
+TransferUtilityOptions options = new TransferUtilityOptions();
+options.setTransferServiceCheckTimeInterval(2 * 60 * 1000); // 2-minutes
+
+TransferUtility transferUtility = TransferUtility.builder()
+ // Pass-in S3Client, Context, AWSConfiguration/DefaultBucket Name
+ .transferUtilityOptions(options)
+ .build();
+```
+
+Android - Kotlin
+You can use the `TransferUtilityOptions` object to customize the operations of the `TransferUtility`.
+
+**TransferThreadPoolSize**
+This parameter will let you specify the number of threads in the thread pool for transfers. By increasing the number of threads, you will be able to increase the number of parts of a multi-part upload that will be uploaded in parallel. By default, this is set to 2 * (N + 1), where N is the number of available processors on the mobile device. The minimum allowed value is 2.
+
+```kotlin
+
+val options = new TransferUtilityOptions().apply {
+ transferThreadPoolSize = 8
+}
+
+val transferUtility = TransferUtility.builder()
+ // Pass-in S3Client, Context, AWSConfiguration/DefaultBucket Name
+ .transferUtilityOptions(options)
+ .build()
+```
+
+**TransferServiceCheckTimeInterval**
+The `TransferUtility` monitors each on-going transfer by checking its status periodically. If a stalled transfer is detected, it will be automatically resumed by the `TransferUtility`. The TransferServiceCheckTimeInterval option allows you to set the time interval
+between the status checks. It is specified in milliseconds and set to 60,000 by default.
+
+```kotlin
+
+val options = new TransferUtilityOptions().apply {
+ transferServiceCheckTimeInterval = 2 * 60 * 1000 // 2-minutes
+}
+
+val transferUtility = TransferUtility.builder()
+ // Pass-in S3Client, Context, AWSConfiguration/DefaultBucket Name
+ .transferUtilityOptions(options)
+ .build()
+```
+
+iOS - Swift
+You can use the `AWSS3TransferUtilityConfiguration` object to configure the operations of the `TransferUtility`.
+
+**isAccelerateModeEnabled**
+The isAccelerateModeEnabled option lets you to upload and download content from a bucket that has Transfer Acceleration enabled on it. See https://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html for information on how to enable transfer acceleration for your bucket.
+
+This option is set to false by default.
+
+```swift
+//Setup credentials
+let credentialProvider = AWSCognitoCredentialsProvider(regionType: YOUR-IDENTITY-POOL-REGION, identityPoolId: "YOUR-IDENTITY-POOL-ID")
+
+//Setup the service configuration
+let configuration = AWSServiceConfiguration(region: .USEast1, credentialsProvider: credentialProvider)
+
+//Setup the transfer utility configuration
+let tuConf = AWSS3TransferUtilityConfiguration()
+tuConf.isAccelerateModeEnabled = true
+
+
+//Register a transfer utility object
+AWSS3TransferUtility.register(
+ with: configuration!,
+ transferUtilityConfiguration: tuConf,
+ forKey: "transfer-utility-with-advanced-options"
+)
+```
+
+//Look up the transfer utility object from the registry to use for your transfers.
+let transferUtility = AWSS3TransferUtility.s3TransferUtility(forKey: "transfer-utility-with-advanced-options")
+
+* `YOUR-IDENTITY-POOL-REGION` should be in the form of `.USEast1`
+
+* `YOUR-IDENTITY-POOL-ID` should be in the form of `us-east-1:01234567-yyyy-0123-xxxx-012345678901`
+
+**retryLimit**
+The retryLimit option allows you to specify the number of times the TransferUtility will retry a transfer when it encounters an error during the transfer. By default, it is set to 0, which means that there will be no retries.
+
+```swift
+
+tuConf.retryLimit = 5
+```
+
+**multiPartConcurrencyLimit**
+The multiPartConcurrencyLimit option allows you to specify the number of parts that will be uploaded in parallel for a MultiPart upload request. By default, this is set to 5.
+
+```swift
+
+tuConf.multiPartConcurrencyLimit = 3
+```
+
+## More Transfer Examples
+
+This section provides descriptions and abbreviated examples of the aspects of each type of transfer that are unique. For information about typical code surrounding the following snippets see `native-track-progress-and-completion-of-a-transfer`.
+
+### Downloading to a File
+
+The following code shows how to download an Amazon S3 Object to a local file.
+
+Android - Java
+
+```java
+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 download.
+ }
+ }
+
+ @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
+ }
+
+});
+```
+
+Android - Kotlin
+
+```kotlin
+val observer = transferUtility.download(
+ "s3Folder/s3Key.txt",
+ new File("/path/to/file/localFile.txt"))
+observer.transferListener = object : TransferListener() {
+ override fun onStateChanged(id: int, state: TransferState) {
+ if (state == TransferState.COMPLETED) {
+ // Handle a completed download
+ }
+ }
+
+ override fun onProgressChanged(id: Int, current: Long, total: Long) {
+ val done = ((current / total) * 100.0) as Int
+ // Do something
+ }
+
+ override fun onError(id: Int, ex: Exception) {
+ // Do something
+ }
+}
+```
+
+iOS - Swift
+
+```swift
+let fileURL = // The file URL of the download destination.
+
+let transferUtility = AWSS3TransferUtility.default()
+transferUtility.download(
+ to: fileURL
+ bucket: S3BucketName,
+ key: S3DownloadKeyName,
+ 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;
+ }
+```
+
+### Uploading Binary Data to a File
+
+Android - Java
+Use the following code to upload binary data to a file in Amazon S3.
+
+```java
+TransferObserver uploadObserver =
+ transferUtility.upload(
+ "s3Folder/s3Key.bin",
+ new File("/path/to/file/localFile.bin"));
+
+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
+ }
+
+});
+```
+
+Android - Kotlin
+Use the following code to upload binary data to a file in Amazon S3.
+
+```kotlin
+val observer = transferUtility.upload(
+ "s3Folder/s3Key.bin",
+ new File("/path/to/file/localFile.bin"))
+observer.transferListener = object : TransferListener() {
+ override fun onStateChanged(id: int, state: TransferState) {
+ if (state == TransferState.COMPLETED) {
+ // Handle a completed download
+ }
+ }
+
+ override fun onProgressChanged(id: Int, current: Long, total: Long) {
+ val done = ((current / total) * 100.0) as Int
+ // Do something
+ }
+
+ override fun onError(id: Int, ex: Exception) {
+ // Do something
+ }
+}
+```
+
+iOS - Swift
+To upload a binary data to a file, you have to make sure to set the appropriate content type in the uploadData method of the TransferUtility. In the example below, we are uploading a PNG image to S3.
+
+```swift
+
+let data: Data = Data() // The data to upload
+
+let transferUtility = AWSS3TransferUtility.default()
+transferUtility.uploadData(data,
+ bucket: S3BucketName,
+ key: S3UploadKeyName,
+ contentType: "image/png",
+ 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;
+ }
+```
+
+### Downloading Binary Data to a File
+
+The following code shows how to download a binary file.
+
+Android - Java
+```java
+
+TransferObserver downloadObserver =
+ transferUtility.download(
+ "s3Folder/s3Key.bin",
+ new File("/path/to/file/localFile.bin"));
+
+downloadObserver.setTransferListener(new TransferListener() {
+
+ @Override
+ public void onStateChanged(int id, TransferState state) {
+ if (TransferState.COMPLETED == state) {
+ // Handle a completed download.
+ }
+ }
+ @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
+ }
+
+});
+```
+
+Android - Kotlin
+```kotlin
+
+val observer = transferUtility.download(
+ "s3Folder/s3Key.bin",
+ new File("/path/to/file/localFile.bin"))
+observer.transferListener = object : TransferListener() {
+ override fun onStateChanged(id: int, state: TransferState) {
+ if (state == TransferState.COMPLETED) {
+ // Handle a completed download
+ }
+ }
+
+ override fun onProgressChanged(id: Int, current: Long, total: Long) {
+ val done = ((current / total) * 100.0) as Int
+ // Do something
+ }
+
+ override fun onError(id: Int, ex: Exception) {
+ // Do something
+ }
+}
+```
+iOS - Swift
+```swift
+
+let fileURL = // The file URL of the download destination
+let transferUtility = AWSS3TransferUtility.default()
+transferUtility.downloadData(
+ fromBucket: S3BucketName,
+ key: S3DownloadKeyName,
+ 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;
+ }
+```
+
+## Limitations
+
+Android - Java
+
+If you expect your app to perform transfers that take longer than 50 minutes, use `AmazonS3Client (http://docs.aws.amazon.com/AWSAndroidSDK/latest/javadoc/com/amazonaws/services/s3/AmazonS3Client.html) instead of `TransferUtility (http://docs.aws.amazon.com/AWSAndroidSDK/latest/javadoc/com/amazonaws/mobileconnectors/s3/transferutility/TransferUtility.html).
+
+`TransferUtility` generates Amazon S3 pre-signed URLs to use for background data transfer. Using |COG| Identity, you receive AWS temporary credentials. The credentials are valid for up to 60 minutes. Generated Amazon S3 pre-signed URLs cannot last longer than that time. Because of this limitation, the Amazon S3 Transfer Utility enforces 50 minute transfer timeouts, leaving a 10 minute buffer before AWS temporary credentials are regenerated. After **50 minutes**, you receive a transfer failure.
+
+Android - Kotlin
+
+If you expect your app to perform transfers that take longer than 50 minutes, use `AmazonS3Client (http://docs.aws.amazon.com/AWSAndroidSDK/latest/javadoc/com/amazonaws/services/s3/AmazonS3Client.html) instead of `TransferUtility (http://docs.aws.amazon.com/AWSAndroidSDK/latest/javadoc/com/amazonaws/mobileconnectors/s3/transferutility/TransferUtility.html).
+
+`TransferUtility` generates Amazon S3 pre-signed URLs to use for background data transfer. Using |COG| Identity, you receive AWS temporary credentials. The credentials are valid for up to 60 minutes. Generated Amazon S3 pre-signed URLs cannot last longer than that time. Because of this limitation, the Amazon S3 Transfer Utility enforces 50 minute transfer timeouts, leaving a 10 minute buffer before AWS temporary credentials are regenerated. After **50 minutes**, you receive a transfer failure.
+
+iOS - Swift
+
+If you expect your app to perform transfers that take longer than 50 minutes, use `AWSS3 (https://docs.aws.amazon.com/AWSiOSSDK/latest/Classes/AWSS3.html) instead of `AWSS3TransferUtility (https://docs.aws.amazon.com/AWSiOSSDK/latest/Classes/AWSS3TransferUtility.html).
+
+`AWSS3TransferUtility` generates Amazon S3 pre-signed URLs to use for background data transfer. Using Amazon Cognito Identity, you receive AWS temporary credentials. The credentials are valid for up to 60 minutes. At the same time, generated S3 pre-signed URLs cannot last longer than that time. Because of this limitation, the AWSS3TransferUtility enforces **50 minutes** transfer timeout, leaving a 10 minute buffer before AWS temporary credentials are regenerated. After 50 minutes, you receive a transfer failure.
diff --git a/android/media/facebook-app-id-console-entry.png b/android/media/facebook-app-id-console-entry.png
new file mode 100755
index 00000000000..43b30109c57
Binary files /dev/null and b/android/media/facebook-app-id-console-entry.png differ
diff --git a/android/media/getting-started-analytics.png b/android/media/getting-started-analytics.png
new file mode 100755
index 00000000000..5c98bf6cb01
Binary files /dev/null and b/android/media/getting-started-analytics.png differ
diff --git a/android/media/new-facebook-add-platform-android.png b/android/media/new-facebook-add-platform-android.png
new file mode 100755
index 00000000000..6ccfc0deb10
Binary files /dev/null and b/android/media/new-facebook-add-platform-android.png differ
diff --git a/android/media/new-facebook-add-platform.png b/android/media/new-facebook-add-platform.png
new file mode 100755
index 00000000000..cdcc6f326dd
Binary files /dev/null and b/android/media/new-facebook-add-platform.png differ
diff --git a/android/media/new-facebook-add-testers.png b/android/media/new-facebook-add-testers.png
new file mode 100755
index 00000000000..8abf88e23eb
Binary files /dev/null and b/android/media/new-facebook-add-testers.png differ
diff --git a/android/media/new-facebook-app-id.png b/android/media/new-facebook-app-id.png
new file mode 100755
index 00000000000..67c5ad7149a
Binary files /dev/null and b/android/media/new-facebook-app-id.png differ
diff --git a/android/media/new-facebook-app-new-app-id.png b/android/media/new-facebook-app-new-app-id.png
new file mode 100755
index 00000000000..b95f1829640
Binary files /dev/null and b/android/media/new-facebook-app-new-app-id.png differ
diff --git a/android/media/new-facebook-app.png b/android/media/new-facebook-app.png
new file mode 100755
index 00000000000..53e29bf2f57
Binary files /dev/null and b/android/media/new-facebook-app.png differ
diff --git a/android/push-notifications.md b/android/push-notifications.md
new file mode 100755
index 00000000000..ce577587576
--- /dev/null
+++ b/android/push-notifications.md
@@ -0,0 +1,266 @@
+# Add Push Notifications to Your Mobile App with Amazon Pinpoint
+
+## Overview
+
+Enable your users to receive mobile push messages sent from the Apple (APNs) and Google (FCM/GCM) platforms. The CLI deploys your push notification backend using [Amazon Pinpoint](http://docs.aws.amazon.com/pinpoint/latest/developerguide/).
+You can also create Amazon Pinpoint campaigns that tie user behavior to push or other forms of messaging.
+
+## Set Up Your Backend
+
+1. Complete the [Get Started](./getting-started) steps before you proceed.
+
+2. Use the CLI to add storage to your cloud-enabled backend and app.
+
+ In a terminal window, navigate to your project folder (the folder that typically contains your project level :file:`build.gradle`), and add the SDK to your app.
+
+ ```bash
+ $ cd ./YOUR_PROJECT_FOLDER
+ $ amplify add notifications
+ ```
+
+3. Set up your backend to support receiving push notifications:
+
+ - Choose Firebase Cloud Messaging (FCM).
+
+ ```
+ > FCM
+ ```
+
+ - Provide your ApiKey. The FCM console refers to this value as `ServerKey`. For information on getting an FCM ApiKey, see [Setting Up Android Push Notifications](http://docs.aws.amazon.com/pinpoint/latest/developerguide/mobile-push-android.html).
+
+ Use the steps in the next section to connect your app to your backend.
+
+## Connect to Your Backend
+
+Use the following steps to connect add push notification backend services to your app.
+
+1. Add the following dependencies and plugin to your `app/build.gradle`:
+
+ ```groovy
+ dependencies {
+ // Overrides an auth dependency to ensure correct behavior
+ implementation 'com.google.android.gms:play-services-auth:15.0.1'
+
+ implementation 'com.google.firebase:firebase-core:16.0.1'
+ implementation 'com.google.firebase:firebase-messaging:17.3.0'
+
+ implementation 'com.amazonaws:aws-android-sdk-pinpoint:2.6.+'
+ implementation ('com.amazonaws:aws-android-sdk-mobile-client:2.6.+@aar') { transitive = true }
+ }
+
+ apply plugin: 'com.google.gms.google-services'
+ ```
+
+2. Add the following to your project level :file:`build.gradle`. Make sure that you specify the `google` repository:
+
+ ```groovy
+ buildscript {
+ dependencies {
+ classpath 'com.google.gms:google-services:4.0.1'
+ }
+ }
+
+ allprojects {
+ repositories {
+ google()
+ }
+ }
+ ```
+
+3. `AndroidManifest.xml` must contain the definition of the following service for PushListenerService in the application tag:
+
+ ```xml
+
+
+
+
+
+ ```
+
+4. Create an Amazon Pinpoint client in the location of your push notification code.
+
+ ```java
+ import android.content.BroadcastReceiver;
+ import android.content.Context;
+ import android.content.Intent;
+ import android.content.IntentFilter;
+ import android.os.Bundle;
+ import android.support.annotation.NonNull;
+ import android.support.v4.content.LocalBroadcastManager;
+ import android.support.v7.app.AlertDialog;
+ import android.support.v7.app.AppCompatActivity;
+ import android.util.Log;
+
+ import com.amazonaws.mobile.client.AWSMobileClient;
+ import com.amazonaws.mobile.client.AWSStartupHandler;
+ import com.amazonaws.mobile.client.AWSStartupResult;
+ import com.amazonaws.mobileconnectors.pinpoint.PinpointConfiguration;
+ import com.amazonaws.mobileconnectors.pinpoint.PinpointManager;
+ import com.google.android.gms.tasks.OnCompleteListener;
+ import com.google.android.gms.tasks.Task;
+ import com.google.firebase.iid.FirebaseInstanceId;
+ import com.google.firebase.iid.InstanceIdResult;
+
+ public class MainActivity extends AppCompatActivity {
+ public static final String TAG = MainActivity.class.getSimpleName();
+
+ private static PinpointManager pinpointManager;
+
+ public static PinpointManager getPinpointManager(final Context applicationContext) {
+ if (pinpointManager == null) {
+ PinpointConfiguration pinpointConfig = new PinpointConfiguration(
+ applicationContext,
+ AWSMobileClient.getInstance().getCredentialsProvider(),
+ AWSMobileClient.getInstance().getConfiguration());
+
+ pinpointManager = new PinpointManager(pinpointConfig);
+
+ FirebaseInstanceId.getInstance().getInstanceId()
+ .addOnCompleteListener(new OnCompleteListener() {
+ @Override
+ public void onComplete(@NonNull Task task) {
+ final String token = task.getResult().getToken();
+ Log.d(TAG, "Registering push notifications token: " + token);
+ pinpointManager.getNotificationClient().registerDeviceToken(token);
+ }
+ });
+ }
+ return pinpointManager;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ // Initialize the AWS Mobile Client
+ AWSMobileClient.getInstance().initialize(this, new AWSStartupHandler() {
+ @Override
+ public void onComplete(AWSStartupResult awsStartupResult) {
+ Log.d(TAG, "AWSMobileClient is instantiated and you are connected to AWS!");
+ }
+ }).execute();
+
+ // Initialize PinpointManager
+ getPinpointManager(getApplicationContext());
+ }
+ }
+ ```
+
+## Add Amazon Pinpoint Targeted and Campaign Push Messaging
+
+The [Amazon Pinpoint console](https://console.aws.amazon.com/pinpoint/) enables you to target your app users with push messaging. You can send individual messages or configure campaigns that target a group of users that match a profile that you define.
+For instance, you could email users that have not used the app in 30 days, or send an SMS to those that frequently use a given feature of your app.
+
+The following steps show how to receive push notifications targeted for your app.
+
+1. Add a push listener service to your app.
+
+ The name of the class must match the push listener service name used in the app manifest.
+ `pinpointManager` is a reference to the static PinpointManager variable declared in
+ the MainActivity shown in a previous step. Use the following steps to detect and display Push
+ Notification in your app.
+
+2. The following push listener code assumes that the app's MainActivity is configured using
+ the manifest setup described in a previous section.
+
+ ```java
+ import android.content.Intent;
+ import android.os.Bundle;
+ import android.support.v4.content.LocalBroadcastManager;
+ import android.util.Log;
+
+ import com.amazonaws.mobileconnectors.pinpoint.targeting.notification.NotificationClient;
+ import com.amazonaws.mobileconnectors.pinpoint.targeting.notification.NotificationDetails;
+ import com.google.firebase.messaging.FirebaseMessagingService;
+ import com.google.firebase.messaging.RemoteMessage;
+
+ import java.util.HashMap;
+
+ public class PushListenerService extends FirebaseMessagingService {
+ public static final String TAG = PushListenerService.class.getSimpleName();
+
+ // Intent action used in local broadcast
+ public static final String ACTION_PUSH_NOTIFICATION = "push-notification";
+ // Intent keys
+ public static final String INTENT_SNS_NOTIFICATION_FROM = "from";
+ public static final String INTENT_SNS_NOTIFICATION_DATA = "data";
+
+ @Override
+ public void onNewToken(String token) {
+ super.onNewToken(token);
+
+ Log.d(TAG, "Registering push notifications token: " + token);
+ MainActivity.getPinpointManager(getApplicationContext()).getNotificationClient().registerDeviceToken(token);
+ }
+
+ @Override
+ public void onMessageReceived(RemoteMessage remoteMessage) {
+ super.onMessageReceived(remoteMessage);
+ Log.d(TAG, "Message: " + remoteMessage.getData());
+
+ final NotificationClient notificationClient = MainActivity.getPinpointManager(getApplicationContext()).getNotificationClient();
+
+ final NotificationDetails notificationDetails = NotificationDetails.builder()
+ .from(remoteMessage.getFrom())
+ .mapData(remoteMessage.getData())
+ .intentAction(NotificationClient.FCM_INTENT_ACTION)
+ .build();
+
+ NotificationClient.CampaignPushResult pushResult = notificationClient.handleCampaignPush(notificationDetails);
+
+ if (!NotificationClient.CampaignPushResult.NOT_HANDLED.equals(pushResult)) {
+ /**
+ The push message was due to a Pinpoint campaign.
+ If the app was in the background, a local notification was added
+ in the notification center. If the app was in the foreground, an
+ event was recorded indicating the app was in the foreground,
+ for the demo, we will broadcast the notification to let the main
+ activity display it in a dialog.
+ */
+ if (NotificationClient.CampaignPushResult.APP_IN_FOREGROUND.equals(pushResult)) {
+ /* Create a message that will display the raw data of the campaign push in a dialog. */
+ final HashMap dataMap = new HashMap<>(remoteMessage.getData());
+ broadcast(remoteMessage.getFrom(), dataMap);
+ }
+ return;
+ }
+ }
+
+ private void broadcast(final String from, final HashMap dataMap) {
+ Intent intent = new Intent(ACTION_PUSH_NOTIFICATION);
+ intent.putExtra(INTENT_SNS_NOTIFICATION_FROM, from);
+ intent.putExtra(INTENT_SNS_NOTIFICATION_DATA, dataMap);
+ LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
+ }
+
+ /**
+ * Helper method to extract push message from bundle.
+ *
+ * @param data bundle
+ * @return message string from push notification
+ */
+ public static String getMessage(Bundle data) {
+ return ((HashMap) data.get("data")).toString();
+ }
+ }
+ ```
+
+3. To create a new campaign to send notifications to your app from the Amazon Pinpoint console run the following command from your app project folder.
+
+ ```bash
+ $ amplify notifications console
+ ```
+
+4. Provide a campaign name, choose `Next`, choose `Filter by standard attributes`, and then choose `android` as the platform.
+
+5. You should see 1 device as a targeted endpoint, which is the app we are running on the Android device. Choose the option and then choose `Next Step`.
+
+6. Provide text for a sample title and body for push notification, and then choose `Next Step`.
+
+7. Choose `Immediate`, and then choose `Next Step`.
+
+8. Review the details on the screen, and then choose `Launch Campaign`.
+
+9. A notification should appear on the Android device. You may want to try testing your app receiving notifications when it is in the foreground and when closed.
diff --git a/android/storage.md b/android/storage.md
new file mode 100755
index 00000000000..dab5bf32e67
--- /dev/null
+++ b/android/storage.md
@@ -0,0 +1,384 @@
+# Add User File Storage to Your Mobile App with Amazon S3
+
+# Note
+
+`TransferService` in version `2.7.0` will only have the responsibility of listening to network connectivity changes. When network goes offline, the transfers that are in progress will be paused. When network comes back online, the transfers that are paused will be resumed. The `TransferService` will not be started or stopped by `TransferUtility` anymore. You have to start `TransferService` manually from your application. A recommended way is to start the service upon Application startup. One way you can do this is to include the following line in the :code:`onCreate` method of your app's Application class.
+
+```java
+getApplicationContext().startService(new Intent(getApplicationContext(), TransferService.class));
+```
+
+See [Limitations of TransferUtility](transfer-utility-limitations) for further details.
+
+# Overview
+
+Enable your app to store and retrieve user files from cloud storage with the permissions model that suits your purpose. The CLI deploys and configures cloud storage buckets using [Amazon Simple Storage Service](http://docs.aws.amazon.com/AmazonS3/latest/dev/).
+
+## Storage Access
+
+The CLI configures three different access levels on the storage bucket; public, protected and private.
+
+- Files with public access level can be accessed by all users who are using your app. In S3, they are stored under the ``public/`` path in your S3 bucket.
+
+- Files with protected access level are readable by all users but writable only by the creating user. In S3, they are stored under ``protected/{user_identity_id}/`` where the user_identity_id corresponds to a unique Amazon Cognito Identity ID for that user.
+
+- Files with private access level are only accessible for specific authenticated users only. In S3, they are stored under ``private/{user_identity_id}/`` where the user_identity_id corresponds to a unique Amazon Cognito Identity ID for that user.
+
+## Set Up Your Backend
+
+1. Complete the [Get Started](./getting-started) steps before you proceed.
+
+2. Use the CLI to add storage to your cloud-enabled backend and app.
+
+ In a terminal window, navigate to your project folder (the folder that typically contains your project level build.gradle), and add the SDK to your app.
+
+ ```bash
+ $ cd ./YOUR_PROJECT_FOLDER
+ $ amplify add storage
+ ```
+
+ In a terminal window, navigate to your project folder (the folder that contains your app `.xcodeproj` file), and add the SDK to your app.
+
+ ```bash
+ $ cd ./YOUR_PROJECT_FOLDER
+ $ amplify add storage
+ ```
+
+3. Choose `Content` as your storage service.
+
+ `❯ Content (Images, audio, video, etc.)`
+
+4. The CLI walks you through the options to enable Auth (if not enabled previously), to name your S3 bucket, and to decide who should have access (select `Auth and guest users` and `read/write` for both auth and guest users).
+
+5. Confirm that you have storage and auth set up.
+
+ ```bash
+ $ amplify status
+ | Category | Resource name | Operation | Provider plugin |
+ | --------- | --------------- | --------- | ----------------- |
+ | Auth | cognito2e202b09 | Create | awscloudformation |
+ | Storage | sabc0123de | Create | awscloudformation |
+ ```
+6. To create your backend run:
+
+ ```bash
+ $ amplify push
+ ```
+
+ The CLI will create the awsconfiguration.json file in your project's `res/raw` directory.
+
+## Connect to Your Backend
+
+Use the following steps to connect add file storage backend services to your app.
+
+1. Add the following to :file:`app/build.gradle` (Module:app):
+
+ ```groovy
+ dependencies {
+ implementation 'com.amazonaws:aws-android-sdk-s3:2.7.+'
+ implementation ('com.amazonaws:aws-android-sdk-mobile-client:2.7.+@aar') { transitive = true }
+ implementation ('com.amazonaws:aws-android-sdk-auth-userpools:2.7.+@aar') { transitive = true }
+ }
+ ```
+ Perform a `Gradle Sync` to download the AWS Mobile SDK components into your app.
+
+2. Add the following to `AndroidManifest.xml`:
+
+ ```xml
+
+
+
+ ```
+
+## Upload a File
+
+To upload a file to an Amazon S3 bucket, use `AWSMobileClient` to get the `AWSConfiguration` and `AWSCredentialsProvider`,
+and then create the `TransferUtility` object. `AWSMobileClient` expects an activity context for resuming an authenticated session and creating the credentials provider.
+
+The following example shows how to use the `TransferUtility` in the context of an Activity.
+If you are creating `TransferUtility` from an application context, you can construct the `AWSCredentialsProvider` and pass it into `TransferUtility` to use in forming the `AWSConfiguration` object. `TransferUtility` checks the size of the file being uploaded and automatically switches over to using multi-part uploads if the file size exceeds 5 MB.
+
+```java
+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 {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ AWSMobileClient.getInstance().initialize(this).execute();
+ uploadWithTransferUtility();
+ }
+
+ public void uploadWithTransferUtility() {
+
+ TransferUtility transferUtility =
+ TransferUtility.builder()
+ .context(getApplicationContext())
+ .awsConfiguration(AWSMobileClient.getInstance().getConfiguration())
+ .s3Client(new AmazonS3Client(AWSMobileClient.getInstance().getCredentialsProvider()))
+ .build();
+
+ TransferObserver uploadObserver =
+ transferUtility.upload(
+ "public/s3Key.txt",
+ new File("/path/to/file/localFile.txt"));
+
+ // Attach a listener to the observer to get state update and progress notifications
+ 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("YourActivity", "ID:" + id + " bytesCurrent: " + bytesCurrent
+ + " bytesTotal: " + bytesTotal + " " + percentDone + "%");
+ }
+
+ @Override
+ public void onError(int id, Exception ex) {
+ // Handle errors
+ }
+
+ });
+
+ // If you prefer to poll for the data, instead of attaching a
+ // listener, check for the state and progress in the observer.
+ if (TransferState.COMPLETED == uploadObserver.getState()) {
+ // Handle a completed upload.
+ }
+
+ Log.d("YourActivity", "Bytes Transferred: " + uploadObserver.getBytesTransferred());
+ Log.d("YourActivity", "Bytes Total: " + uploadObserver.getBytesTotal());
+ }
+}
+```
+
+```kotlin
+import android.os.Bundle
+import android.support.v7.app.AppCompatActivity
+import android.util.Log
+import com.amazonaws.AmazonServiceException
+import com.amazonaws.mobile.client.AWSMobileClient
+import com.amazonaws.mobileconnectors.s3.transferutility.TransferListener
+import com.amazonaws.mobileconnectors.s3.transferutility.TransferState
+import com.amazonaws.mobileconnectors.s3.transferutility.TransferUtility
+import com.amazonaws.services.s3.AmazonS3Client
+import kotlinx.android.synthetic.main.activity_main.*
+import java.io.File;
+
+class YourActivity : Activity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ AWSMobileClient.getInstance().initialize(this).execute()
+ uploadWithTransferUtility()
+ }
+
+ fun uploadWithTransferUtility() {
+ val transferUtility = TransferUtility.builder()
+ .context(this.applicationContext)
+ .awsConfiguration(AWSMobileClient.getInstance().configuration)
+ .s3Client(AmazonS3Client(AWSMobileClient.getInstance().credentialsProvider))
+ .build()
+
+ val uploadObserver = transferUtility.upload("public/s3key.txt", File("/path/to/localfile.txt"))
+
+ // Attach a listener to the observer
+ uploadObserver.setTransferListener(object : TransferListener {
+ override fun onStateChanged(id: Int, state: TransferState) {
+ if (state == TransferState.COMPLETED) {
+ // Handle a completed upload
+ }
+ }
+
+ override fun onProgressChanged(id: Int, current: Long, total: Long) {
+ val done = (((current.toDouble() / total) * 100.0).toInt())
+ Log.d("Your Activity", "UPLOAD - - ID: $id, percent done = $done")
+ }
+
+ override fun onError(id: Int, ex: Exception) {
+ Log.d("Your Activity", "UPLOAD ERROR - - ID: $id - - EX: ${ex.message.toString()}")
+ }
+ })
+
+ // If you prefer to long-poll for updates
+ if (uploadObserver.state == TransferState.COMPLETED) {
+ /* Handle completion */
+ }
+
+ val bytesTransferred = uploadObserver.bytesTransferred
+ }
+}
+```
+
+## Download a File
+
+To download a file from an Amazon S3 bucket, use `AWSMobileClient`
+to get the `AWSConfiguration` and `AWSCredentialsProvider` to create the `TransferUtility` object.
+`AWSMobileClient` expects an activity context for resuming an authenticated session and creating the :code:`AWSCredentialsProvider`.
+
+The following example shows how to use the `TransferUtility` in the context of an Activity.
+If you are creating `TransferUtility` from an application context, you can construct the `AWSCredentialsProvider` and
+ pass it into `TransferUtility` to use in forming the `AWSConfiguration` object.
+
+```java
+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 {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ AWSMobileClient.getInstance().initialize(this).execute();
+ downloadWithTransferUtility();
+ }
+
+ private void downloadWithTransferUtility() {
+
+ TransferUtility transferUtility =
+ TransferUtility.builder()
+ .context(getApplicationContext())
+ .awsConfiguration(AWSMobileClient.getInstance().getConfiguration())
+ .s3Client(new AmazonS3Client(AWSMobileClient.getInstance().getCredentialsProvider()))
+ .build();
+
+ TransferObserver downloadObserver =
+ transferUtility.download(
+ "public/s3Key.txt",
+ new File("/path/to/file/localFile.txt"));
+
+ // Attach a listener to the observer to get state update and progress notifications
+ 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("Your Activity", " ID:" + id + " bytesCurrent: " + bytesCurrent + " bytesTotal: " + bytesTotal + " " + percentDone + "%");
+ }
+
+ @Override
+ public void onError(int id, Exception ex) {
+ // Handle errors
+ }
+
+ });
+
+ // If you prefer to poll for the data, instead of attaching a
+ // listener, check for the state and progress in the observer.
+ if (TransferState.COMPLETED == downloadObserver.getState()) {
+ // Handle a completed upload.
+ }
+
+ Log.d("Your Activity", "Bytes Transferred: " + downloadObserver.getBytesTransferred());
+ Log.d("Your Activity", "Bytes Total: " + downloadObserver.getBytesTotal());
+ }
+}
+```
+
+```kotlin
+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;
+
+class YourActivity : Activity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ AWSMobileClient.getInstance().initialize(this).execute()
+ downloadWithTransferUtility()
+ }
+
+ private fun downloadWithTransferUtility() {
+ val transferUtility = TransferUtility.builder()
+ .context(applicationContext)
+ .awsConfiguration(AWSMobileClient.getInstance().configuration)
+ .s3Client(AmazonS3Client(AWSMobileClient.getInstance().credentialsProvider))
+ .build()
+
+ val downloadObserver = transferUtility.download(
+ "public/s3key.txt",
+ File("/path/to/file/localfile.txt"))
+
+ // Attach a listener to get state updates
+ downloadObserver.setTransferListener(object : TransferListener {
+ override fun onStateChanged(id: Int, state: TransferState) {
+ if (state == TransferState.COMPLETED) {
+ // Handle a completed upload.
+ }
+ }
+
+ override fun onProgressChanged(id: Int, current: Long, total: Long) {
+ try {
+ val done = (((current.toDouble() / total) * 100.0).toInt()) //as Int
+ Log.d("Your Activity", "DOWNLOAD - - ID: $id, percent done = $done")
+ }
+ catch (e: Exception) {
+ Log.e("Your Activity", "Trouble calculating progress percent", e)
+ }
+ }
+
+ override fun onError(id: Int, ex: Exception) {
+ Log.d("Your Activity", "DOWNLOAD ERROR - - ID: $id - - EX: ${ex.message.toString()}")
+ }
+ })
+
+ // If you prefer to poll for the data, instead of attaching a
+ // listener, check for the state and progress in the observer.
+ if (downloadObserver.state == TransferState.COMPLETED) {
+ // Handle a completed upload.
+ }
+
+ Log.d("Your Activity", "Bytes Transferred: ${downloadObserver.bytesTransferred}");
+ }
+}
+```
+
+Next Steps
+==========
+
+* For sample apps that demonstrate TransferUtility capabilities, see [Android S3 TransferUtility Sample](https://github.com/awslabs/aws-sdk-android-samples/tree/master/S3TransferUtilitySample).
+* Looking for Amazon Cognito Sync? If you are a new user, use [AWS AppSync](https://aws.amazon.com/appsync/) instead. AppSync is a new service for synchronizing application data across devices. Like Cognito Sync, AppSync enables synchronization of a user's own data, such as game state or app preferences. AppSync extends these capabilities by allowing multiple users to synchronize and collaborate in real time on shared data, such as a virtual meeting space or chat room. [Start building with AWS AppSync now](https://aws.amazon.com/appsync/)
diff --git a/ios/add-aws-mobile-user-sign-in-customize.md b/ios/add-aws-mobile-user-sign-in-customize.md
new file mode 100755
index 00000000000..7714892643d
--- /dev/null
+++ b/ios/add-aws-mobile-user-sign-in-customize.md
@@ -0,0 +1,65 @@
+# Customize the SDK Sign-In UI
+
+By default, the SDK presents sign-in UI for each sign in provider you enable in your Mobile Hub project (Email and Password, Facebook, Google) with a default look and feel. It knows which provider(s) you chose by reading the :file:`awsconfiguration.json` file you integrated with your app.
+
+To override the defaults, and modify the behavior, look, and feel of the sign-in UI, create an `AuthUIConfiguration` object and set the appropriate properties.
+
+
+iOS - Swift
+
+Create and configure an `AWSAuthUIConfiguration` object and set its properties.
+
+Create and configure an `AuthUIConfiguration` object.
+
+* To present the Email and Password user `SignInUI`, set `enableUserPoolsUI` to `true`.
+
+* To present Facebook or Google user `SignInUI`, add `.addSignInButtonView(class: AWSFacebookSignInButton.self)` or `.addSignInButtonView(class: AWSFacebookSignInButton.self)`.
+
+* To change the logo, use `logoImage`.
+
+* To change the background color, use `backgroundColor`.
+
+* To cancel the sign-in flow, use `canCancel`.
+
+* To change the font in the sign-in views, use the `font` property and pass in the `UIFont` object that represents a font family.
+
+* To draw the `backgroundColor` full screen, use `fullScreenBackgroundColor`.
+
+```swift
+import UIKit
+import AWSAuthUI
+import AWSMobileClient
+import AWSUserPoolsSignIn
+import AWSFacebookSignIn
+import AWSGoogleSignIn
+
+class SampleViewController: UIViewController {
+ override func viewDidLoad() {
+ super.viewDidLoad()
+ if !AWSSignInManager.sharedInstance().isLoggedIn {
+ presentAuthUIViewController()
+ }
+ }
+
+ func presentAuthUIViewController() {
+ let config = AWSAuthUIConfiguration()
+ config.enableUserPoolsUI = true
+ config.addSignInButtonView(class: AWSFacebookSignInButton.self)
+ config.addSignInButtonView(class: AWSGoogleSignInButton.self)
+ config.backgroundColor = UIColor.blue
+ config.font = UIFont (name: "Helvetica Neue", size: 20)
+ config.isBackgroundColorFullScreen = true
+ config.canCancel = true
+
+ AWSAuthUIViewController.presentViewController(
+ with: self.navigationController!,
+ configuration: config, completionHandler: { (provider: AWSSignInProvider, error: Error?) in
+ if error == nil {
+ // SignIn succeeded.
+ } else {
+ // end user faced error while loggin in, take any required action here.
+ }
+ })
+ }
+}
+```
diff --git a/ios/analytics.md b/ios/analytics.md
new file mode 100755
index 00000000000..9a60dc2b66f
--- /dev/null
+++ b/ios/analytics.md
@@ -0,0 +1,170 @@
+# Add Analytics to Your Mobile App with Amazon Pinpoint
+
+## Pinpoint
+
+Gather the data that helps improve your app's usability, monetization, and engagement with your users. The CLI deploys your analytics backend using [Amazon Pinpoint](http://docs.aws.amazon.com/pinpoint/latest/developerguide/welcome.html).
+
+### Set Up Your Backend
+
+1. Complete the [Get Started TODO link](asdf) steps before you proceed.
+
+2. Use the CLI to add analytics to your cloud-enabled backend and app.
+
+ In a terminal window, navigate to your project folder (the folder that typically contains your project level `build.gradle`), and add the SDK to your app.
+
+ ```bash
+ $ cd ./YOUR_PROJECT_FOLDER
+ $ amplify add analytics
+ ```
+
+ In a terminal window, navigate to your project folder (the folder contains your app :file:`.xcodeproj` file), and add the SDK to your app.
+
+ ```bash
+ $ cd ./YOUR_PROJECT_FOLDER
+ $ amplify add analytics
+ ```
+
+3. When configuration for analytics is complete, a message appears confirming that you have configured local CLI metadata for this category. You can confirm this by viewing status.
+
+ ```bash
+ $ amplify status
+ | Category | Resource name | Operation | Provider plugin |
+ | --------- | --------------- | --------- | ----------------- |
+ | Auth | cognitoabcd0123 | Create | awscloudformation |
+ | Analytics | yourprojectname | Create | awscloudformation |
+ ```
+
+4. To create your backend AWS resources run the following:
+
+ ```bash
+ $ amplify push
+ ```
+
+### Connect to Your Backend
+
+Use the following steps to add analytics to your mobile app and monitor the results through Amazon Pinpoint.
+
+#### Add Analytics
+
+Set up AWS Mobile SDK components as follows.
+
+1. The `Podfile` that you configure to install the AWS Mobile SDK must contain:
+
+```
+
+platform :ios, '9.0'
+target :'YourAppName' do
+ use_frameworks!
+
+ pod 'AWSPinpoint', '~> 2.6.13'
+ pod 'AWSMobileClient', '~> 2.6.13'
+
+ # other pods
+
+end
+```
+
+Run `pod install --repo-update` before you continue.
+
+If you encounter an error message that begins `[!] Failed to connect to GitHub to update the CocoaPods/Specs . . .`, and your internet connectivity is working, you may need to [update openssl and Ruby](https://stackoverflow.com/questions/38993527/cocoapods-failed-to-connect-to-github-to-update-the-cocoapods-specs-specs-repo/48962041#48962041).
+
+2. Classes that call Amazon Pinpoint APIs must use the following import statements:
+
+ ```
+ /** start code copy **/
+ import AWSCore
+ import AWSPinpoint
+ import AWSMobileClient
+ /** end code copy **/
+ ```
+
+3. Replace the return statement with following code into the `application(_:didFinishLaunchingWithOptions:)` method of your app's `AppDelegate.swift`.
+
+ ```swift
+ class AppDelegate: UIResponder, UIApplicationDelegate {
+
+ /** start code copy **/
+ var pinpoint: AWSPinpoint?
+ /** end code copy **/
+
+ func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions:
+ [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
+
+ //. . .
+
+ // Initialize Pinpoint
+ /** start code copy **/
+ pinpoint = AWSPinpoint(configuration:
+ AWSPinpointConfiguration.defaultPinpointConfiguration(launchOptions: launchOptions))
+
+ // Create AWSMobileClient to connect with AWS
+ return AWSMobileClient.sharedInstance().interceptApplication(application, didFinishLaunchingWithOptions: launchOptions)
+ /** end code copy **/
+ }
+ }
+ ```
+
+#### Monitor Analytics
+
+Build and run your app to see usage metrics in Amazon Pinpoint. When you run the previous code samples, the console shows a logged Session.
+
+1. To see visualizations of the analytics coming from your app, open your project in the Amazon Pinpoint console by running the following:
+
+ ```bash
+ $ amplify console analytics
+ ```
+
+2. Choose `Analytics` from the icons on the left of the console, and view the graphs of your app's usage. It may take up to 15 minutes for metrics to become visible.
+
+ 
+
+ [Learn more about Amazon Pinpoint](http://docs.aws.amazon.com/pinpoint/latest/developerguide/welcome.html).
+
+### Enable Custom App Analytics
+
+Instrument your code to capture app usage event information, including attributes you define. Use graphs of your custom usage event data in the Amazon Pinpoint console. Visualize how your users' behavior aligns with a model you design using [Amazon Pinpoint Funnel Analytics](https://docs.aws.amazon.com/pinpoint/latest/userguide/analytics-funnels.html), or use [stream the data](https://docs.aws.amazon.com/pinpoint/latest/userguide/analytics-streaming.html) for deeper analysis.
+
+Use the following steps to implement Amazon Pinpoint custom analytics for your app.
+
+```swift
+// You can add this function in desired part of your app. It will be used to log events to the backend.
+func logEvent() {
+
+ let pinpointAnalyticsClient =
+ AWSPinpoint(configuration:
+ AWSPinpointConfiguration.defaultPinpointConfiguration(launchOptions: nil)).analyticsClient
+
+ let event = pinpointAnalyticsClient.createEvent(withEventType: "EventName")
+ event.addAttribute("DemoAttributeValue1", forKey: "DemoAttribute1")
+ event.addAttribute("DemoAttributeValue2", forKey: "DemoAttribute2")
+ event.addMetric(NSNumber.init(value: arc4random() % 65535), forKey: "EventName")
+ pinpointAnalyticsClient.record(event)
+ pinpointAnalyticsClient.submitEvents()
+
+}
+```
+
+Build, run, and use your app. Then, view your custom events on the `Events` tab of the Amazon Pinpoint console (choose `Analytics`>`Events`). Look for the name of your event in the `Events` menu.
+
+### Enable Revenue Analytics
+
+Amazon Pinpoint supports the collection of monetization event data. Use the following steps to place
+and design analytics related to purchases through your app.
+
+```swift
+func sendMonetizationEvent()
+ {
+ let pinpointClient = AWSPinpoint(configuration:
+ AWSPinpointConfiguration.defaultPinpointConfiguration(launchOptions: nil))
+
+ let pinpointAnalyticsClient = pinpointClient.analyticsClient
+
+ let event =
+ pinpointAnalyticsClient.createVirtualMonetizationEvent(withProductId:
+ "DEMO_PRODUCT_ID", withItemPrice: 1.00, withQuantity: 1, withCurrency: "USD")
+ pinpointAnalyticsClient.record(event)
+ pinpointAnalyticsClient.submitEvents()
+ }
+```
+
+## Kinesis
\ No newline at end of file
diff --git a/ios/api-apigw.md b/ios/api-apigw.md
new file mode 100755
index 00000000000..6dbf86dc220
--- /dev/null
+++ b/ios/api-apigw.md
@@ -0,0 +1,171 @@
+# Add Cloud APIs to Your Mobile App with Amazon API Gateway and AWS Lambda
+
+# Overview
+
+Add RESTful APIs handled by your serverless |LAM| functions. The CLI deploys your APIs and handlers using [Amazon API Gateway](http://docs.aws.amazon.com/apigateway/latest/developerguide/) and [AWS Lambda](http://docs.aws.amazon.com/lambda/latest/dg/).
+
+## Set Up Your Backend
+
+1. Complete the [Get Started](./get-started) steps before you proceed.
+
+2. Use the CLI to add api to your cloud-enabled backend and app.
+
+ In a terminal window, navigate to your project folder (the folder that contains your app `.xcodeproj` file), and add the SDK to your app.
+
+ ```bash
+ $ cd ./YOUR_PROJECT_FOLDER
+ $ amplify add api
+ ```
+
+3. Choose `> REST` as your API service.
+
+4. Choose `> Create a new Lambda function`.
+
+5. Choose the `> Serverless express function` template.
+
+6. Restrict API access? Choose `Yes`
+
+7. Who should have access? Choose `Authenticated and Guest users`
+
+8. When configuration of your API is complete, the CLI displays a message confirming that you have configured local CLI metadata for this category. You can confirm this by viewing status.
+
+ ```bash
+ $ amplify status
+ | Category | Resource name | Operation | Provider plugin |
+ | --------- | --------------- | --------- | ----------------- |
+ | Function | lambda01234567 | Create | awscloudformation |
+ | Api | api012345678 | Create | awscloudformation |
+ ```
+
+9. To create your backend AWS resources run:
+
+ ```bash
+ $ amplify push
+ ```
+
+ Use the steps in the next section to connect your app to your backend.
+
+## Connect to Your Backend
+
+Use the following steps to add Cloud Logic to your app.
+
+1. `Podfile` that you configure to install the AWS Mobile SDK must contain:
+
+ ```ruby
+ platform :ios, '9.0'
+
+ target :'YOUR-APP-NAME' do
+ use_frameworks!
+
+ # For auth
+ pod 'AWSAuthCore', '~> 2.6.13'
+ pod 'AWSMobileClient', '~> 2.6.13'
+
+ # For API
+ pod 'AWSAPIGateway', '~> 2.6.13'
+
+ # other pods
+
+ end
+ ```
+
+ Run `pod install --repo-update` before you continue.
+
+ If you encounter an error message that begins `[!] Failed to connect to GitHub to update the CocoaPods/Specs . . .`, and your internet connectivity is working, you may need to [update openssl and Ruby](https://stackoverflow.com/questions/38993527/cocoapods-failed-to-connect-to-github-to-update-the-cocoapods-specs-specs-repo/48962041#48962041).
+
+2. Classes that call |ABP| APIs must use the following import statements:
+
+ ```
+ import AWSAuthCore
+ import AWSCore
+ import AWSAPIGateway
+ import AWSMobileClient
+ ```
+
+3. Next, import files generated by CLI. The CLI generates a client code file and request-response structure file for each API you add.
+
+4. Add those files by going to your Xcode Project Navigator project, right-click on project's name in top left corner, and select "Add Files to YOUR_APP_NAME".
+
+5. Select all the files under :code:`generated-src` folder of your application's root folder and add them to your project.
+
+6. Next, set the bridging header for Swift in your project settings. Double-click your project name in the Xcode Project Navigator, choose the Build Settings tab and search for :guilabel:`Objective-C Bridging Header`. Enter :code:`generated-src/Bridging_Header.h`
+
+ This is needed because the AWS generated code has some Objective-C code which requires bridging to be used for Swift.
+
+ > If you already have a bridging header in your app, you can just append an extra line to it: `#import "AWSApiGatewayBridge.h"` instead of above step.
+
+7. Use the files generated by CLI to determine the client name of your API. In the :code:`generated-src` folder, files ending with name :code:`*Client.swift` are the names of your client (without .swift extension).
+
+ The path of the client code file is `./generated-src/YOUR_API_RESOURCE_NAME+YOUR_APP_NAME+Client.swift`.
+
+ So, for an app named :code:`useamplify` with an API resource named `xyz123`, the path of the code file might be `./generated-src/xyz123useamplifyabcdClient.swift`. The API client name would be `xyz123useamplifyabcdClient`.
+
+ - Find the resource name of your API by running `amplify status`.
+ - Copy your API client name to use when invoking the API in the following step.
+
+
+8. Invoke a Cloud Logic API.
+
+ To invoke a Cloud Logic API, create code in the following form and substitute your API's
+ client class, model, and resource paths. Replace :code:`YOUR_API_CLIENT_NAME` with the value you copied from the previous step.
+
+ ```swift
+ import UIKit
+ import AWSAuthCore
+ import AWSCore
+ import AWSAPIGateway
+ import AWSMobileClient
+
+ // ViewController or application context . . .
+
+ func doInvokeAPI() {
+ // change the method name, or path or the query string parameters here as desired
+ let httpMethodName = "POST"
+ // change to any valid path you configured in the API
+ let URLString = "/items"
+ let queryStringParameters = ["key1":"{value1}"]
+ let headerParameters = [
+ "Content-Type": "application/json",
+ "Accept": "application/json"
+ ]
+
+ let httpBody = "{ \n " +
+ "\"key1\":\"value1\", \n " +
+ "\"key2\":\"value2\", \n " +
+ "\"key3\":\"value3\"\n}"
+
+ // Construct the request object
+ let apiRequest = AWSAPIGatewayRequest(httpMethod: httpMethodName,
+ urlString: URLString,
+ queryParameters: queryStringParameters,
+ headerParameters: headerParameters,
+ httpBody: httpBody)
+
+ // Create a service configuration
+ let serviceConfiguration = AWSServiceConfiguration(region: AWSRegionType.USEast1,
+ credentialsProvider: AWSMobileClient.sharedInstance().getCredentialsProvider())
+
+ // Initialize the API client using the service configuration
+ xyz123useamplifyabcdClient.registerClient(withConfiguration: serviceConfiguration!, forKey: "CloudLogicAPIKey")
+
+ // Fetch the Cloud Logic client to be used for invocation
+ let invocationClient = xyz123useamplifyabcdClient.client(forKey: "CloudLogicAPIKey")
+
+ invocationClient.invoke(apiRequest).continueWith { (task: AWSTask) -> Any? in
+ if let error = task.error {
+ print("Error occurred: \(error)")
+ // Handle error here
+ return nil
+ }
+
+ // Handle successful result here
+ let result = task.result!
+ let responseString = String(data: result.responseData!, encoding: .utf8)
+
+ print(responseString)
+ print(result.statusCode)
+
+ return nil
+ }
+ }
+ ```
diff --git a/ios/auth-facebook-setup.md b/ios/auth-facebook-setup.md
new file mode 100755
index 00000000000..570d6d0e3ed
--- /dev/null
+++ b/ios/auth-facebook-setup.md
@@ -0,0 +1,70 @@
+# Set Up Facebook Authentication
+
+To use the following Facebook service configuration steps to federate Facebook as a user sign-in provider for AWS services called in your app, try the AWS Amplify `User Sign-in feature `.
+
+You must first register your application with Facebook by using the [Facebook Developers portal] (https://developers.facebook.com/).
+
+AWS Amplify generates code that enables you to use Facebook to provide federated authentication for your mobile app users. This topic explains how to set up Facebook as an identity provider for your app.
+
+If you already have a Facebook app ID, copy and paste it into the `Facebook App ID` field
+when configuring authentication using the AWS Amplify CLI.
+
+**To get a Facebook app ID**
+
+1. In the [Facebook Developers portal] (https://developers.facebook.com/), sign in with your
+ Facebook credentials.
+
+2. From `Create App`, choose `Add a New App` (note: this menu label will be
+ `My Apps` if you have previously created an app.
+
+
+
+3. If asked, choose the platform of your app that will use Facebook sign-in, and `basic
+ setup`.
+
+4. Type a display name for your app, select a category for your app from the `Category`
+ drop-down list, and then choose `Create App ID`.
+
+
+
+
+5. Complete the `Security Check` that appears. Your new app then appears in the
+ `Dashboard`.
+
+
+
+6. Copy the App ID and paste it into the `Facebook App ID` field in the Mobile Hub console.
+
+
+
+7. In the Facebook Developer portal's left hand navigation list, choose `Settings`, then
+ choose `+ Add Platform`.
+
+
+
+8. Choose your platform and provide information about your app that Facebook will use for
+ integration during credential validation.
+
+ `For iOS:`
+
+ 1. Add your app's Bundle ID. (for example, com.amazon.YourProjectName).
+
+
+
+
+9. In the Facebook Developers portal, choose `Save changes`, then `Use this
+ package name` if a dialog appears saying that Google Play has an issue with your package name.
+
+10. Only users with roles assigned in the Facebook portal will be able to authenticate through your
+ app while it is in development (not yet published).
+
+ To authorize users, in the Facebook Developer portal's left hand navigation list, choose
+ `Roles`, then `Add Testers`. Provide a valid Facebook ID.
+
+
+
+
+11. In the Mobile Hub console, choose `Save changes`.
+
+For more information about integrating with Facebook Login, see the [Facebook Getting Started Guide]
+(https://developers.facebook.com/docs/facebook-login).
diff --git a/ios/auth-google-setup.md b/ios/auth-google-setup.md
new file mode 100755
index 00000000000..4ca571f906e
--- /dev/null
+++ b/ios/auth-google-setup.md
@@ -0,0 +1,13 @@
+# Set Up Google Authentication
+
+To use the following Google service configuration steps to federate Google as a user sign-in provider for AWS services called in your app, try the AWS Amplify `User Sign-in feature `.
+
+With AWS Amplify, you can configure a working Google Sign-In feature for both Android and iOS apps. To fully integrate Google Sign-In with your app, AWS Amplify needs information that comes from Google's setup process.
+
+The following pages detail the Google Sign-In requirements ans steps to integrate Google Sign-In for both iOS and Android apps.
+
+* `auth-google-create-google-project` (required for `all apps` regardless of platform)
+
+* `auth-google-create-oauth-android-clientid` (required for all Android apps)
+
+* `auth-google-create-oauth-ios-clientid` (required for all iOS apps)
diff --git a/ios/authentication.md b/ios/authentication.md
new file mode 100755
index 00000000000..5f72e2b65c6
--- /dev/null
+++ b/ios/authentication.md
@@ -0,0 +1,367 @@
+# Add User Sign-in to Your Mobile App with Amazon Cognito
+
+Enable your users to sign-in using credentials from Facebook, Google, or your own custom user directory. The CLI deploys [Amazon Cognito identity pool](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-identity.html) and [user pools](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools.html) to create your backend.
+
+## Set Up Your Backend
+
+**Prerequisite** Complete the [Get Started](./get-started) steps before you proceed.
+
+### Email & Password
+
+`This default auth configuration sets up a custom user pool for your app.`
+
+**To set up email and password sign-in**
+
+1. Navigate to your project folder (the folder that contains your app `.xcodeproj` file), and add the SDK to your app.
+ ```bash
+ $ cd ./YOUR_PROJECT_FOLDER
+ $ amplify add auth
+ ```
+
+2. Choose the default configuration.
+
+ ```
+ ❯ Yes, use the default configuration.
+ ```
+
+3. When configuration for email and password sign-in is complete, a message appears confirming that you have configured local CLI metadata for this category. You can confirm this by viewing status.
+
+ ```bash
+ $ amplify status
+ | Category | Resource name | Operation | Provider plugin |
+ | -------- | --------------- | --------- | ----------------- |
+ | Auth | cognitoabcd0123 | Create | awscloudformation |
+ ```
+
+4. To create your backend AWS resources run the following:
+
+ ```bash
+ $ amplify push
+ ```
+
+5. Follow the [Set up Email & Password Login](set-up-email-and-password) steps to connect to your backend from your app.
+
+## Facebook
+
+**To set up Facebook sign-in**
+
+1. In a terminal window, navigate to the root of your app files and add the auth category to your app. The CLI prompts you for configuration parameters.
+
+ ```bash
+ $ cd ./YOUR_PROJECT_FOLDER
+ $ amplify add auth
+ ```
+
+2. Choose to set up your own configuration.
+
+ ```
+ ❯ No, I will set up my own configuration.
+ ```
+
+3. Choose to set up authentication flow using AWS IAM access controls.
+
+ ```
+ ❯ User Sign-Up, Sign-In, connected with AWS IAM controls
+ ```
+
+4. Choose yes, to: `? Allow unauthenticated logins?`.
+
+5. Choose yes, to: `? Do you want to enable 3rd party authentication providers in your identity pool?`.
+
+6. Choose Facebook and then provide your Facebook app ID. To retrieve or create your Facebook app ID, see [Setting Up Facebook Authentication](http://docs.aws.amazon.com/aws-mobile/latest/developerguide/auth-facebook-setup.html).
+
+7. When configuration for Facebook sign-in is complete, the CLI displays a message confirming that you have configured local CLI metadata for this category. You can confirm this by viewing status.
+
+ ```
+ $ amplify status
+ | Category | Resource name | Operation | Provider plugin |
+ | --------- | --------------- | --------- | ----------------- |
+ | Auth | cognitoa7cbb553 | Create | awscloudformation |
+ ```
+
+8. To create your backend AWS resources run the following:
+
+ ```
+ $ amplify push
+ ```
+
+9. Follow the steps at [Set Up Facebook Login](./set-up-facebook) to connect to your backend from your app.
+
+## Google
+
+**To set up Google sign-in**
+
+1. In a terminal window, navigate to the root of your app files and add the auth category to your app. The CLI prompts you for configuration parameters.
+
+ ```
+ $ cd ./YOUR_APP_ROOT
+ $ amplify add auth
+ ```
+2. Choose to set up your own configuration.
+
+ ```
+ ❯ No, I will set up my own configuration.
+ ```
+3. Choose to set up authentication flow using AWS IAM access controls.
+
+ ```
+ ❯ User Sign-Up, Sign-In, connected with AWS IAM controls ...
+ ```
+
+4. Choose yes, to: `? Allow unauthenticated logins?`.
+
+5. Choose yes, to: `? Do you want to enable 3rd party authentication providers in your identity pool?`.
+
+6. Choose Google and then provide your Google client ID. To retrieve or create your Google app ID, see [Setting Up Google Authentication](http://docs.aws.amazon.com/aws-mobile/latest/developerguide/auth-google-setup.html).
+
+7. When configuration for Google sign-in is complete, the CLI displays a message confirming that you have configured local CLI metadata for this category. You can confirm this by viewing status.
+
+ ```
+ $ amplify status
+ | Category | Resource name | Operation | Provider plugin |
+ | --------- | --------------- | --------- | ----------------- |
+ | Auth | cognitoa7cbb553 | Create | awscloudformation |
+ ```
+
+8. To create your backend AWS resources run the following:
+
+ ```
+ amplify push
+ ```
+
+9. Follow the steps at [Set Up Google Login](./set-up-google) to connect to your backend from your app.
+
+Note that the CLI allows you to select more than one identity provider for your app. You can also run `amplify auth update` to add an identity provider to an existing auth configuration.
+
+## Set Up Email and Password Login in Your Mobile App
+
+1. Add the following dependencies in your project's `Podfile`:
+
+ ```ruby
+ platform :ios, '9.0'
+ target :'YOUR-APP-NAME' do
+ use_frameworks!
+ pod 'AWSUserPoolsSignIn', '~> 2.6.13'
+ pod 'AWSAuthUI', '~> 2.6.13'
+ pod 'AWSMobileClient', '~> 2.6.13'
+ # other pods
+ end
+ ```
+2. Pull the SDK libraries into your local repo as follows:
+
+ ```bash
+ pod install --repo-update
+ ```
+## Set Up Facebook Login in Your Mobile App
+
+1. Add or update your AWS backend configuration file to incorporate your new sign-in. For details, see the last steps in the [Get Started: Set Up Your Backend](./add-aws-mobile-sdk-basic-setup) section.
+
+2. Add the following dependencies in your project's `Podfile`.
+
+ ```
+ platform :ios, '9.0'
+ target :'YOUR-APP-NAME' do
+ use_frameworks!
+ pod 'AWSMobileClient', '~> 2.6.13'
+ pod 'AWSFacebookSignIn', '~> 2.6.13'
+ pod 'AWSUserPoolsSignIn', '~> 2.6.13'
+ pod 'AWSAuthUI', '~> 2.6.13'
+ # other pods
+ end
+ ```
+ Run `pod install --repo-update`.
+
+3. Add Facebook meta data to `Info.plist`.
+
+ To configure your Xcode project to use Facebook Login, right-choose `Info.plist` and then choose `Open As > Source Code`.
+
+ Add the following entry, using your project name, Facebook ID and login scheme ID.
+
+ ```xml
+
+
+
+
+
+
+
+ FacebookAppID
+ 0123456789012345
+ FacebookDisplayName
+ YOUR-PROJECT-NAME
+ LSApplicationQueriesSchemes
+
+ fbapi
+ fb-messenger-api
+ fbauth2
+ fbshareextension
+
+
+
+
+
+ CFBundleURLTypes
+
+
+ CFBundleURLSchemes
+
+ fb0123456789012345
+
+
+
+
+
+
+ ```
+
+## Set Up Google Login in Your Mobile App
+
+1. Add or update your AWS backend configuration file to incorporate your new sign-in. For details, see the last steps in the [Get Started: Set Up Your Backend](./getting-started) section.
+
+2. Add the following dependencies in the Podfile.
+
+ ```ruby
+ platform :ios, '9.0'
+ target :'YOUR-APP-NAME' do
+ use_frameworks!
+ pod 'AWSMobileClient', '~> 2.6.13'
+ pod 'AWSGoogleSignIn', '~> 2.6.13'
+ pod 'AWSUserPoolsSignIn', '~> 2.6.13'
+ pod 'AWSAuthUI', '~> 2.6.13'
+ pod 'GoogleSignIn', '~> 4.0'
+ # other pods
+ end
+ ```
+ Run `pod install --repo-update` before you continue.
+
+3. Add Google metadata to `Info.plist`.
+
+ To configure your Xcode project to use Google Login, open its `Info.plist` file using **Right-click > Open As > Source Code.** Add the following entry. Substitute your project name for the placeholder string.
+
+ ```xml
+
+
+
+
+
+
+ CFBundleURLTypes
+
+
+ CFBundleURLSchemes
+
+ com.googleusercontent.apps.xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+
+
+
+
+
+ ```
+
+## Add sign-in
+
+1. Add code to create an instance of `AWSMobileClient` in the `application:open url` function of your `AppDelegate.swift`, to resume a previously signed-in authenticated session.
+
+ Then add another instance of `AWSMobileClient` in the `didFinishLaunching` function to register the sign in providers, and to fetch an Amazon Cognito credentials that AWS will use to authorize access once the user signs in.
+
+ ```swift
+ import UIKit
+ import AWSMobileClient
+
+ @UIApplicationMain
+
+ class AppDelegate: UIResponder, UIApplicationDelegate {
+
+ // Add an AWSMobileClient call in application:open url
+ func application(_ application: UIApplication, open url: URL,
+ sourceApplication: String?, annotation: Any) -> Bool {
+
+ return AWSMobileClient.sharedInstance().interceptApplication(
+ application, open: url,
+ sourceApplication: sourceApplication,
+ annotation: annotation)
+
+ }
+
+ // Add an AWSMobileClient call in application:didFinishLaunching
+ func application(
+ _ application: UIApplication,
+ didFinishLaunchingWithOptions launchOptions:
+ [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
+
+ return AWSMobileClient.sharedInstance().interceptApplication(
+ application, didFinishLaunchingWithOptions:
+ launchOptions)
+ }
+
+ // Other functions in AppDelegate . . .
+
+ }
+ ```
+
+2. Make sure you have a `UINavigationController` in your app to use the sign-in UI. The sign-in UI uses the `UINavigationController` as an anchor to perform all the transitions. Learn more about using [UINavigationController](https://medium.com/whoknows-swift/swift-the-hierarchy-of-uinavigationcontroller-programmatically-91631990f495).
+
+3. Implement your sign-in UI by calling the library provided by the SDK.
+
+ ```swift
+ import UIKit
+ import AWSAuthCore
+ import AWSAuthUI
+
+ class SampleViewController: UIViewController {
+
+ override func viewDidLoad() {
+
+ super.viewDidLoad()
+
+ // Call the showSignIn method from your `viewDidLoad` method
+ // The showSignIn() method will check if the user is logged in,
+ // and if the user is not logged in, it will present a sign-in UI using the navigation controller the view is part of.
+ showSignIn()
+ }
+
+ func showSignIn() {
+ if !AWSSignInManager.sharedInstance().isLoggedIn {
+ AWSAuthUIViewController
+ .presentViewController(with: self.navigationController!,
+ configuration: nil,
+ completionHandler: { (provider: AWSSignInProvider, error: Error?) in
+ if error != nil {
+ print("Error occurred: \(String(describing: error))")
+ } else {
+ // Sign in successful.
+ }
+ })
+ }
+ }
+ }
+ ```
+
+ Choose the run icon (|play|) in the top left of the Xcode window or type Cmd+R to build and run your app. You should see our pre-built sign-in UI for your app. Checkout the next steps to learn how to :ref:`customize your UI `.
+
+ * - API References
+ - * `AWSMobileClient `_
+ `A library that initializes the SDK, fetches the AWS credentials, and creates a SDK SignInUI client instance.`
+ * `Auth UserPools `_
+ `A wrapper Library for Amazon Cognito UserPools that provides a managed Email/Password sign-in UI.`
+ * `Auth Core `_
+ `A library that caches and federates a login provider authentication token using Amazon Cognito Federated Identities, caches the federated AWS credentials, and handles the sign-in flow.`
+
+## Add sign-out
+
+Sign-out code example. This call should be invoked on a UI activity like a button press triggered by the end user. E.g. `onSignOutButtonClicked` action of sign out button in your app.
+
+ ```swift
+ AWSSignInManager.sharedInstance().logout(completionHandler: {(result: Any?, error: Error?) in
+ // Note: The showSignIn() method used below was added by us previously while integrating the sign-in UI.
+ self.showSignIn()
+ })
+ ```
+
+For a fuller example, see [Sign-out a Signed-in User](how-to-user-sign-in-sign-out) in the How To section.
+
+### Next Steps
+
+ * `Customize the UI `
+ * `Import Your Existing Amazon Cognito Identity Pool `
+ * `Amazon Cognito Developer Guide `__
diff --git a/ios/getting-started.md b/ios/getting-started.md
new file mode 100755
index 00000000000..c5fba8fcff4
--- /dev/null
+++ b/ios/getting-started.md
@@ -0,0 +1,110 @@
+# Get Started
+
+Get started building a cloud-powered iOS app using the AWS Amplify CLI and the AWS SDK for iOS. This page guides you through setting up an initial backend and integrating the SDK into your app.
+
+## Step 1: Set Up Your Development Environment
+
+We strongly recommend that you use the Amplify CLI for building the serverless backend for your app. If you have already installed the CLI, skip ahead to `Step 2 `.
+
+* `Sign up for an [AWS Account](https://portal.aws.amazon.com/billing/signup?redirect_url=https%3A%2F%2Faws.amazon.com%2Fregistration-confirmation#/start).
+
+* Install `Node.js `__ and npm (if they are not already installed).
+
+> Verify that you are running at least Node.js version 8.x or greater and npm version 5.x or greater by running :code:`node -v` and :code:`npm -v` in a terminal/console window. Older versions aren't supported and might generate errors.
+
+To install and configure the Amplify CLI globally, run the following commands in a terminal window.
+
+```bash
+ $ npm install -g @aws-amplify/cli
+ $ amplify configure
+```
+
+* Choose the iOS app project you want to integrate with an AWS backend.
+* `Install Xcode `__ version 8.0 or later.
+
+## Step 2: Set Up Your Backend
+
+1. The CLI prompts you for configuration parameters.
+
+ In a terminal window, navigate to your project folder (the folder that typically contains your project level :file:`xcodeproj` file), and add the SDK to your app.
+
+```bash
+ $ cd ./YOUR_PROJECT_FOLDER
+ $ amplify init
+```
+
+2. To create your backend AWS resources and add a configuration file to your app, run the following:
+
+ ```bash
+ $ amplify push
+ ```
+
+In the Finder, navigate to the folder containing your app :file:`.xcodeproj` file. From there, drag :code:`awsconfiguration.json` to Xcode under the top Project Navigator folder (the folder name should match your Xcode project name). In the :guilabel:`Options` dialog box that appears, do the following:
+
+* Clear the :guilabel:`Copy items if needed` check box.
+* Choose :guilabel:`Create groups`, and then choose :guilabel:`Next`.
+
+3. To verify that the CLI is set up for your app, run the following command. The CLI displays a status table with no resources listed. As you add categories to your app, backend resources created for your app are listed in this table.
+
+ ```bash
+ $ amplify status
+ | Category | Resource name | Operation | Provider plugin |
+ | -------- | ------------- | --------- | --------------- |
+ ```
+
+ Use the steps in the next section to configure the connection between your app and the serverless backend.
+
+## Step 3: Connect to Your Backend
+
+Perform the following steps to set up a connection to AWS services that you'll use in the Get Started section of this guide.
+
+1. Install Cocoapods. From a terminal window run the following:
+
+ .. code-block:: none
+
+ sudo gem install cocoapods
+
+2. Create :file:`Podfile`. From a terminal window, navigate to the directory that contains your project's :file:`.xcodeproj` file and run the following:
+
+ .. code-block:: none
+
+ pod init
+
+3. Open :file:`Podfile` in a text editor and add the pod for core AWS Mobile SDK components to your build.
+
+ .. code-block:: none
+
+ platform :ios, '9.0'
+ target :'YOUR-APP-NAME' do
+ use_frameworks!
+
+ pod 'AWSCore', '~> 2.6.13'
+
+ # other pods
+ end
+
+4. Install dependencies by running the following:
+
+ .. code-block:: none
+
+ pod install --repo-update
+
+ If you encounter an error message that begins `[!] Failed to connect to GitHub to update the CocoaPods/Specs . . .`, and your internet connectivity is working, you might need to [update openssl and Ruby](https://stackoverflow.com/questions/38993527/cocoapods-failed-to-connect-to-github-to-update-the-cocoapods-specs-specs-repo/48962041#48962041).
+
+5. The command `pod install` creates a new workspace file. Close your Xcode project and reopen it using `./YOUR-PROJECT-NAME.xcworkspace`.
+ - Use **ONLY** your .xcworkspace
+ - Remember to always use :file:`./YOUR-PROJECT-NAME.xcworkspace` to open your Xcode project from now on.
+
+6. Rebuild your app after reopening it in the workspace to resolve APIs from new libraries called in your code. This is a good practice any time you add import statements.
+
+Your app is now ready for you to add cloud-powered features. We recommend [adding analytics](./analytics) as your first feature.
+
+## Next Steps
+
+* [Add Analytics](./analytics)
+* [Add User Sign-in](./authentication)
+* [Add Push Notification](./push-notifications)
+* [Add User File Storage](./storage)
+* [Add Serverless Backend](./api)
+* [Add Cloud Logic](./api)
+* [Add Messaging](./messaging)
diff --git a/ios/how-to-cognito-integrate-an-existing-identity-pool-ios.md b/ios/how-to-cognito-integrate-an-existing-identity-pool-ios.md
new file mode 100755
index 00000000000..bc3158de19c
--- /dev/null
+++ b/ios/how-to-cognito-integrate-an-existing-identity-pool-ios.md
@@ -0,0 +1,174 @@
+# How to Integrate Your Existing Identity Pool
+
+
+**Just Getting Started?** | `Use streamlined steps ` to install the SDK and integrate Amazon Cognito.
+------------ | -------------
+
+The `Get Started ` section of this guide allows you to create new resources and complete the steps described on this page in minutes. If you want to import existing resources or create them from scratch, this page will walk you through the following steps:
+
+ * Set up short-lived credentials for accessing your AWS resources using a [Cognito Identity Pool] (http://docs.aws.amazon.com/cognito/latest/developerguide/identity-pools.html).
+
+ * Create an AWS Mobile configuration file that ties your app code to the identity pool that enables users to access your AWS resources.
+
+ * Make small adjustments to your app code to install the SDK and retrieve AWS credentials for your user.
+
+
+## Set Up Your Backend
+
+### Import or Create a New Identity Pool
+
+* If you already have an Amazon Cognito Identity Pool and know its ID and region, you can skip to :ref:`how-to-auth-connect-to-your-backend`.
+
+To create a new identity pool:
+
+1. Go to [Amazon Cognito Console] (https://console.aws.amazon.com/cognito) and choose `Manage Federated Identities`.
+
+2. Choose `Create new Identity pool` on the top left of the console.
+
+3. Type a name for the Identity pool, select `Enable access to unauthenticated identities` under the `Unauthenticated Identities` section, and then choose `Create pool` on the bottom right.
+
+4. Expand the `View Details` section to see the two roles that are to be created to enable access to your bucket. Copy and keep both the Authenticated and Unauthenticated role names, in the form of :code:`Cognito_Auth_Role` and :code:`Cognito_Unauth_Role`. In many cases, you will modify the permissions policy of these roles to control access to AWS resources that you add to your app.
+
+5. Choose `Allow` on the bottom right.
+
+6. In the code snippet labeled `Get AWSCredentials` displayed by the console, copy the Identity Pool ID and the Region for use in a following configuration step. You will use these values to connect your backend to your app.
+
+## Connect to Your Backend
+
+Take the following steps to connect your app to its backend.
+
+
+### Create the awsconfiguration.json file
+
+1. Create a file with name `awsconfiguration.json` with the following contents:
+
+```json
+ {
+ "Version": "1.0",
+ "CredentialsProvider": {
+ "CognitoIdentity": {
+ "Default": {
+ "PoolId": "COGNITO-IDENTITY-POOL-ID",
+ "Region": "COGNITO-IDENTITY-POOL-REGION"
+ }
+ }
+ },
+ "IdentityManager" : {
+ "Default" : {
+
+ }
+ }
+ }
+```
+
+2. Make the following changes to the configuration file.
+
+* Replace the `COGNITO-IDENTITY-POOL-ID` with the identity pool ID.
+
+* Replace the `COGNITO-IDENTITY-POOL-REGION` with the region the identity pool was created in.
+
+
+ - Need to find your pool's ID and region?
+
+ - Go to [Amazon Cognito Console] (https://console.aws.amazon.com/cognito) and choose `Manage Federated Identities`, then choose your pool and choose `Edit identity pool`. Copy the value of `Identity pool ID`.
+
+ Insert this region value into the following form to create the value you need for this integration.
+
+ ```bash
+
+ "Region": "REGION-PREFIX-OF-YOUR-POOL-ID".
+ ```
+ For example, if your pool ID is :code:`us-east-1:01234567-yyyy-0123-xxxx-012345678901`, then your integration region value would be:
+ ```bash
+
+ "Region": "us-east-1".
+ ```
+
+### Add the awsconfiguration.json file to your app
+
+iOS - Swift
+
+Drag the `awsconfiguration.json` into the folder containing your `Info.plist` file in your Xcode project. Choose `Copy items` and `Create groups` in the options dialog.
+
+
+### Add the SDK to your App
+
+iOS - Swift
+
+Set up AWS Mobile SDK components as follows:
+
+1. Add the `AWSMobileClient` pod to your `Podfile` to install the AWS Mobile SDK.
+
+```swift
+
+ platform :ios, '9.0'
+
+ target :'YOUR-APP-NAME' do
+ use_frameworks!
+
+ pod 'AWSMobileClient', '~> 2.6.13'
+
+ # other pods . . .
+
+ end
+```
+
+2. Run `pod install --repo-update` in your app root folder before you continue.
+
+ If you encounter an error message that begins "`[!] Failed to connect to GitHub to update the CocoaPods/Specs . . .`", and your internet connectivity is working, you may need to (update openssl and Ruby) (https://stackoverflow.com/questions/38993527/cocoapods-failed-to-connect-to-github-to-update-the-cocoapods-specs-specs-repo/48962041#48962041).
+
+
+3. Add the following code to your AppDelegate to establish a run-time connection with AWS Mobile.
+
+```swift
+ import UIKit
+ import AWSMobileClient
+
+ @UIApplicationMain
+ class AppDelegate: UIResponder, UIApplicationDelegate {
+
+ func application(_ application: UIApplication,
+ didFinishLaunchingWithOptions launchOptions:
+
+ [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
+
+
+ // Uncomment to turn on logging, look for "Welcome to AWS!" to confirm success
+ // AWSDDLog.add(AWSDDTTYLogger.sharedInstance)
+ // AWSDDLog.sharedInstance.logLevel = .info
+
+
+ // Instantiate AWSMobileClient to get AWS user credentials
+ return AWSMobileClient.sharedInstance().interceptApplication(application, didFinishLaunchingWithOptions: launchOptions)
+
+ }
+ }
+```
+When you run your app, you should see no behavior change. To verify success, turn on logging by uncommenting the lines in the preceding example, and look for the message :code:`"Welcome to AWS!"` in your the output.
+
+4. To get the users identity, use `getCredentialsProvider()` to access `AWSIdentityManager`, shown here being done in a `ViewController`.
+
+```swift
+import UIKit
+import AWSMobileClient
+import AWSAuthCore
+
+class ViewController: UIViewController {
+
+ @IBOutlet weak var textfield: UITextField!
+ override func viewDidLoad() {
+ super.viewDidLoad()
+ textfield.text = "View Controller Loaded"
+
+ // Get the identity Id from the AWSIdentityManager
+ let appDelegate = UIApplication.shared.delegate as! AppDelegate
+ let credentialsProvider = AWSMobileClient.sharedInstance().getCredentialsProvider()
+ let identityId = AWSIdentityManager.default().identityId
+ }
+}
+```
+
+
+## Next Steps
+
+* For further information, see [Amazon Cognito Developer Guide] (https://docs.aws.amazon.com/cognito/latest/developerguide/what-is-amazon-cognito.html).
diff --git a/ios/how-to-ios-asynchrounous-tasks.md b/ios/how-to-ios-asynchrounous-tasks.md
new file mode 100755
index 00000000000..f0aa09900b2
--- /dev/null
+++ b/ios/how-to-ios-asynchrounous-tasks.md
@@ -0,0 +1,240 @@
+# iOS: Working with Asynchronous Tasks
+
+To work with asynchronous operations without blocking the UI thread, the SDK provides the following options:
+
+ - ``completionHandler``, a streamlined class which offers a simple, common pattern for most API calls.
+
+ - ``AWSTask``, a class that is a renamed version of BFTask from the Bolts framework. AWSTasks provides advantages for more complex operations like chaining asynchronous requests. For complete documentation on Bolts, see the
+ [Bolts-ObjC repo] (https://github.com/BoltsFramework/Bolts-ObjC).
+
+## Using completionHandler
+
+Most simple asynchronous API method calls can use ``completionHandler`` to handle
+method callbacks. When an asynchronous method is complete, ``completionHandler`` returns two parts: a response
+object containing the method's return if the call was successful, or ``nil`` if failed; and an error object containing the ``NSError`` state when a call fails, or ``nil`` upon success.
+
+### Handling Asynchronous Method Returns with completionHandler
+
+The following code shows typical usage of ``completionHandler`` using Amazon Kinesis Firehose as the example.
+
+```swift
+var firehose = AWSFirehose.default()
+firehose.putRecord(AWSFirehosePutRecordInput(), completionHandler: {(_ response: AWSFirehosePutRecordOutput?, _ error: Error?) -> Void in
+ if error != nil {
+ //handle error
+ }
+ else {
+ //handle response
+ }
+})
+```
+
+## Using AWSTask
+
+An ``AWSTask`` object represents the result of an asynchronous method. Using ``AWSTask``,
+you can wait for an asynchronous method to return a value, and then do something with that
+returned value. You can chain asynchronous requests instead of nesting them. This
+helps keep logic clean and code readable.
+
+### Handling Asynchronous Method Returns with AWSTask
+
+The following code shows how to use ``continueOnSuccessBlockWith:`` and ``continueWith:`` to handle methods calls
+that return an ``AWSTask`` object.
+
+```swift
+let kinesisRecorder = AWSKinesisRecorder.default()
+
+let testData = "test-data".data(using: .utf8)
+kinesisRecorder?.saveRecord(testData, streamName: "test-stream-name").continueOnSuccessWith(block: { (task:AWSTask) -> AWSTask? in
+ // Guaranteed to happen after saveRecord has executed and completed successfully.
+ return kinesisRecorder?.submitAllRecords()
+}).continueWith(block: { (task:AWSTask) -> Any? in
+ if let error = task.error as? NSError {
+ print("Error: \(error)")
+ return nil
+ }
+
+ return nil
+})
+```
+
+The ``submitAllRecords`` call is made within the ``continueOnSuccessWith`` /
+``continueWithSuccessBlock:`` because we want to run ``submitAllRecords`` after
+``saveRecord:streamName:`` successfully finishes running. The ``continueWith``
+and ``continueOnSuccessWith`` won't run until the previous asynchronous call finishes.
+In this example, ``submitAllRecords`` is guaranteed to see the result of ``saveRecord:streamName:``.
+
+### Handling Errors with AWSTask
+
+The ``continueWith:`` and ``continueOnSuccessWith:`` block calls work in similar ways. Both ensure
+that the previous asynchronous method finishes executing before the subsequent block runs. However, they
+have one important difference: ``continueOnSuccessWith:`` is skipped if an error occurred in the previous operation, but ``continueWith:`` is always executed.
+
+For example, consider the following scenarios, which refer to the preceding code snippet above.
+
+* ``saveRecord:streamName:`` succeeded and ``submitAllRecords`` succeeded.
+
+ In this scenario, the program flow proceeds as follows:
+
+ 1. ``saveRecord:streamName:`` is successfully executed.
+ 2. ``continueOnSuccessWith:`` is executed.
+ 3. ``submitAllRecords`` is successfully executed.
+ 4. ``continueWith:`` is executed.
+ 5. Because ``task.error`` is nil, it doesn't log an error.
+ 6. Done.
+
+* ``saveRecord:streamName:`` succeeded and ``submitAllRecords`` failed.
+
+ In this scenario, the program flow proceeds as follows:
+
+ 1. ``saveRecord:streamName:`` is successfully executed.
+ 2. ``continueOnSuccessWith`` is executed.
+ 3. ``submitAllRecords`` is executed with an error.
+ 4. ``continueWithBlock:`` is executed.
+ 5. Because ``task.error`` is NOT nil, it logs an error from ``submitAllRecords``.
+ 6. Done.
+
+* ``saveRecord:streamName:`` failed.
+
+ In this scenario, the program flow proceeds as follows:
+
+ 1. ``saveRecord:streamName:`` is executed with an error.
+ 2. ``continueOnSuccessWith:`` is skipped and will NOT be executed.
+ 3. ``continueWithBlock:`` is executed.
+ 4. Because ``task.error`` is NOT nil, it logs an error from ``saveRecord:streamName:``.
+ 5. Done.
+
+
+#### Consolidated Error Logic with AWSTask
+
+The preceding example consolidates error handling logic at the end of the execution chain for both methods called. It doesn't check for ``task.error`` in ``continueOnSuccessBlockWith:``, but waits until the ``continueWith:`` block executes to do so. An error from either the ``submitAllRecords`` or the ``saveRecord:streamName:`` method will be printed.
+
+#### Per Method Error Logic with AWSTask
+
+The following code shows how to implement the same behavior, but makes error handling specific to each method. ``submitAllRecords`` is only called if ``saveRecord:streamName`` succeeds, however, in this case, the ``saveRecord:streamName`` call uses ``continueWith:``, the block logic checks ``task.error`` and returns nil upon error. If that block succeeds then ``submitAllRecords`` is called using ``continueWith:`` in a block that also checks ``task.error`` for its own context.
+
+```swift
+let kinesisRecorder = AWSKinesisRecorder.default()
+
+let testData = "test-data".data(using: .utf8)
+kinesisRecorder?.saveRecord(testData, streamName: "test-stream-name").continueWith(block: { (task:AWSTask) -> AWSTask? in
+ if let error = task.error as? NSError {
+ print("Error from 'saveRecord:streamName:': \(error)")
+ return nil
+ }
+ return kinesisRecorder?.submitAllRecords()
+}).continueWith(block: { (task:AWSTask) -> Any? in
+ if let error = task.error as? NSError {
+ print("Error from 'submitAllRecords': \(error)")
+ return nil
+ }
+
+ return nil
+})
+```
+
+### Returning AWSTask or nil
+
+Remember to return either an ``AWSTask`` object or ``nil`` in every usage of ``continueWith:`` and ``continueOnSuccessWith:``. In most cases, Xcode provides a warning if there is no valid return present, but in some cases an undefined error can occur.
+
+### Executing Multiple Tasks with AWSTask
+
+If you want to execute a large number of operations, you have two options: executing in sequence or executing in parallel.
+
+#### In Sequence
+
+You can submit 100 records to an Amazon Kinesis stream in sequence as follows:
+
+```swift
+var task = AWSTask(result: nil)
+
+for i in 0...100 {
+ task = task.continueOnSuccessWith(block: { (task:AWSTask) -> AWSTask? in
+ return kinesisRecorder!.saveRecord(String(format: "TestString-%02d", i).data(using: .utf8), streamName: "YourStreamName")
+ })
+}
+
+task.continueOnSuccessWith { (task:AWSTask) -> AWSTask? in
+ return kinesisRecorder?.submitAllRecords()
+}
+```
+
+In this case, the key is to concatenate a series of tasks by reassigning ``task``.
+
+```swift
+task.continueOnSuccessWith { (task:AWSTask) -> AWSTask? in
+```
+
+#### In Parallel
+
+You can execute multiple methods in parallel by using ``taskForCompletionOfAllTasks:`` as follows.
+
+```swift
+var tasks = Array>()
+for i in 0...100 {
+ tasks.append(kinesisRecorder!.saveRecord(String(format: "TestString-%02d", i).data(using: .utf8), streamName: "YourStreamName")!)
+}
+
+AWSTask(forCompletionOfAllTasks: tasks).continueOnSuccessWith(block: { (task:AWSTask) -> AWSTask? in
+ return kinesisRecorder?.submitAllRecords()
+}).continueWith(block: { (task:AWSTask) -> Any? in
+ if let error = task.error as? NSError {
+ print("Error: \(error)")
+ return nil
+ }
+
+ return nil
+})
+```
+
+In this example you create an instance of ``NSMutableArray``, put all of our tasks in it, and then pass it to ``taskForCompletionOfAllTasks:``, which is successful only when all of the tasks are successfully executed. This approach may be faster, but it may consume more system resources. Also, some AWS services, such as Amazon DynamoDB, throttle a large number of certain requests. Choose a sequential or parallel approach based on your use case.
+
+### Executing a Block on the Main Thread with AWSTask
+
+By default, ``continueWithBlock:`` and ``continueWithSuccessBlock:`` are executed on a background thread. But in some cases (for example, updating a UI component based on the result of a service call), you need to execute an operation on the main thread. To execute an operation on the main thread, you can use Grand Central Dispatch or ``AWSExecutor``.
+
+#### Grand Central Dispatch
+
+The following example shows the use of ``dispatch_async(dispatch_get_main_queue(), ^{...});`` to execute a block on the main thread. For error handling, it creates a ``UIAlertView`` on the main thread when record submission fails.
+
+```swift
+let kinesisRecorder = AWSKinesisRecorder.default()
+
+let testData = "test-data".data(using: .utf8)
+kinesisRecorder?.saveRecord(testData, streamName: "test-stream-name").continueOnSuccessWith(block: { (task:AWSTask) -> AWSTask? in
+ return kinesisRecorder?.submitAllRecords()
+}).continueWith(block: { (task:AWSTask) -> Any? in
+ if let error = task.error as? NSError {
+ DispatchQueue.main.async(execute: {
+ let alertController = UIAlertView(title: "Error!", message: error.description, delegate: nil, cancelButtonTitle: "OK")
+ alertController.show()
+ })
+ return nil
+ }
+
+ return nil
+})
+```
+
+#### AWSExecutor
+
+Another option is to use ``AWSExecutor`` as follows.
+
+```swift
+let kinesisRecorder = AWSKinesisRecorder.default()
+
+let testData = "test-data".data(using: .utf8)
+kinesisRecorder?.saveRecord(testData, streamName: "test-stream-name").continueOnSuccessWith(block: { (task:AWSTask) -> AWSTask? in
+ return kinesisRecorder?.submitAllRecords()
+}).continueWith(executor: AWSExecutor.mainThread(), block: { (task:AWSTask) -> Any? in
+ if let error = task.error as? NSError {
+ let alertController = UIAlertView(title: "Error!", message: error.description, delegate: nil, cancelButtonTitle: "OK")
+ alertController.show()
+ return nil
+ }
+
+ return nil
+})
+```
+
+In this case, ``block:`` (Swift) is executed on the main thread.
diff --git a/ios/how-to-ios-ats.md b/ios/how-to-ios-ats.md
new file mode 100755
index 00000000000..9bdbdc9b056
--- /dev/null
+++ b/ios/how-to-ios-ats.md
@@ -0,0 +1,86 @@
+# iOS: Preparing Your App to Work with ATS
+
+If you use the iOS 9 SDK (or Xcode 7) or later, the Apple [App Transport Security (ATS)] (https://developer.apple.com/library/prerelease/ios/technotes/App-Transport-Security-Technote/)
+feature might impact how your apps interact with some AWS services.
+
+If your app targeted for iOS 9+ attempts to connect to an AWS service endpoint that does not yet meet all the ATS requirements, the connection may fail. The following sections provide instructions to determine if your app is affected, and what steps to take to mitigate the impact of ATS on your app.
+
+## Diagnosing ATS Conflicts
+
+If your app stops working after being upgraded to Xcode 7 or later and iOS 9 or later, follow these steps to determine if it affected by ATS.
+
+1. Turn on verbose logging of the AWS Mobile SDK for iOS by calling the following line in the ``- application:didFinishLaunchingWithOptions:`` application delegate.
+
+```swift
+@UIApplicationMain
+class AppDelegate: UIResponder, UIApplicationDelegate {
+
+ var window: UIWindow?
+ func application(application: UIApplication, didFinishLaunchingWithOptions
+ launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
+ ...
+ AWSLogger.default().logLevel = .verbose
+ ...
+
+ return true
+ }
+}
+```
+
+2. Run your app and make a request to an AWS service.
+
+3. Search your log output for "SSL". The message containing: "An SSL error has occurred and a secure connection to the server cannot be made" indicates that your app is affected by the ATS changes.
+
+```
+ 2015-10-06 11:39:13.402 DynamoDBSampleSwift[14467:303540] CFNetwork SSLHandshake failed (-9824)
+ 2015-10-06 11:39:13.403 DynamoDBSampleSwift[14467:303540] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9824)
+ 2015-10-06 11:39:13.569 DynamoDBSampleSwift[14467:303540] CFNetwork SSLHandshake failed (-9824)
+ 2015-10-06 11:39:13.569 DynamoDBSampleSwift[14467:303540] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9824)
+ Error: Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={_kCFStreamErrorCodeKey=-9824, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, NSUnderlyingError=0x7fca343012f0 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, _kCFNetworkCFStreamSSLErrorOriginalValue=-9824, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9824}}, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://dynamodb.us-east-1.amazonaws.com/, NSErrorFailingURLStringKey=https://dynamodb.us-east-1.amazonaws.com/, _kCFStreamErrorDomainKey=3}
+```
+ If you cannot find the SSL handshake error message, it is possible that another problem caused your app to stop working. Some internal behaviors change with major operating system updates, and it is common for previously unseen issues to surface.
+
+ If you are unable to resolve such issues, you can post code snippets, and steps to reproduce the issue on [our forum] (https://forums.aws.amazon.com/forum.jspa?forumID=88) or [GitHub] (https://github.com/aws/aws-sdk-ios/issues) so that we can assist you in identifying the issue. Remember to include the versions of Xcode, iOS, and the AWS Mobile SDK.
+
+## Mitigating ATS Connection Issues
+
+If you determine that your app is impacted by the diagnostic handshake error, you can configure the app to interact properly with the ATS feature by taking the following steps to add properties to your ``Info.plist`` file.
+
+1. Locate your ``Info.plist`` and from the context menu select **Open As** > **Source Code**.
+
+ 
+
+2. Copy and paste the following key as a direct child of the top level ```` tag.
+
+```xml
+
+ NSAppTransportSecurity
+
+ NSExceptionDomains
+
+ amazonaws.com
+
+ NSThirdPartyExceptionMinimumTLSVersion
+ TLSv1.0
+ NSThirdPartyExceptionRequiresForwardSecrecy
+
+ NSIncludesSubdomains
+
+
+ amazonaws.com.cn
+
+ NSThirdPartyExceptionMinimumTLSVersion
+ TLSv1.0
+ NSThirdPartyExceptionRequiresForwardSecrecy
+
+ NSIncludesSubdomains
+
+
+
+
+
+ . . .
+
+```
+
+After following these steps, your app should be able to access AWS endpoints while running on iOS 9 or later.
diff --git a/ios/how-to-ios-kinesis-data-stream.md b/ios/how-to-ios-kinesis-data-stream.md
new file mode 100755
index 00000000000..506129e69e9
--- /dev/null
+++ b/ios/how-to-ios-kinesis-data-stream.md
@@ -0,0 +1,206 @@
+# ios: Process Data Streams with Amazon Kinesis
+
+## Overview
+
+Amazon Kinesis is a fully managed service for real-time processing of streaming data at massive
+scale.
+
+The SDK for iOS provides two high-level client classes, `AWSKinesisRecorder` and
+`AWSFirehoseRecorder`, designed to help you interface with Amazon Kinesis and Amazon
+Kinesis Firehose.
+
+The Amazon Kinesis `AWSKinesisRecorder` client lets you store `PutRecord
+`_ requests on disk and
+then send them all at once. This is useful because many mobile applications that use Amazon Kinesis
+will create multiple `PutRecord` requests per second. Sending an individual request for
+each `PutRecord` action could adversely impact battery life. Moreover, the requests could
+be lost if the device goes offline. Thus, using the high-level Amazon Kinesis client for batching
+can preserve both battery life and data.
+
+The Amazon Kinesis Firehose `AWSFirehoseRecorder` client lets you store `PutRecords
+`_ requests on disk and
+then send them using Kinesis Data Firehose`PutRecordBatch`.
+
+For information about Amazon Kinesis Region availability, see [AWS Service Region Availability]
+(http://aws.amazon.com/about-aws/global-infrastructure/regional-product-services/).
+
+## What is Amazon Kinesis?
+
+[Amazon Kinesis] (http://aws.amazon.com/kinesis/) is a fully managed service for real-time
+processing of streaming data at massive scale. Amazon Kinesis can collect and process hundreds of
+terabytes of data per hour from hundreds of thousands of sources, so you can write applications that
+process information in real-time. With Amazon Kinesis applications, you can build real-time
+dashboards, capture exceptions and generate alerts, drive recommendations, and make other real-time
+business or operational decisions. You can also easily send data to other services such as Amazon
+Simple Storage Service, Amazon DynamoDB, and Amazon Redshift.
+
+
+## What is Amazon Kinesis Firehose?
+
+[Amazon Kinesis Firehose] (http://aws.amazon.com/kinesis/firehose/) is a fully managed service for
+delivering real-time streaming data to destinations such as Amazon Simple Storage Service (Amazon
+S3) and Amazon Redshift. With Firehose, you do not need to write any applications or manage any
+resources. You configure your data producers to send data to Firehose and it automatically delivers
+the data to the destination that you specified.
+
+For more information about Amazon Kinesis Firehose, see [Amazon Kinesis Firehose]
+(http://docs.aws.amazon.com/firehose/latest/dev/what-is-this-service.html).
+
+You can also learn more about how the Amazon Kinesis services work together on the following page: [Amazon
+Kinesis services] (http://aws.amazon.com/kinesis/).
+
+
+## Integrating Amazon Kinesis and Amazon Kinesis Firehose
+
+To use the Amazon Kinesis mobile client, you'll need to integrate the SDK for iOS into your app
+and import the necessary libraries. To do so, follow these steps:
+
+If you haven't already done so, [download the SDK for iOS] (http://aws.amazon.com/mobile/sdk/),
+unzip it, and include it in your application as described at `setup-aws-sdk-for-ios`. The
+instructions direct you to import the headers for the services you'll be
+using. For this example, you need the following import.
+
+```swift
+import AWSKinesis
+```
+
+You can use Amazon Cognito to provide temporary AWS credentials to your application.
+
+These credentials let the app access your AWS resources. To create a credentials provider, follow the instructions at [Cognito Identity Developer Guide] (http://docs.aws.amazon.com/cognito/devguide/identity/).
+
+To use Amazon Kinesis in an application, you must set the correct permissions. The
+following IAM policy allows the user to submit records to a specific Amazon Kinesis
+stream, which is identified by [ARN] (http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html).
+
+```json
+{
+ "Statement": [{
+ "Effect": "Allow",
+ "Action": "kinesis:PutRecords",
+ "Resource": "arn:aws:kinesis:us-west-2:111122223333:stream/mystream"
+ }]
+}
+```
+
+The following IAM policy allows the user to submit records to a specific Amazon Kinesis Firehose
+stream.
+
+```json
+{
+ "Statement": [{
+ "Effect": "Allow",
+ "Action": "firehose:PutRecordBatch",
+ "Resource": "arn:aws:firehose:us-west-2:111122223333:deliverystream/mystream"
+ }]
+}
+```
+
+This policy should be applied to roles assigned to the Amazon Cognito
+identity pool, but you need to replace the `Resource` value
+with the correct ARN for your Amazon Kinesis or Amazon Kinesis Firehose stream. You can apply policies at the
+[IAM console] (https://console.aws.amazon.com/iam/). To
+learn more about IAM policies, see [Using IAM] (http://docs.aws.amazon.com/IAM/latest/UserGuide/IAM_Introduction.html).
+
+To learn more about Amazon Kinesis-specific policies, see
+[Controlling Access to Amazon Kinesis Resources with IAM] (http://docs.aws.amazon.com/kinesis/latest/dev/kinesis-using-iam.html).
+
+To learn more about Amazon Kinesis Firehose policies, see [Controlling Access with Amazon Kinesis Firehose] (http://docs.aws.amazon.com/firehose/latest/dev/controlling-access.html).
+
+Once you have credentials, you can use `AWSKinesisRecorder` with Amazon Kinesis. The
+following snippet returns a shared instance of the Amazon Kinesis service client:
+
+```swift
+let kinesisRecorder = AWSKinesisRecorder.default()
+```
+
+You can use `AWSFirehoseRecorder` with Amazon Kinesis Firehose. The
+following snippet returns a shared instance of the Amazon Kinesis Firehose service client:
+
+```swift
+let firehoseRecorder = AWSFirehoseRecorder.default()
+```
+
+You can configure `AWSKinesisRecorder` or `AWSFirehoseRecorder` through their properties:
+
+```swift
+ kinesisRecorder.diskAgeLimit = TimeInterval(30 * 24 * 60 * 60); // 30 days
+ kinesisRecorder.diskByteLimit = UInt(10 * 1024 * 1024); // 10MB
+ kinesisRecorder.notificationByteThreshold = UInt(5 * 1024 * 1024); // 5MB
+```
+
+The `diskAgeLimit` property sets the expiration for cached requests.
+When a request exceeds the limit, it's discarded. The default is no age limit. The
+`diskByteLimit` property holds the limit of the disk cache size in
+bytes. If the storage limit is exceeded, older requests are discarded. The default
+value is 5 MB. Setting the value to 0 means that there's no practical limit. The
+`notficationByteThreshold` property sets the point beyond which
+Kinesis issues a notification that the byte threshold has been reached. The default
+value is 0, meaning that by default Amazon Kinesis doesn't post the notification.
+
+To see how much local storage is being used for Amazon Kinesis `PutRecord`
+requests, check the `diskBytesUsed` property.
+
+With `AWSKinesisRecorder` created and configured, you can use
+`saveRecord:streamName:` to save records to local storage.
+
+```swift
+let yourData = "Test_data".data(using: .utf8)
+kinesisRecorder.saveRecord(yourData, streamName: "YourStreamName")
+```
+
+In the preceding example, we create an NSData object and save it locally.
+`YourStreamName` should be a string corresponding to the name of your
+Kinesis stream. You can create new streams in the [Amazon Kinesis
+console] (https://console.aws.amazon.com/kinesis/).
+
+Here is a similar snippet for Amazon Kinesis Firehose:
+
+```swift
+let yourData = "Test_data".data(using: .utf8)
+firehoseRecorder.saveRecord(yourData, streamName: "YourStreamName")
+```
+
+To submit all the records stored on the device, call
+`submitAllRecords`.
+
+```swift
+kinesisRecorder.submitAllRecords()
+
+firehoseRecorder.submitAllRecords()
+```
+
+`submitAllRecords` sends all locally saved requests to the Amazon Kinesis
+service. Requests that are successfully sent will be deleted from the device.
+Requests that fail because the device is offline will be kept and submitted later.
+Invalid requests are deleted.
+
+Both `saveRecord` and `submitAllRecords` are asynchronous
+operations, so you should ensure that `saveRecord` is complete before you
+invoke `submitAllRecords`. The following code sample shows the methods
+used correctly together.
+
+```swift
+ // Create an array to store a batch of objects.
+ var tasks = Array>()
+ for i in 0...100 {
+ tasks.append(kinesisRecorder!.saveRecord(String(format: "TestString-%02d", i).data(using: .utf8), streamName: "YourStreamName")!)
+ }
+
+ AWSTask(forCompletionOfAllTasks: tasks).continueOnSuccessWith(block: { (task:AWSTask) -> AWSTask? in
+ return kinesisRecorder?.submitAllRecords()
+ }).continueWith(block: { (task:AWSTask) -> Any? in
+ if let error = task.error as? NSError {
+ print("Error: \(error)")
+ }
+ return nil
+ })
+```
+
+To learn more about working with Amazon Kinesis, see the [Amazon Kinesis Developer Resources]
+(http://aws.amazon.com/kinesis/developer-resources/).
+
+To learn more about the Amazon Kinesis classes, see the [class reference for AWSKinesisRecorder]
+(http://docs.aws.amazon.com/AWSiOSSDK/latest/Classes/AWSKinesisRecorder.html).
+
+For information about AWS service region availability, see [AWS Service Region Availability]
+(http://aws.amazon.com/about-aws/global-infrastructure/regional-product-services/).
diff --git a/ios/how-to-ios-lex.md b/ios/how-to-ios-lex.md
new file mode 100755
index 00000000000..0c379e8f282
--- /dev/null
+++ b/ios/how-to-ios-lex.md
@@ -0,0 +1,137 @@
+# iOS: Use Natural Language with Amazon Lex
+
+## Overview
+
+Amazon Lex is an AWS service for building voice and text conversational interfaces into applications. With , the same natural language understanding engine that powers Amazon Alexa is now available to any
+developer, enabling you to build sophisticated, natural language chatbots into your new and existing
+applications.
+
+The The AWS Mobile SDK for iOS provides an optimized client for interacting with Amazon Lex runtime APIs,
+which support both voice and text input and can return either voice or text. Included are features
+like APIs to support detecting when a user finishes speaking and encoding incoming audio to the format
+the Amazon Lex service prefers.
+
+Amazon Lex has built-in integration with AWS Lambda to allow insertion of custom business logic
+into your Amazon Lex processing flow, including all of the extension to other services that Lambda makes possible.
+
+For information on Amazon Lex concepts and service configuration, see
+[How it Works] (http://docs.aws.amazon.com/lex/latest/dg/how-it-works.html) in the Amazon Lex Developer Guide.
+
+To get started using the Amazon Lex mobile client for iOS, you'll need to integrate the SDK for iOS
+into your app, set the appropriate permissions, and import the necessary libraries.
+
+
+## Setting Up
+
+### Include the SDK in Your Project
+
+Follow the instructions on the [Set Up the SDK for iOS] (http://docs.aws.amazon.com/mobile/sdkforios/developerguide/setup.html) page to include the frameworks for this service.
+
+### Set IAM Permissions for Amazon Lex
+
+To use Amazon Lex in an application, create a role and attach policies as described in Step 1 of
+[Getting Started] (http://docs.aws.amazon.com/lex/latest/dg/gs-bp-prep.html) in the Amazon Lex Developer Guide.
+
+To learn more about IAM policies, see [Using IAM] (http://docs.aws.amazon.com/IAM/latest/UserGuide/IAM_Introduction.html).
+
+### Configure a Bot
+
+Use the [Amazon Lex console] (https://console.aws.amazon.com/lex/) console to configure a bot that interacts with your mobile app features. To learn more, see [Amazon Lex Developer Guide] (https://docs.aws.amazon.com/lex/latest/dg/what-is.html). For a quickstart, see [Getting Started] (https://alpha-docs-aws.amazon.com/lex/latest/dg/getting-started.html).
+
+Amazon Lex also supports model building APIs, which allow creation of bots, intents, and slots at runtime. This SDK does not currently offer additional support for interacting with Amazon Lex model building APIs.
+
+## Implement Text and Voice Interaction with Amazon Lex
+
+### Add Permissions and Get Credentials
+
+Take the following steps to allow your app to access device resources and AWS services.
+
+#### Add permission to use the microphone
+
+To add permission to use the microphone to enable users to speak to Amazon Lex through your app, open your project's `Info.plist` file using `Right-click > Open As > Source Code`, and then add the following entry.
+
+```xml
+
+ . . .
+
+ NSMicrophoneUsageDescription
+ For interaction with Amazon Lex
+
+ . . .
+
+```
+
+### Integrating the Interaction Client
+
+Take the following steps to integrate the Amazon Lex interaction client with your app.
+
+#### Initialize the `InteractionKit` for voice and text
+
+Add the following code using the name and alias of your Lex bot to initialize an instance of `InteractionKit`.
+
+
+```swift
+let chatConfig = AWSLexInteractionKitConfig.defaultInteractionKitConfig(withBotName: BotName, botAlias: BotAlias)
+
+// interaction kit for the voice button
+AWSLexInteractionKit.register(with: configuration!, interactionKitConfiguration: chatConfig, forKey: "AWSLexVoiceButton")
+
+chatConfig.autoPlayback = false
+
+// interaction kit configuration for the client
+AWSLexInteractionKit.register(with: configuration!, interactionKitConfiguration: chatConfig, forKey: "chatConfig")
+```
+
+#### Implement `InteractionKit` delegate methods
+
+Declare and implement the following methods in the class where you intend to use your `InteractionKit`:
+
+- `interactionKit` is called to begin a conversation. When passed `interactionKit`, `switchModeInput`, and `completionSource`, the function should set the mode of interaction (audio or text input and output) and pass the `SwitchModeResponse` to the `completionSource`. On error, the `interactionKit:onError` method is called.
+
+```swift
+ public func interactionKit(_ interactionKit: AWSLexInteractionKit, switchModeInput:
+ AWSLexSwitchModeInput, completionSource: AWSTaskCompletionSource?)
+
+ public func interactionKit(_ interactionKit: AWSLexInteractionKit, onError error: Error)
+```
+
+- Amazon Lex`interactionKitContinue` is called to continue an ongoing conversation with its transaction state and metadata maintained.
+
+```swift
+func interactionKitContinue(withText interactionKit: AWSLexInteractionKit, completionSource: AWSTaskCompletionSource){
+ textModeSwitchingCompletion = completionSource
+}
+```
+
+ Alternatively, you can explicitly set `SwitchModeResponse` to a selected mode.
+
+ ```swift
+ let switchModeResponse = AWSLexSwitchModeResponse()
+ switchModeResponse.interactionMode = AWSLexInteractionMode.text
+ switchModeResponse.sessionAttributes = switchModeInput.sessionAttributes
+ completionSource?.setResult(switchModeResponse)
+ ```
+
+#### Begin or Continue a Conversation
+
+When you call `InteractionKit` to provide input for a conversation, check if the conversation is already in progress by examining the state of `AWSTaskCompletionSource`. The following example illustrates the case where `textModeSwitchingCompletion` is an `AWSTaskCompletionSource` instance and the desired result is that a new conversation will be in the `texttInTextOut` mode.
+
+```swift
+ if let textModeSwitchingCompletion = textModeSwitchingCompletion {
+ textModeSwitchingCompletion.setResult(text)
+ self.textModeSwitchingCompletion = nil
+ }
+ else {
+ self.interactionKit?.textInTextOut(text)
+ }
+```
+
+### Integrating Voice Conversation
+
+Perform the following tasks to implement voice interaction with Amazon Lex in your iOS app.
+
+#### Add a voice button and bind it to the Lex SDK UI component
+
+Add a voice UIView into your storyboard scene or xib file, add a voice button (the UI element that enables users to speak to Amazon Lex). Map the voice button to the SDK button component by setting the `class` for the voice UIView to `AWSLexVoiceButton` as illustrated in the following image.
+
+
diff --git a/ios/how-to-ios-s3-presigned-urls.md b/ios/how-to-ios-s3-presigned-urls.md
new file mode 100755
index 00000000000..c5a68133480
--- /dev/null
+++ b/ios/how-to-ios-s3-presigned-urls.md
@@ -0,0 +1,89 @@
+# Amazon S3 Pre-Signed URLs: For Background Transfer
+
+If you are working with large file transfers, you
+may want to perform uploads and downloads in the background. To do this, you need to create a
+background session using ``NSURLSession`` and then transfer your objects using pre-signed URLs.
+
+The following sections describe pre-signed Amazon S3 URLs. To learn more about ``NSURLSession``, see
+[Using NSURLSession] (https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/URLLoadingSystem/Articles/UsingNSURLSession.html).
+
+## Pre-Signed URLs
+By default, all Amazon S3 resources are private. If you want your users to have access to Amazon S3 buckets
+or objects, you can assign appropriate permissions with an [IAM policy] (http://docs.aws.amazon.com/IAM/latest/UserGuide/PoliciesOverview.html).
+
+Alternatively, you can use pre-signed URLs to give your users access to Amazon S3 objects. A pre-signed URL
+provides access to an object without requiring AWS security credentials or permissions.
+
+When you create a pre-signed URL, you must provide your security credentials, specify a bucket name,
+an object key, an HTTP method, and an expiration date and time. The pre-signed URL is valid only for the specified duration.
+
+## Build a Pre-Signed URL
+
+The following example shows how to build a pre-signed URL for an Amazon S3 download in the background.
+
+```swift
+ AWSS3PreSignedURLBuilder.default().getPreSignedURL(getPreSignedURLRequest).continueWith { (task:AWSTask) -> Any? in
+ if let error = task.error as? NSError {
+ print("Error: \(error)")
+ return nil
+ }
+
+ let presignedURL = task.result
+ print("Download presignedURL is: \(presignedURL)")
+
+ let request = URLRequest(url: presignedURL as! URL)
+ let downloadTask: URLSessionDownloadTask = URLSession.shared.downloadTask(with: request)
+ downloadTask.resume()
+
+ return nil
+ }
+```
+
+The preceding example uses ``GET`` as the HTTP method: ``AWSHTTPMethodGET``. For an upload request to Amazon S3,
+we would need to use a PUT method and also specify a content type.
+
+```swift
+ getPreSignedURLRequest.httpMethod = .PUT
+ let fileContentTypeStr = "text/plain"
+ getPreSignedURLRequest.contentType = fileContentTypeStr
+```
+
+Here's an example of building a pre-signed URL for a background upload to Amazon S3.
+
+```swift
+ let getPreSignedURLRequest = AWSS3GetPreSignedURLRequest()
+ getPreSignedURLRequest.bucket = "myBucket"
+ getPreSignedURLRequest.key = "myFile.txt"
+ getPreSignedURLRequest.httpMethod = .PUT
+ getPreSignedURLRequest.expires = Date(timeIntervalSinceNow: 3600)
+
+ //Important: set contentType for a PUT request.
+ let fileContentTypeStr = "text/plain"
+ getPreSignedURLRequest.contentType = fileContentTypeStr
+
+ AWSS3PreSignedURLBuilder.default().getPreSignedURL(getPreSignedURLRequest).continueWith { (task:AWSTask) -> Any? in
+ if let error = task.error as? NSError {
+ print("Error: \(error)")
+ return nil
+ }
+
+ let presignedURL = task.result
+ print("Download presignedURL is: \(presignedURL)")
+
+ var request = URLRequest(url: presignedURL as! URL)
+ request.cachePolicy = .reloadIgnoringLocalCacheData
+ request.httpMethod = "PUT"
+ request.setValue(fileContentTypeStr, forHTTPHeaderField: "Content-Type")
+
+ let uploadTask: URLSessionTask = URLSession.shared.uploadTask(with: request, fromFile: URL(fileURLWithPath: "your/file/path/myFile.txt"))
+ uploadTask.resume()
+
+ return nil
+ }
+```
+
+## Additional Resources
+
+* [Amazon Simple Storage Service Getting Started Guide] (http://docs.aws.amazon.com/AmazonS3/latest/gsg/GetStartedWithS3.html)
+* [Amazon Simple Storage Service API Reference] (http://docs.aws.amazon.com/AmazonS3/latest/API/Welcome.html)
+* [Amazon Simple Storage Service Developer Guide] (http://docs.aws.amazon.com/AmazonS3/latest/dev/Welcome.html)
diff --git a/ios/how-to-ios-s3-server-side-encryption.md b/ios/how-to-ios-s3-server-side-encryption.md
new file mode 100755
index 00000000000..f68d8f77e8a
--- /dev/null
+++ b/ios/how-to-ios-s3-server-side-encryption.md
@@ -0,0 +1,65 @@
+# Amazon S3 Server-Side Encryption Support in iOS
+
+The AWS Mobile SDK for iOS supports server-side encryption of Amazon S3 data. To learn more about server-side
+encryption, see [PUT Object] (http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html).
+
+The following properties are available to configure the encryption:
+
+* [SSECustomerAlgorithm] (http://docs.aws.amazon.com/AWSiOSSDK/latest/Classes/AWSS3ReplicateObjectOutput.html#//api/name/SSECustomerAlgorithm)
+* [SSECustomerKey] (http://docs.aws.amazon.com/AWSiOSSDK/latest/Classes/AWSS3UploadPartRequest.html#//api/name/SSECustomerKey)
+* [SSECustomerKeyMD5] (http://docs.aws.amazon.com/AWSiOSSDK/latest/Classes/AWSS3PutObjectOutput.html#//api/name/SSECustomerKeyMD5)
+* [AWSS3ServerSideEncryption] (http://docs.aws.amazon.com/AWSiOSSDK/latest/Constants/AWSS3ServerSideEncryption.html)
+
+To use these properties, add the following statement which imports the ``AWSSS3Model``.
+
+```swift
+import AWSS3
+```
+
+``SSECustomerAlgorithm`` is a property of ``AWSS3ReplicateObjectOutput``. If server-side encryption
+with a customer-provided encryption key was requested, the response will include this header,
+which confirms the encryption algorithm that was used. Currently, the only valid option is AES256. You can
+access ``SSECustomerAlgorithm`` as follows.
+
+```swift
+let replicateObjectOutput = AWSS3ReplicateObjectOutput()
+replicateObjectOutput?.sseCustomerAlgorithm = "mySseCustomerAlgorithm"
+```
+
+``SSECustomerKey``, a property of ``AWSS3UploadPartRequest``, specifies the customer-provided
+encryption key for Amazon S3 to use to encrypting data. This value is used to store the object,
+and is then discarded; Amazon doesn't store the encryption key. The key must be appropriate for
+use with the algorithm specified in the ``x-amz-server-side-encryption-customer-algorithm`` header.
+This must be the same encryption key specified in the request to initiate a multipart upload. You
+can access SSECustomerKey as follows.
+
+```swift
+let uploadPartRequest = AWSS3UploadPartRequest()
+uploadPartRequest?.sseCustomerKey = "customerProvidedEncryptionKey"
+```
+
+``SSECustomerKeyMD5`` is a property of ``AWSS3PutObjectOutput``. If server-side encryption
+with a customer-provided encryption key is requested, the response will include this
+header. The response provides round trip message integrity verification of the customer-provided
+encryption key. You can access ``SSECustomerKeyMD5`` as follows.
+
+```swift
+let objectOutput = AWSS3PutObjectOutput()
+// Access objectOutput?.sseCustomerKeyMD5 ...
+```
+
+``AWSS3ServerSideEncryption`` represents the encryption algorithm for storing an object in Amazon S3. You
+can access it as follows.
+
+```swift
+let objectOutput = AWSS3PutObjectOutput()
+// Access objectOutput?.sseCustomerKeyMD5 ...
+```
+## Additional Resources
+
+* [Amazon Simple Storage Service Getting Started Guide] (http://docs.aws.amazon.com/AmazonS3/latest/gsg/GetStartedWithS3.html)
+* [Amazon Simple Storage Service API Reference] (http://docs.aws.amazon.com/AmazonS3/latest/API/Welcome.html)
+* [Amazon Simple Storage Service Developer Guide] (http://docs.aws.amazon.com/AmazonS3/latest/dev/Welcome.html)
+
+.. _Identity and Access Management Console: https://console.aws.amazon.com/iam/home
+.. _Granting Access to an Amazon S3 Bucket: http://blogs.aws.amazon.com/security/post/Tx3VRSWZ6B3SHAV/Writing-IAM-Policies-How-to-grant-access-to-an-Amazon-S3-bucket
diff --git a/ios/how-to-ios-sdk-setup.md b/ios/how-to-ios-sdk-setup.md
new file mode 100755
index 00000000000..646e3d1ab35
--- /dev/null
+++ b/ios/how-to-ios-sdk-setup.md
@@ -0,0 +1,405 @@
+# iOS: Setup Options for the SDK
+
+**Just Getting Started?** | `Use streamlined steps ` to install the SDK and integrate AWS features.
+------------ | -------------
+
+*Or, use the contents of this page if your app will integrate existing AWS services.*
+
+To add the SDK, install the following on your development machine:
+
+- Xcode 7 or later
+
+- iOS 8 or later
+
+You can view the source code in the [AWS Mobile SDK for iOS GitHub repository] (https://github.com/aws/aws-sdk-ios).
+
+## Include the AWS Mobile SDK for iOS in an Existing Application
+
+The samples included with the SDK are standalone projects that are already set up. You can also integrate the SDK into your own existing project. Choose one of the following three ways to import the SDK into your project:
+
+- Cocoapods
+- Carthage
+- Dynamic Frameworks
+
+Importing the SDK in multiple ways loads duplicate copies of the SDK into the project and causes compiler errors.
+
+CocoaPods
+1. The AWS Mobile SDK for iOS is available through [CocoaPods] (http://cocoapods.org/). Install CocoaPods by running the following commands from the folder containing your projects `*.xcodeproj` file.
+
+ $ `gem install cocoapods`
+
+ Depending on your system settings, you may need to run the command as administrator using `sudo`, as follows:
+
+ $ `sudo gem install cocoapods`
+
+ $ `pod setup`
+
+ $ `pod init`
+
+2. In your project directory (the directory where your `*.xcodeproj` file is), open the empty text file named `Podfile` (without a file extension) and add the following lines to the file. Replace ``myAppName`` with your app name. You can also remove pods for services that you don't use. For example, if you don't use `AWSAutoScaling`, remove or do not include the ``AWSAutoScaling`` pod.
+
+```javascript
+ source 'https://github.com/CocoaPods/Specs.git'
+
+ platform :ios, '8.0'
+ use_frameworks!
+
+ target :'YOUR-APP-NAME' do
+ pod 'AWSAuth'
+ pod 'AWSAuthCore'
+ pod 'AWSAuthUI'
+ pod 'AWSAutoScaling'
+ pod 'AWSCloudWatch'
+ pod 'AWSCognito'
+ pod 'AWSCognitoAuth'
+ pod 'AWSCognitoIdentityProvider'
+ pod 'AWSCognitoIdentityProviderASF'
+ pod 'AWSCore'
+ pod 'AWSDynamoDB'
+ pod 'AWSEC2'
+ pod 'AWSElasticLoadBalancing'
+ pod 'AWSFacebookSignIn'
+ pod 'AWSGoogleSignIn'
+ pod 'AWSIoT'
+ pod 'AWSKMS'
+ pod 'AWSKinesis'
+ pod 'AWSLambda'
+ pod 'AWSLex'
+ pod 'AWSLogs'
+ pod 'AWSMachineLearning'
+ pod 'AWSMobileAnalytics'
+ pod 'AWSMobileClient'
+ pod 'AWSPinpoint'
+ pod 'AWSPolly'
+ pod 'AWSRekognition'
+ pod 'AWSS3'
+ pod 'AWSSES'
+ pod 'AWSSNS'
+ pod 'AWSSQS'
+ pod 'AWSSimpleDB'
+ pod 'AWSUserPoolsSignIn'
+ end
+```
+
+3. Run the following command:
+
+ $ `pod install`
+
+4. Open `*.xcworkspace` with Xcode, rebuild your app, and start using the SDK.
+
+ Once you have created a workspace, always use `*.xcworkspace` to open the project instead of `*.xcodeproj`.
+
+5. Rebuild your app after reopening it in the workspace to resolve APIs from new libraries called in your code. This is a good practice any time you add import statements.
+
+
+Carthage
+1. Install the latest version of `Carthage `__.
+
+2. Add the following to your `Cartfile`::
+
+ github "aws/aws-sdk-ios"
+
+3. Run the following command:
+
+ $ `carthage update`
+
+4. With your project open in Xcode, choose your **Target**. In the **General** tab, find **Embedded Binaries**, then choose the **+** button.
+
+5. Choose the **Add Other** button, navigate to the ``AWS<#ServiceName#>.framework`` files under **Carthage** > **Build** > **iOS** and select ``AWSCore.framework`` and the other service frameworks you require. Do not select the **Destination: Copy items if needed** check box when prompted.
+
+ * :code:`AWSAuth`
+ * :code:`AWSAuthCore`
+ * :code:`AWSAuthUI`
+ * :code:`AWSAutoScaling`
+ * :code:`AWSCloudWatch`
+ * :code:`AWSCognito`
+ * :code:`AWSCognitoAuth`
+ * :code:`AWSCognitoIdentityProvider`
+ * :code:`AWSCognitoIdentityProviderASF`
+ * :code:`AWSCore`
+ * :code:`AWSDynamoDB`
+ * :code:`AWSEC2`
+ * :code:`AWSElasticLoadBalancing`
+ * :code:`AWSFacebookSignIn`
+ * :code:`AWSGoogleSignIn`
+ * :code:`AWSIoT`
+ * :code:`AWSKMS`
+ * :code:`AWSKinesis`
+ * :code:`AWSLambda`
+ * :code:`AWSLex`
+ * :code:`AWSLogs`
+ * :code:`AWSMachineLearning`
+ * :code:`AWSMobileAnalytics`
+ * :code:`AWSMobileClient`
+ * :code:`AWSPinpoint`
+ * :code:`AWSPolly`
+ * :code:`AWSRekognition`
+ * :code:`AWSS3`
+ * :code:`AWSSES`
+ * :code:`AWSSNS`
+ * :code:`AWSSQS`
+ * :code:`AWSSimpleDB`
+ * :code:`AWSUserPoolsSignIn`
+
+6. Under the **Build Phases** tab in your **Target**, choose the **+** button on the top left and then select **New Run Script Phase**.
+
+7. Setup the build phase as follows. Make sure this phase is below the **Embed Frameworks** phase.
+
+ ```bash
+ Shell /bin/sh
+
+ bash "${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/AWSCore.framework/strip-frameworks.sh"
+
+ Show environment variables in build log: Checked
+ Run script only when installing: Not checked
+
+ Input Files: Empty
+ Output Files: Empty
+ ```
+
+Frameworks
+1. Download the SDK from http://aws.amazon.com/mobile/sdk. The SDK is stored in a compressed
+ file archive named `aws-ios-sdk-#.#.#`, where '#.#.#' represents the version number. For version
+ 2.5.0, the filename is `aws-ios-sdk-2.5.0`.
+
+
+2. With your project open in Xcode, choose your **Target**. Under the **General** tab, find
+ **Embedded Binaries** and then choose the **+** button.
+
+3. Choose **Add Other**. Navigate to the ``AWS<#ServiceName#>.framework`` files
+ and select ``AWSCore.framework`` and the other service frameworks you require. Select
+ the **Destination: Copy items if needed** check box when prompted.
+
+ * :code:`AWSAuth`
+ * :code:`AWSAuthCore`
+ * :code:`AWSAuthUI`
+ * :code:`AWSAutoScaling`
+ * :code:`AWSCloudWatch`
+ * :code:`AWSCognito`
+ * :code:`AWSCognitoAuth`
+ * :code:`AWSCognitoIdentityProvider`
+ * :code:`AWSCognitoIdentityProviderASF`
+ * :code:`AWSCore`
+ * :code:`AWSDynamoDB`
+ * :code:`AWSEC2`
+ * :code:`AWSElasticLoadBalancing`
+ * :code:`AWSFacebookSignIn`
+ * :code:`AWSGoogleSignIn`
+ * :code:`AWSIoT`
+ * :code:`AWSKMS`
+ * :code:`AWSKinesis`
+ * :code:`AWSLambda`
+ * :code:`AWSLex`
+ * :code:`AWSLogs`
+ * :code:`AWSMachineLearning`
+ * :code:`AWSMobileAnalytics`
+ * :code:`AWSMobileClient`
+ * :code:`AWSPinpoint`
+ * :code:`AWSPolly`
+ * :code:`AWSRekognition`
+ * :code:`AWSS3`
+ * :code:`AWSSES`
+ * :code:`AWSSNS`
+ * :code:`AWSSQS`
+ * :code:`AWSSimpleDB`
+ * :code:`AWSUserPoolsSignIn`
+
+4. Under the **Build Phases** tab in your **Target**, click the **+** button on the top left and then select **New Run Script Phase**.
+
+5. Setup the build phase as follows. Make sure this phase is below the `Embed Frameworks` phase.
+
+```bash
+ Shell /bin/sh
+
+ bash "${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/AWSCore.framework/strip-frameworks.sh"
+
+ Show environment variables in build log: Checked
+ Run script only when installing: Not checked
+
+ Input Files: Empty
+ Output Files: Empty
+```
+
+### Update the SDK to a Newer Version
+
+This section describes how to pick up changes when a new SDK is released.
+
+CocoaPods
+
+Run the following command in your project directory. CocoaPods automatically picks up the changes.
+
+ `$ pod update`
+
+ If your pod update command fails, delete `Podfile.lock` and `Pods/`
+ and then run `pod install` to cleanly install the SDK.
+
+Carthage
+
+Run the following command in your project directory. Carthage automatically updates
+your frameworks with the new changes.
+
+ `$ carthage update`
+
+Frameworks
+
+1. In Xcode select the following frameworks in **Project Navigator** and press the **delete** key. Then select **Move to Trash**:
+
+ * :code:`AWSAuth`
+ * :code:`AWSAuthCore`
+ * :code:`AWSAuthUI`
+ * :code:`AWSAutoScaling`
+ * :code:`AWSCloudWatch`
+ * :code:`AWSCognito`
+ * :code:`AWSCognitoAuth`
+ * :code:`AWSCognitoIdentityProvider`
+ * :code:`AWSCognitoIdentityProviderASF`
+ * :code:`AWSCore`
+ * :code:`AWSDynamoDB`
+ * :code:`AWSEC2`
+ * :code:`AWSElasticLoadBalancing`
+ * :code:`AWSFacebookSignIn`
+ * :code:`AWSGoogleSignIn`
+ * :code:`AWSIoT`
+ * :code:`AWSKMS`
+ * :code:`AWSKinesis`
+ * :code:`AWSLambda`
+ * :code:`AWSLex`
+ * :code:`AWSLogs`
+ * :code:`AWSMachineLearning`
+ * :code:`AWSMobileAnalytics`
+ * :code:`AWSMobileClient`
+ * :code:`AWSPinpoint`
+ * :code:`AWSPolly`
+ * :code:`AWSRekognition`
+ * :code:`AWSS3`
+ * :code:`AWSSES`
+ * :code:`AWSSNS`
+ * :code:`AWSSQS`
+ * :code:`AWSSimpleDB`
+ * :code:`AWSUserPoolsSignIn`
+
+2. Follow the Frameworks installation steps in the previous section, to include the new version of the SDK.
+
+
+### Logging
+
+As of version 2.5.4 of this SDK, logging utilizes [CocoaLumberjack SDK] (https://github.com/CocoaLumberjack/CocoaLumberjack), a flexible, fast, open source logging framework. It supports many capabilities including the ability to set logging level per output target, for instance, concise messages logged to the console and verbose messages to a log file.
+
+CocoaLumberjack logging levels are additive such that when the level is set to verbose, all messages from the levels below verbose are logged. It is also possible to set custom logging to meet your needs. For more information, see [CocoaLumberjack Logging Levels] (https://github.com/CocoaLumberjack/CocoaLumberjack/blob/master/Documentation/CustomLogLevels.md).
+
+## Changing Logging Level
+
+You can change the logging level to suit the phase of your development cycle by importing AWSCore and calling:
+
+```swift
+:code:`AWSDDLog.sharedInstance().logLevel = .verbose`
+
+The following logging level options are available:
+
+- ``.off``
+- ``.error``
+- ``.warning``
+- ``.info``
+- ``.debug``
+- ``.verbose``
+```
+We recommend setting the log level to ``.off`` before publishing to the App Store.
+
+
+## Targeting Log Output
+
+CocoaLumberjack can direct logs to file or used as a framework that integrates with the Xcode console.
+
+To initialize logging to files, use the following code:
+
+```swift
+let fileLogger: AWSDDFileLogger = AWSDDFileLogger() // File Logger
+fileLogger.rollingFrequency = TimeInterval(60*60*24) // 24 hours
+fileLogger.logFileManager.maximumNumberOfLogFiles = 7
+AWSDDLog.add(fileLogger)
+```
+
+To initialize logging to your Xcode console, use the following code:
+
+```swift
+AWSDDLog.add(AWSDDTTYLogger.sharedInstance) // TTY = Xcode console
+```
+
+To learn more, see [CocoaLumberjack] (https://github.com/CocoaLumberjack/CocoaLumberjack) on GitHub.
+
+### Sample Apps
+
+The AWS Mobile SDK for iOS includes sample apps that demonstrate common use cases.
+
+**Amazon Cognito Your User Pools Sample** ([Objective-C] (https://github.com/awslabs/aws-sdk-ios-samples/tree/master/CognitoYourUserPools-Sample/Objective-C/))
+
+ This sample demonstrates how sign up and sign in a user to display an authenticated portion of your app.
+
+ AWS services demonstrated:
+
+ - [Amazon Cognito Pools] (http://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools.html)
+ - [Amazon Cognito Identity] (http://aws.amazon.com/cognito/)
+
+**Amazon DynamoDB Object Mapper Sample**
+([Swift] (https://github.com/awslabs/aws-sdk-ios-samples/tree/master/DynamoDBObjectMapper-Sample/Swift), [Objective-C] (https://github.com/awslabs/aws-sdk-ios-samples/tree/master/DynamoDBObjectMapper-Sample/Objective-C/))
+
+ This sample demonstrates how to insert, update, delete, query items using DynamoDBObjectMapper.
+
+ AWS services demonstrated:
+
+ - [Amazon DynamoDB] (http://aws.amazon.com/dynamodb/)
+ - [Amazon Cognito Identity] (http://aws.amazon.com/cognito/)
+
+**Amazon S3 Transfer Utility Sample**
+([Swift] (https://github.com/awslabs/aws-sdk-ios-samples/tree/master/S3TransferUtility-Sample/Swift/), `Objective-C (https://github.com/awslabs/aws-sdk-ios-samples/tree/master/S3TransferUtility-Sample/Objective-C/))
+
+ This sample demonstrates how to use the Amazon S3 TransferUtility to download / upload files.
+
+ AWS services demonstrated:
+
+ - [Amazon S3] (http://aws.amazon.com/s3/)
+ - [Amazon Cognito Identity] (http://aws.amazon.com/cognito/)
+
+
+### Install the Reference Documentation in Xcode
+
+The AWS Mobile SDK for iOS includes documentation in the DocSets format that you can view within
+Xcode. The easiest way to install the documentation is to use the macOS terminal.
+
+## To install the DocSet for Xcode
+
+Open the macOS terminal and go to the directory containing the expanded
+archive. For example:
+
+ `$ cd ~/Downloads/aws-ios-sdk-2.5.0`
+
+Replace `2.5.0` in the preceding example with the
+version number of the AWS Mobile SDK for iOS that you downloaded.
+
+Create a directory called
+`~/Library/Developer/Shared/Documentation/DocSets`:
+
+
+ `$ mkdir -p ~/Library/Developer/Shared/Documentation/DocSets`
+
+Copy (or move) `documentation/com.amazon.aws.ios.docset`
+from the SDK installation files to the directory you created in the previous
+step:
+
+ `$ mv documentation/com.amazon.aws.ios.docset ~/Library/Developer/Shared/Documentation/DocSets/`
+
+If Xcode was running during this procedure, restart Xcode. To browse the
+documentation, go to `Help`, click `Documentation and API Reference`, and select `AWS Mobile SDK for iOS v2.0 Documentation`
+(where '2.0' is the appropriate version number).
+
+### Next Steps
+
+- **Run the demos**: View our [sample iOS apps]
+ (https://github.com/awslabs/aws-sdk-iOS-samples) that demonstrate common use cases. To run
+ the sample apps, set up the SDK for iOS as described above, and then follow the instructions
+ contained in the README files of the individual samples.
+
+- **Read the API Reference**: View the [API Reference]
+ (https://docs.aws.amazon.com/AWSiOSSDK/latest/) for the AWS Mobile SDK for Android.
+
+- **Ask questions**: Post questions on the `AWS Mobile SDK Forums <88>`.
diff --git a/ios/how-to-polly.md b/ios/how-to-polly.md
new file mode 100755
index 00000000000..30372d3eaa0
--- /dev/null
+++ b/ios/how-to-polly.md
@@ -0,0 +1,13 @@
+# Convert Text to Speech with Amazon Polly
+
+Amazon Polly is a service that turns text into lifelike speech, making it easy to develop mobile applications that use high-quality speech to increase engagement and accessibility. With Amazon Polly you can quickly build speech-enabled apps that work in multiple geographies.
+
+Using the following resources, you can integrate Amazon Polly with your iOS app to add text to speech transformation. No deep knowledge of either AWS services or natural language computing is needed.
+
+For information on Amazon Polly concepts and service configuration, see [How it Works] (http://docs.aws.amazon.com/polly/latest/dg/how-text-to-speech-works.html) in the Amazon Polly Developer Guide.
+
+## iOS
+
+* For sample iOS integration code, see the [iOS Amazon Polly Example] (https://docs.aws.amazon.com/polly/latest/dg/examples-ios.html).
+
+* For more end to end sample apps using Amazon Polly see the [AWS SDK for iOS samples] (https://github.com/awslabs/aws-sdk-ios-samples/).
diff --git a/ios/how-to-transfer-files-with-transfer-utility.md b/ios/how-to-transfer-files-with-transfer-utility.md
new file mode 100755
index 00000000000..84b2d688318
--- /dev/null
+++ b/ios/how-to-transfer-files-with-transfer-utility.md
@@ -0,0 +1,1448 @@
+# Transfer Files and Data Using TransferUtility and Amazon S3
+
+**Just Getting Started?** | [Use streamlined steps] (./add-aws-mobile-user-data-storage) to install the SDK and integrate Amazon S3.
+------------ | -------------
+
+*Or, use the contents of this page if your app will integrate existing AWS services.*
+
+This page explains how to implement upload and download functionality and a number of additional storage use cases.
+
+The examples on this page assume you have added the AWS Mobile SDK to your mobile app. To create a new cloud storage backend for your app, see [Add User File Storage] (./add-aws-mobile-user-data-storage).
+
+**Best practice** | If you use the transfer utility multipart upload feature, take advantage of automatic cleanup features by setting up the [AbortIncompleteMultipartUpload] (https://docs.aws.amazon.com/AmazonS3/latest/dev/intro-lifecycle-rules.html) action in your Amazon S3 bucket life cycle configuration.
+------------ | -------------
+
+## Upload a File
+
+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. AWSMobileClient expects an activity context for resuming an authenticated session and creating the credentials provider.
+
+The following example shows using the transfer utility in the context of an Activity. If you are creating transfer utility from an application context, you can construct the CredentialsProvider and
+AWSConfiguration object and pass it into TransferUtility. The TransferUtility will check the size of file being uploaded and will automatically switch over to using multi part uploads if the file size exceeds 5 MB.
+
+```java
+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 {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ AWSMobileClient.getInstance().initialize(this).execute();
+ uploadWithTransferUtility();
+ }
+
+ private void uploadWithTransferUtility() {
+
+ 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"));
+
+ // Attach a listener to the observer to get state update and progress notifications
+ 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("YourActivity", "ID:" + id + " bytesCurrent: " + bytesCurrent
+ + " bytesTotal: " + bytesTotal + " " + percentDone + "%");
+ }
+
+ @Override
+ public void onError(int id, Exception ex) {
+ // Handle errors
+ }
+
+ });
+
+ // If you prefer to poll for the data, instead of attaching a
+ // listener, check for the state and progress in the observer.
+ if (TransferState.COMPLETED == uploadObserver.getState()) {
+ // Handle a completed upload.
+ }
+
+ Log.d("YourActivity", "Bytes Transferred: " + uploadObserver.getBytesTransferred());
+ Log.d("YourActivity", "Bytes Total: " + uploadObserver.getBytesTotal());
+ }
+}
+```
+
+Android - Kotlin
+
+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. AWSMobileClient expects an activity context for resuming an authenticated session and creating the credentials provider.
+
+The following example shows using the transfer utility in the context of an Activity. If you are creating transfer utility from an application context, you can construct the CredentialsProvider and
+AWSConfiguration object and pass it into TransferUtility. The TransferUtility will check the size of file being uploaded and will automatically switch over to using multi part uploads if the file size exceeds 5 MB.
+
+```java
+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;
+
+class MainActivity : Activity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate()
+ AWSMobileClient.getInstance().initialize(this).execute()
+ uploadWithTransferUtility(
+ "s3Folder/s3Key.txt"
+ File("/path/to/file/localfile.txt")
+ )
+ }
+
+ private fun uploadWithTransferUtility(remote: String, local: File) {
+ val txUtil = TransferUtility.builder()
+ .context(getApplicationContext)
+ .awsConfiguration(AWSMobileClient.getInstance().configuration)
+ .s3Client(AmazonS3Client(AWSMobileClient.getInstance().credentialsProvider))
+ .build()
+
+ val txObserver = txUtil.upload(remote, local)
+ txObserver.transferListener = object : TransferListener() {
+ override fun onStateChanged(id: Int, state: TransferState) {
+ if (state == TransferState.COMPLETED) {
+ // Handle a completed upload
+ }
+ }
+
+ override fun onProgressChanged(id: Int, current: Long, total: Long) {
+ val done = (((current / total) * 100.0) as Float) as Int
+ Log.d(TAG, "ID: $id, percent done = $done")
+ }
+
+ override fun onError(id: Int, ex: Exception) {
+ // Handle errors
+ }
+ }
+
+ // If you prefer to poll for the data, instead of attaching a
+ // listener, check for the state and progress in the observer.
+ if (txObserver.state == TransferState.COMPLETED) {
+ // Handle a completed upload.
+ }
+ }
+}
+```
+
+iOS - Swift
+ The transfer utility provides methods for both single-part and multipart uploads. When a transfer uses multipart upload, the data is chunked into a number of 5 MB parts which are transferred in parallel for increased speed.
+
+ The following example shows how to upload a file to an Amazon S3 bucket.
+
+```swift
+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;
+ }
+}
+```
+
+The following example shows how to upload a file to an Amazon S3 bucket using multipart uploads.
+
+```swift
+func uploadData() {
+
+ let data: Data = Data() // Data to be uploaded
+
+ let expression = AWSS3TransferUtilityMultiPartUploadExpression()
+ expression.progressBlock = {(task, progress) in
+ DispatchQueue.main.async(execute: {
+ // Do something e.g. Update a progress bar.
+ })
+ }
+
+ var completionHandler: AWSS3TransferUtilityMultiPartUploadCompletionHandlerBlock
+ 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.uploadUsingMultiPart(data: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 - 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. AWSMobileClient expects an activity context for resuming an authenticated session and creating the credentials provider.
+
+This example shows using the transfer utility in the context of an Activity. If you are creating transfer utility from an application context, you can construct the CredentialsProvider and
+AWSConfiguration object and pass it into TransferUtility.
+
+```java
+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 {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ AWSMobileClient.getInstance().initialize(this).execute();
+ downloadWithTransferUtility();
+ }
+
+ public void downloadWithTransferUtility() {
+
+ 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"));
+
+ // Attach a listener to the observer to get notified of the
+ // updates in the state and the progress
+ 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
+ }
+
+ });
+
+ // If you do not want to attach a listener and poll for the data
+ // from the observer, you can check for the state and the progress
+ // in the observer.
+ if (TransferState.COMPLETED == downloadObserver.getState()) {
+ // Handle a completed upload.
+ }
+
+ Log.d("YourActivity", "Bytes Transferred: " + downloadObserver.getBytesTransferred());
+ Log.d("YourActivity", "Bytes Total: " + downloadObserver.getBytesTotal());
+ }
+}
+```
+
+Android - Kotlin
+
+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. AWSMobileClient expects an activity context for resuming an authenticated session and creating the credentials provider.
+
+This example shows using the transfer utility in the context of an Activity. If you are creating transfer utility from an application context, you can construct the CredentialsProvider and
+AWSConfiguration object and pass it into TransferUtility.
+
+```java
+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;
+
+class MainActivity : Activity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate()
+ AWSMobileClient.getInstance().initialize(this).execute()
+ downloadWithTransferUtility(
+ "s3Folder/s3Key.txt"
+ File("/path/to/file/localfile.txt")
+ )
+ }
+
+ private fun downloadWithTransferUtility(remote: String, local: File) {
+ val txUtil = TransferUtility.builder()
+ .context(getApplicationContext)
+ .awsConfiguration(AWSMobileClient.getInstance().configuration)
+ .s3Client(AmazonS3Client(AWSMobileClient.getInstance().credentialsProvider))
+ .build()
+
+ val txObserver = txUtil.download(remote, local)
+ txObserver.transferListener = object : TransferListener() {
+ override fun onStateChanged(id: Int, state: TransferState) {
+ if (state == TransferState.COMPLETED) {
+ // Handle a completed upload
+ }
+ }
+
+ override fun onProgressChanged(id: Int, current: Long, total: Long) {
+ val done = (((current / total) * 100.0) as Float) as Int
+ Log.d(TAG, "ID: $id, percent done = $done")
+ }
+
+ override fun onError(id: Int, ex: Exception) {
+ // Handle errors
+ }
+ }
+
+ // If you prefer to poll for the data, instead of attaching a
+ // listener, check for the state and progress in the observer.
+ if (txObserver.state == TransferState.COMPLETED) {
+ // Handle a completed upload.
+ }
+ }
+}
+```
+
+iOS - Swift
+
+The following example shows how to download a file from an Amazon S3 bucket.
+
+```swift
+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;
+ }
+}
+```
+
+## Track Transfer Progress
+
+Android - Java
+
+With the `TransferUtility`, the download() and upload() methods return a `TransferObserver` object. This object gives access to:
+
+1. The state, as an `enum`
+2. The total bytes currently transferred
+3. The total bytes remaining to transfer, to aid in calculating progress bars
+4. A unique ID that you can use to keep track of distinct transfers
+
+Given the transfer ID, the `TransferObserver` object can be retrieved from anywhere in your app, even if the app was terminated during a transfer. It also lets you create a `TransferListener`, which will be updated on state or progress change, as well as when an error occurs.
+
+To get the progress of a transfer, call `setTransferListener()` on your `TransferObserver`. This requires you to implement `onStateChanged`, `onProgressChanged`, and `onError`. For example:
+
+You can also query for `TransferObservers` with either the `getTransfersWithType(transferType)` or `getTransfersWithTypeAndState(transferType, transferState)` method. You can use `TransferObservers` to determine what transfers are underway, what are paused and handle the transfers as necessary.
+
+```java
+
+TransferObserver transferObserver = download(MY_BUCKET, OBJECT_KEY, MY_FILE);
+transferObserver.setTransferListener(new TransferListener(){
+
+ @Override
+ public void onStateChanged(int id, TransferState state) {
+ // do something
+ }
+
+ @Override
+ public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) {
+ int percentage = (int) (bytesCurrent/bytesTotal * 100);
+ //Display percentage transferred to user
+ }
+
+ @Override
+ public void onError(int id, Exception ex) {
+ // do something
+ }
+});
+```
+
+The transfer ID can be retrieved from the `TransferObserver` object that is returned from upload or download function.
+
+```java
+// Gets id of the transfer.
+int transferId = transferObserver.getId();
+```
+
+Android - Kotlin
+
+With the `TransferUtility`, the download() and upload() methods return a `TransferObserver` object. This object gives access to:
+
+1. The state, as an `enum`
+2. The total bytes currently transferred
+3. The total bytes remaining to transfer, to aid in calculating progress bars
+4. A unique ID that you can use to keep track of distinct transfers
+
+Given the transfer ID, the `TransferObserver` object can be retrieved from anywhere in your app, even if the app was terminated during a transfer. It also lets you create a `TransferListener`, which will be updated on state or progress change, as well as when an error occurs.
+
+To get the progress of a transfer, call `setTransferListener()` on your `TransferObserver`. This requires you to implement `onStateChanged`, `onProgressChanged`, and `onError`. For example:
+
+You can also query for `TransferObservers` with either the `getTransfersWithType(transferType)` or `getTransfersWithTypeAndState(transferType, transferState)` method. You can use `TransferObservers` to determine what transfers are underway, what are paused and handle the transfers as necessary.
+
+```kotlin
+val transferObserver = download(MY_BUCKET, OBJECT_KEY, MY_FILE);
+transferObserver.transferListener = object : TransferListener() {
+ override fun onStateChanged(id: Int, state: TransferState) {
+ // Do something
+ }
+
+ override fun onProgressChanged(id: int, current: Long, total: Long) {
+ int percent = ((current / total) * 100.0) as Int
+ // Display percent transferred
+ }
+
+ override fun onError(id: Int, ex: Exception) {
+ // Do something
+ }
+}
+```
+
+The transfer ID can be retrieved from the `TransferObserver` object that is returned from upload or download function.
+
+```kotlin
+// Gets id of the transfer.
+val transferId = transferObserver.id;
+```
+
+iOS - Swift
+
+Implement progress and completion actions for transfers by passing a `progressBlock` and `completionHandler` blocks to the call to `AWSS3TransferUtility` that initiates the transfer.
+
+The following example of initiating a data upload, shows how progress and completion handling is typically done for all transfers. The `AWSS3TransferUtilityUploadExpression`, `AWSS3TransferUtilityMultiPartUploadExpression` and `AWSS3TransferUtilityDownloadExpression` contains the `progressBlock` that gives you the progress of the transfer which you can use to update the progress bar.
+
+```swift
+// For example, create a progress bar
+let progressView: UIProgressView! = UIProgressView()
+progressView.progress = 0.0;
+
+let data = Data() // The data to upload
+
+let expression = AWSS3TransferUtilityUploadExpression()
+expression.progressBlock = {(task, progress) in DispatchQueue.main.async(execute: {
+ // Update a progress bar.
+ progressView.progress = Float(progress.fractionCompleted)
+ })
+}
+
+let completionHandler: AWSS3TransferUtilityUploadCompletionHandlerBlock = { (task, error) -> Void in DispatchQueue.main.async(execute: {
+ if let error = error {
+ NSLog("Failed with error: \(error)")
+ }
+ else if(self.progressView.progress != 1.0) {
+ NSLog("Error: Failed.")
+ } else {
+ NSLog("Success.")
+ }
+ })
+}
+
+var refUploadTask: AWSS3TransferUtilityTask?
+let transferUtility = AWSS3TransferUtility.default()
+transferUtility.uploadData(data,
+ bucket: "S3BucketName",
+ key: "S3UploadKeyName",
+ contentType: "text/plain",
+ expression: expression,
+ completionHandler: completionHandler).continueWith { (task) -> AnyObject! in
+ if let error = task.error {
+ print("Error: \(error.localizedDescription)")
+ }
+
+ if let uploadTask = task.result {
+ // Do something with uploadTask.
+ // The uploadTask can be used to pause/resume/cancel the operation, retrieve task specific information
+ refUploadTask = uploadTask
+ }
+
+ return nil;
+ }
+```
+
+## Pause a Transfer
+
+Android - Java
+
+Transfers can be paused using the `pause(transferId)` method. If your app is terminated, crashes, or loses Internet connectivity, transfers are automatically paused.
+
+The `transferId` can be retrieved from the `TransferObserver` object as described in :ref:`native-track-progress-and-completion-of-a-transfer`.
+
+To pause a single transfer:
+```java
+transferUtility.pause(idOfTransferToBePaused);
+```
+
+To pause all uploads:
+
+```java
+transferUtility.pauseAllWithType(TransferType.UPLOAD);
+```
+
+To pause all downloads:
+
+```java
+transferUtility.pauseAllWithType(TransferType.DOWNLOAD);
+```
+
+To pause all transfers of any type:
+
+```java
+transferUtility.pauseAllWithType(TransferType.ANY);
+```
+
+Android - Kotlin
+
+Transfers can be paused using the `pause(transferId)` method. If your app is terminated, crashes, or loses Internet connectivity, transfers are automatically paused.
+
+The `transferId` can be retrieved from the `TransferObserver` object as described in :ref:`native-track-progress-and-completion-of-a-transfer`.
+
+To pause a single transfer:
+
+```kotlin
+transferUtility.pause(idOfTransferToBePaused);
+```
+
+To pause all uploads:
+
+```kotlin
+transferUtility.pauseAllWithType(TransferType.UPLOAD);
+```
+
+To pause all downloads:
+
+```kotlin
+transferUtility.pauseAllWithType(TransferType.DOWNLOAD);
+```
+
+To pause all transfers of any type:
+
+```kotlin
+transferUtility.pauseAllWithType(TransferType.ANY);
+```
+
+iOS - Swift
+
+To pause or suspend a transfer, retain references to `AWSS3TransferUtilityUploadTask`, `AWSS3TransferUtilityMultiPartUploadTask` or `AWSS3TransferUtilityDownloadTask` .
+
+As described in the previous section :ref:`native-track-progress-and-completion-of-a-transfer`, the variable `refUploadTask` is a reference to the `UploadTask` object that is retrieved from the `continueWith` block of an upload operation that is invoked through `transferUtility.uploadData`.
+
+To pause a transfer, use the `suspend` method:
+
+```swift
+refUploadTask.suspend()
+```
+
+## Resume a Transfer
+
+Android - Java
+
+In the case of a loss in network connectivity, transfers will automatically resume when network connectivity is restored. If the app crashed or was terminated by the operating system, transfers can be resumed with the `resume(transferId)` method.
+
+The `transferId` can be retrieved from the `TransferObserver` object as described in :ref:`native-track-progress-and-completion-of-a-transfer`.
+
+To resume a single transfer:
+
+```java
+transferUtility.resume(idOfTransferToBeResumed);
+```
+To resume all uploads:
+
+```java
+transferUtility.resumeAllWithType(TransferType.UPLOAD);
+```
+
+To resume all downloads:
+
+```java
+transferUtility.resumeAllWithType(TransferType.DOWNLOAD);
+```
+
+To resume all transfers of any type:
+
+```java
+transferUtility.resumeAllWithType(TransferType.ANY);
+```
+
+Android - Kotlin
+
+In the case of a loss in network connectivity, transfers will automatically resume when network connectivity is restored. If the app crashed or was terminated by the operating system, transfers can be resumed with the `resume(transferId)` method.
+
+The `transferId` can be retrieved from the `TransferObserver` object as described in :ref:`native-track-progress-and-completion-of-a-transfer`.
+
+To resume a single transfer:
+
+```kotlin
+transferUtility.resume(idOfTransferToBeResumed);
+```
+
+To resume all uploads:
+
+```kotlin
+
+transferUtility.resumeAllWithType(TransferType.UPLOAD);
+```
+
+To resume all downloads:
+
+```kotlin
+
+transferUtility.resumeAllWithType(TransferType.DOWNLOAD);
+```
+
+To resume all transfers of any type:
+
+```kotlin
+
+transferUtility.resumeAllWithType(TransferType.ANY);
+```
+
+iOS - Swift
+
+To resume an upload or a download operation, retain references to `AWSS3TransferUtilityUploadTask`, `AWSS3TransferUtilityMultiPartUploadTask` or `AWSS3TransferUtilityDownloadTask`.
+
+As described in the previous section :ref:`native-track-progress-and-completion-of-a-transfer`, the variable `refUploadTask` is a reference to the `UploadTask` object that is retrieved from the `continueWith` block of an upload operation that is invoked through `transferUtility.uploadData`.
+
+To resume a transfer, use the `resume` method:
+
+```swift
+
+refUploadTask.resume()
+```
+
+## Cancel a Transfer
+
+Android - Java
+To cancel an upload, call cancel() or cancelAllWithType() on the `TransferUtility` object.
+
+The `transferId` can be retrieved from the `TransferObserver` object as described in :ref:`native-track-progress-and-completion-of-a-transfer`.
+
+To cancel a single transfer, use:
+
+```java
+
+transferUtility.cancel(idToBeCancelled);
+```
+
+To cancel all transfers of a certain type, use:
+
+```java
+
+transferUtility.cancelAllWithType(TransferType.DOWNLOAD);
+```
+Android - Kotlin
+
+To cancel an upload, call cancel() or cancelAllWithType() on the `TransferUtility` object.
+
+The `transferId` can be retrieved from the `TransferObserver` object as described in :ref:`native-track-progress-and-completion-of-a-transfer`.
+
+To cancel a single transfer, use:
+
+```kotlin
+
+transferUtility.cancel(idToBeCancelled);
+```
+To cancel all transfers of a certain type, use:
+
+```kotlin
+
+transferUtility.cancelAllWithType(TransferType.DOWNLOAD);
+```
+
+iOS - Swift
+
+To cancel an upload or a download operation, retain references to `AWSS3TransferUtilityUploadTask`, `AWSS3TransferUtilityMultiPartUploadTask` and `AWSS3TransferUtilityDownloadTask`.
+
+As described in the previous section :ref:`native-track-progress-and-completion-of-a-transfer`, the variable `refUploadTask` is a reference to the `UploadTask` object that is retrieved from the `continueWith` block of an upload operation that is invoked through `transferUtility.uploadData`.
+
+To cancel a transfer, use the `cancel` method:
+
+```swift
+
+refUploadTask.cancel()
+```
+
+## Background Transfers
+
+The SDK supports uploading to and downloading from Amazon S3 while your app is running in the background.
+
+Android - Java
+No additional work is needed to use this feature. As long as your app is present in the background a transfer that is in progress will continue.
+
+Android - Kotlin
+No additional work is needed to use this feature. As long as your app is present in the background a transfer that is in progress will continue.
+
+iOS - Swift
+**Configure the Application Delegate**
+
+The `TransferUtility` for iOS uses NSURLSession background transfers to continue data transfers even when your app moves to the background. Call the following method in the `- application:handleEventsForBackgroundURLSession: completionHandler:` of your application delegate.
+When the app moves the foreground, the delegate enables iOS to notify TransferUtility that a transfer has completed.
+
+```swift
+
+func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {
+ // Store the completion handler.
+ AWSS3TransferUtility.interceptApplication(application, handleEventsForBackgroundURLSession: identifier, completionHandler: completionHandler)
+}
+```
+
+**Manage a Transfer with the App in the Foreground**
+
+To manage transfers for an app that has moved from the background to the foreground, retain references to `AWSS3TransferUtilityUploadTask`, `AWSS3TransferUtilityMultiPartUploadTask` and `AWSS3TransferUtilityDownloadTask`. Call suspend, resume, or cancel methods on those task references. The following example shows how to suspend a transfer when the app is about to be terminated.
+
+```swift
+transferUtility.uploadFile(fileURL,
+ bucket: S3BucketName,
+ key: S3UploadKeyName,
+ contentType: "image/png",
+ expression: nil,
+ completionHandler: nil).continueWith {
+ (task) -> AnyObject! in if let error = task.error {
+ print("Error: \(error.localizedDescription)")
+ }
+
+ if let uploadTask = task.result {
+ uploadTask.suspend()
+ }
+
+ return nil;
+ }
+```
+
+**Manage a Transfer when a Suspended App Returns to the Foreground**
+
+When an app that has initiated a transfer becomes suspended and then returns to the foreground, the transfer may still be in progress or may have completed. In both cases, use the following code to reestablish the progress and completion handler blocks of the app.
+
+This code example is for downloading a file but the same pattern can be used for upload:
+
+You can get a reference to the `AWSS3TransferUtilityUploadTask`, `AWSS3TransferUtilityMultiPartUploadTask` and `AWSS3TransferUtilityDownloadTask` objects from the task.result in continueWith block when you initiate the upload and download respectively. These tasks have a property called taskIdentifier, which uniquely identifies the transfer task object within the `AWSS3TransferUtility`. Your app should persist the identifier through closure and relaunch, so that you can uniquely identify the task objects when the app comes back into the foreground.
+
+```swift
+
+let transferUtility = AWSS3TransferUtility.default()
+
+var uploadProgressBlock: AWSS3TransferUtilityProgressBlock? = {(task: AWSS3TransferUtilityTask, progress: Progress) in
+ DispatchQueue.main.async {
+ // Handle progress feedback, e.g. update progress bar
+ }
+}
+
+
+var downloadProgressBlock: AWSS3TransferUtilityProgressBlock? = {
+ (task: AWSS3TransferUtilityTask, progress: Progress) in DispatchQueue.main.async {
+ // Handle progress feedback, e.g. update progress bar
+ }
+}
+var completionBlockUpload:AWSS3TransferUtilityUploadCompletionHandlerBlock? = {
+ (task, error) in DispatchQueue.main.async {
+ // perform some action on completed upload operation
+ }
+}
+var completionBlockDownload:AWSS3TransferUtilityDownloadCompletionHandlerBlock? = {
+ (task, url, data, error) in DispatchQueue.main.async {
+ // perform some action on completed download operation
+ }
+}
+
+
+
+transferUtility.enumerateToAssignBlocks(forUploadTask: {
+ (task, progress, completion) -> Void in
+
+ let progressPointer = AutoreleasingUnsafeMutablePointer(& uploadProgressBlock)
+
+ let completionPointer = AutoreleasingUnsafeMutablePointer(&completionBlockUpload)
+
+ // Reassign your progress feedback
+ progress?.pointee = progressPointer.pointee
+
+ // Reassign your completion handler.
+ completion?.pointee = completionPointer.pointee
+
+}, downloadTask: {
+ (task, progress, completion) -> Void in
+
+ let progressPointer = AutoreleasingUnsafeMutablePointer(&downloadProgressBlock)
+
+ let completionPointer = AutoreleasingUnsafeMutablePointer(&completionBlockDownload)
+
+ // Reassign your progress feedback
+ progress?.pointee = progressPointer.pointee
+
+ // Reassign your completion handler.
+ completion?.pointee = completionPointer.pointee
+})
+
+ if let downloadTask = task.result {
+ // Do something with downloadTask.
+}
+```
+
+## Advanced Transfer Methods
+
+### Transfer with Object Metadata
+
+Android - Java
+
+To upload a file with metadata, use the `ObjectMetadata` object. Create a `ObjectMetadata` object and add in the metadata headers and pass it to the upload function.
+
+```java
+
+import com.amazonaws.services.s3.model.ObjectMetadata;
+
+ObjectMetadata myObjectMetadata = new ObjectMetadata();
+
+//create a map to store user metadata
+Map userMetadata = new HashMap();
+userMetadata.put("myKey","myVal");
+
+//call setUserMetadata on our ObjectMetadata object, passing it our map
+myObjectMetadata.setUserMetadata(userMetadata);
+```
+
+Then, upload an object along with its metadata:
+
+```java
+
+TransferObserver observer = transferUtility.upload(
+ MY_BUCKET, /* The bucket to upload to */
+ OBJECT_KEY, /* The key for the uploaded object */
+ MY_FILE, /* The file where the data to upload exists */
+ myObjectMetadata /* The ObjectMetadata associated with the object*/
+);
+```
+
+To download the meta, use the S3 `getObjectMetadata` method. For more information, see the [API Reference] (http://docs.aws.amazon.com/AWSAndroidSDK/latest/javadoc/com/amazonaws/services/s3/AmazonS3Client.html#getObjectMetadata%28com.amazonaws.services.s3.model.GetObjectMetadataRequest%29).
+
+Android - Kotlin
+
+To upload a file with metadata, use the `ObjectMetadata` object. Create a `ObjectMetadata` object and add in the metadata headers and pass it to the upload function.
+
+```kotlin
+
+import com.amazonaws.services.s3.model.ObjectMetadata;
+
+val myObjectMetadata = new ObjectMetadata()
+myObjectMetadata.userMetadata = mapOf("myKey" to "myVal")
+```
+
+Then, upload an object along with its metadata:
+
+```kotlin
+
+val observer = transferUtility.upload(
+ MY_BUCKET, /* The bucket to upload to */
+ OBJECT_KEY, /* The key for the uploaded object */
+ MY_FILE, /* The file where the data to upload exists */
+ myObjectMetadata /* The ObjectMetadata associated with the object*/
+)
+```
+
+To download the meta, use the S3 `getObjectMetadata` method. For more information, see the [API Reference] (http://docs.aws.amazon.com/AWSAndroidSDK/latest/javadoc/com/amazonaws/services/s3/AmazonS3Client.html#getObjectMetadata%28com.amazonaws.services.s3.model.GetObjectMetadataRequest%29).
+
+iOS - Swift
+
+`AWSS3TransferUtilityUploadExpression` and `AWSS3TransferUtilityMultiPartUploadExpression` contain the method `setValue:forRequestHeader` where you can pass in metadata to Amazon S3. This example demonstrates passing in the Server-side Encryption Algorithm as a request header in uploading data to S3 using MultiPart.
+
+```swift
+
+let data: Data = Data() // The data to upload
+
+let uploadExpression = AWSS3TransferUtilityMultiPartUploadExpression()
+uploadExpression.setValue("AES256", forRequestHeader: "x-amz-server-side-encryption-customer-algorithm")
+uploadExpression.progressBlock = {(task, progress) in DispatchQueue.main.async(execute: {
+ // Do something e.g. Update a progress bar.
+ })
+}
+
+let transferUtility = AWSS3TransferUtility.default()
+
+transferUtility.uploadUsingMultiPart(data:data,
+ bucket: "S3BucketName",
+ key: "S3UploadKeyName",
+ contentType: "text/plain",
+ expression: uploadExpression,
+ completionHandler: nil).continueWith { (task) -> AnyObject! in
+ if let error = task.error {
+ print("Error: \(error.localizedDescription)")
+ }
+
+ return nil;
+ }
+```
+
+### Transfer with Access Control List
+
+Android - Java
+
+To upload a file with Access Control List, use the `CannedAccessControlList` object. The [CannedAccessControlList] (http://docs.aws.amazon.com/AWSAndroidSDK/latest/javadoc/com/amazonaws/services/s3/model/CannedAccessControlList.html) specifies the constants defining a canned access control list. For example, if you use [CannedAccessControlList.PublicRead] (http://docs.aws.amazon.com/AWSAndroidSDK/latest/javadoc/com/amazonaws/services/s3/model/CannedAccessControlList.html#PublicRead) , this specifies the owner is granted `Permission.FullControl` and the `GroupGrantee.AllUsers` group grantee is granted Permission.Read access.
+
+Then, upload an object along with its ACL:
+
+```java
+
+TransferObserver observer = transferUtility.upload(
+ MY_BUCKET, /* The bucket to upload to */
+ OBJECT_KEY, /* The key for the uploaded object */
+ MY_FILE, /* The file where the data to upload exists */
+ CannedAccessControlList.PublicRead /* Specify PublicRead ACL for the object in the bucket. */
+);
+```
+
+Android - Kotlin
+
+To upload a file with Access Control List, use the `CannedAccessControlList` object. The [CannedAccessControlList] (http://docs.aws.amazon.com/AWSAndroidSDK/latest/javadoc/com/amazonaws/services/s3/model/CannedAccessControlList.html) specifies the constants defining a canned access control list. For example, if you use [CannedAccessControlList.PublicRead] (http://docs.aws.amazon.com/AWSAndroidSDK/latest/javadoc/com/amazonaws/services/s3/model/CannedAccessControlList.html#PublicRead) , this specifies the owner is granted `Permission.FullControl` and the `GroupGrantee.AllUsers` group grantee is granted Permission.Read access.
+
+Then, upload an object along with its ACL:
+
+```kotlin
+
+val observer = transferUtility.upload(
+ MY_BUCKET, /* The bucket to upload to */
+ OBJECT_KEY, /* The key for the uploaded object */
+ MY_FILE, /* The file where the data to upload exists */
+ CannedAccessControlList.PublicRead /* Specify PublicRead ACL for the object in the bucket. */
+)
+```
+
+iOS - Swift
+
+To upload a file and specify permissions for it, you can use predefined grants, also known as canned ACLs. The following code shows you how to setup a file with publicRead access using the AWSS3 client.
+
+
+```swift
+//Create a AWSS3PutObjectRequest object and setup the content, bucketname, key on it.
+//use the .acl method to specify the ACL for the file
+let s3: AWSS3 = AWSS3.default()
+
+let putObjectRequest: AWSS3PutObjectRequest! = AWSS3PutObjectRequest()
+let content = "testObjectData"
+putObjectRequest.acl = AWSS3ObjectCannedACL.publicRead
+putObjectRequest.bucket = "bucket name"
+putObjectRequest.key = "file name"
+putObjectRequest.body = content
+putObjectRequest.contentLength = content.count as NSNumber
+putObjectRequest.contentType = "text/plain";
+
+s3.putObject(putObjectRequest, completionHandler: { (putObjectOutput:AWSS3PutObjectOutput? , error: Error? ) in
+ if let output = putObjectOutput {
+ print (output)
+ }
+
+ if let error = error {
+ print (error)
+ }
+})
+```
+
+### Transfer Utility Options
+
+Android - Java
+You can use the `TransferUtilityOptions` object to customize the operations of the `TransferUtility`.
+
+**TransferThreadPoolSize**
+This parameter will let you specify the number of threads in the thread pool for transfers. By increasing the number of threads, you will be able to increase the number of parts of a multi-part upload that will be uploaded in parallel. By default, this is set to 2 * (N + 1), where N is the number of available processors on the mobile device. The minimum allowed value is 2.
+
+```java
+TransferUtilityOptions options = new TransferUtilityOptions();
+options.setTransferThreadPoolSize(8);
+
+TransferUtility transferUtility = TransferUtility.builder()
+ // Pass-in S3Client, Context, AWSConfiguration/DefaultBucket Name
+ .transferUtilityOptions(options)
+ .build();
+```
+
+**TransferServiceCheckTimeInterval**
+The `TransferUtility` monitors each on-going transfer by checking its status periodically. If a stalled transfer is detected, it will be automatically resumed by the `TransferUtility`. The TransferServiceCheckTimeInterval option allows you to set the time interval
+between the status checks. It is specified in milliseconds and set to 60,000 by default.
+
+```java
+TransferUtilityOptions options = new TransferUtilityOptions();
+options.setTransferServiceCheckTimeInterval(2 * 60 * 1000); // 2-minutes
+
+TransferUtility transferUtility = TransferUtility.builder()
+ // Pass-in S3Client, Context, AWSConfiguration/DefaultBucket Name
+ .transferUtilityOptions(options)
+ .build();
+```
+
+Android - Kotlin
+You can use the `TransferUtilityOptions` object to customize the operations of the `TransferUtility`.
+
+**TransferThreadPoolSize**
+This parameter will let you specify the number of threads in the thread pool for transfers. By increasing the number of threads, you will be able to increase the number of parts of a multi-part upload that will be uploaded in parallel. By default, this is set to 2 * (N + 1), where N is the number of available processors on the mobile device. The minimum allowed value is 2.
+
+```kotlin
+
+val options = new TransferUtilityOptions().apply {
+ transferThreadPoolSize = 8
+}
+
+val transferUtility = TransferUtility.builder()
+ // Pass-in S3Client, Context, AWSConfiguration/DefaultBucket Name
+ .transferUtilityOptions(options)
+ .build()
+```
+
+**TransferServiceCheckTimeInterval**
+The `TransferUtility` monitors each on-going transfer by checking its status periodically. If a stalled transfer is detected, it will be automatically resumed by the `TransferUtility`. The TransferServiceCheckTimeInterval option allows you to set the time interval
+between the status checks. It is specified in milliseconds and set to 60,000 by default.
+
+```kotlin
+
+val options = new TransferUtilityOptions().apply {
+ transferServiceCheckTimeInterval = 2 * 60 * 1000 // 2-minutes
+}
+
+val transferUtility = TransferUtility.builder()
+ // Pass-in S3Client, Context, AWSConfiguration/DefaultBucket Name
+ .transferUtilityOptions(options)
+ .build()
+```
+
+iOS - Swift
+You can use the `AWSS3TransferUtilityConfiguration` object to configure the operations of the `TransferUtility`.
+
+**isAccelerateModeEnabled**
+The isAccelerateModeEnabled option lets you to upload and download content from a bucket that has Transfer Acceleration enabled on it. See https://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html for information on how to enable transfer acceleration for your bucket.
+
+This option is set to false by default.
+
+```swift
+//Setup credentials
+let credentialProvider = AWSCognitoCredentialsProvider(regionType: YOUR-IDENTITY-POOL-REGION, identityPoolId: "YOUR-IDENTITY-POOL-ID")
+
+//Setup the service configuration
+let configuration = AWSServiceConfiguration(region: .USEast1, credentialsProvider: credentialProvider)
+
+//Setup the transfer utility configuration
+let tuConf = AWSS3TransferUtilityConfiguration()
+tuConf.isAccelerateModeEnabled = true
+
+
+//Register a transfer utility object
+AWSS3TransferUtility.register(
+ with: configuration!,
+ transferUtilityConfiguration: tuConf,
+ forKey: "transfer-utility-with-advanced-options"
+)
+```
+
+//Look up the transfer utility object from the registry to use for your transfers.
+let transferUtility = AWSS3TransferUtility.s3TransferUtility(forKey: "transfer-utility-with-advanced-options")
+
+* `YOUR-IDENTITY-POOL-REGION` should be in the form of `.USEast1`
+
+* `YOUR-IDENTITY-POOL-ID` should be in the form of `us-east-1:01234567-yyyy-0123-xxxx-012345678901`
+
+**retryLimit**
+The retryLimit option allows you to specify the number of times the TransferUtility will retry a transfer when it encounters an error during the transfer. By default, it is set to 0, which means that there will be no retries.
+
+```swift
+
+tuConf.retryLimit = 5
+```
+
+**multiPartConcurrencyLimit**
+The multiPartConcurrencyLimit option allows you to specify the number of parts that will be uploaded in parallel for a MultiPart upload request. By default, this is set to 5.
+
+```swift
+
+tuConf.multiPartConcurrencyLimit = 3
+```
+
+## More Transfer Examples
+
+This section provides descriptions and abbreviated examples of the aspects of each type of transfer that are unique. For information about typical code surrounding the following snippets see `native-track-progress-and-completion-of-a-transfer`.
+
+### Downloading to a File
+
+The following code shows how to download an Amazon S3 Object to a local file.
+
+Android - Java
+
+```java
+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 download.
+ }
+ }
+
+ @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
+ }
+
+});
+```
+
+Android - Kotlin
+
+```kotlin
+val observer = transferUtility.download(
+ "s3Folder/s3Key.txt",
+ new File("/path/to/file/localFile.txt"))
+observer.transferListener = object : TransferListener() {
+ override fun onStateChanged(id: int, state: TransferState) {
+ if (state == TransferState.COMPLETED) {
+ // Handle a completed download
+ }
+ }
+
+ override fun onProgressChanged(id: Int, current: Long, total: Long) {
+ val done = ((current / total) * 100.0) as Int
+ // Do something
+ }
+
+ override fun onError(id: Int, ex: Exception) {
+ // Do something
+ }
+}
+```
+
+iOS - Swift
+
+```swift
+let fileURL = // The file URL of the download destination.
+
+let transferUtility = AWSS3TransferUtility.default()
+transferUtility.download(
+ to: fileURL
+ bucket: S3BucketName,
+ key: S3DownloadKeyName,
+ 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;
+ }
+```
+
+### Uploading Binary Data to a File
+
+Android - Java
+Use the following code to upload binary data to a file in Amazon S3.
+
+```java
+TransferObserver uploadObserver =
+ transferUtility.upload(
+ "s3Folder/s3Key.bin",
+ new File("/path/to/file/localFile.bin"));
+
+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
+ }
+
+});
+```
+
+Android - Kotlin
+Use the following code to upload binary data to a file in Amazon S3.
+
+```kotlin
+val observer = transferUtility.upload(
+ "s3Folder/s3Key.bin",
+ new File("/path/to/file/localFile.bin"))
+observer.transferListener = object : TransferListener() {
+ override fun onStateChanged(id: int, state: TransferState) {
+ if (state == TransferState.COMPLETED) {
+ // Handle a completed download
+ }
+ }
+
+ override fun onProgressChanged(id: Int, current: Long, total: Long) {
+ val done = ((current / total) * 100.0) as Int
+ // Do something
+ }
+
+ override fun onError(id: Int, ex: Exception) {
+ // Do something
+ }
+}
+```
+
+iOS - Swift
+To upload a binary data to a file, you have to make sure to set the appropriate content type in the uploadData method of the TransferUtility. In the example below, we are uploading a PNG image to S3.
+
+```swift
+
+let data: Data = Data() // The data to upload
+
+let transferUtility = AWSS3TransferUtility.default()
+transferUtility.uploadData(data,
+ bucket: S3BucketName,
+ key: S3UploadKeyName,
+ contentType: "image/png",
+ 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;
+ }
+```
+
+### Downloading Binary Data to a File
+
+The following code shows how to download a binary file.
+
+Android - Java
+```java
+
+TransferObserver downloadObserver =
+ transferUtility.download(
+ "s3Folder/s3Key.bin",
+ new File("/path/to/file/localFile.bin"));
+
+downloadObserver.setTransferListener(new TransferListener() {
+
+ @Override
+ public void onStateChanged(int id, TransferState state) {
+ if (TransferState.COMPLETED == state) {
+ // Handle a completed download.
+ }
+ }
+ @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
+ }
+
+});
+```
+
+Android - Kotlin
+```kotlin
+
+val observer = transferUtility.download(
+ "s3Folder/s3Key.bin",
+ new File("/path/to/file/localFile.bin"))
+observer.transferListener = object : TransferListener() {
+ override fun onStateChanged(id: int, state: TransferState) {
+ if (state == TransferState.COMPLETED) {
+ // Handle a completed download
+ }
+ }
+
+ override fun onProgressChanged(id: Int, current: Long, total: Long) {
+ val done = ((current / total) * 100.0) as Int
+ // Do something
+ }
+
+ override fun onError(id: Int, ex: Exception) {
+ // Do something
+ }
+}
+```
+iOS - Swift
+```swift
+
+let fileURL = // The file URL of the download destination
+let transferUtility = AWSS3TransferUtility.default()
+transferUtility.downloadData(
+ fromBucket: S3BucketName,
+ key: S3DownloadKeyName,
+ 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;
+ }
+```
+
+## Limitations
+
+Android - Java
+
+If you expect your app to perform transfers that take longer than 50 minutes, use `AmazonS3Client (http://docs.aws.amazon.com/AWSAndroidSDK/latest/javadoc/com/amazonaws/services/s3/AmazonS3Client.html) instead of `TransferUtility (http://docs.aws.amazon.com/AWSAndroidSDK/latest/javadoc/com/amazonaws/mobileconnectors/s3/transferutility/TransferUtility.html).
+
+`TransferUtility` generates Amazon S3 pre-signed URLs to use for background data transfer. Using |COG| Identity, you receive AWS temporary credentials. The credentials are valid for up to 60 minutes. Generated Amazon S3 pre-signed URLs cannot last longer than that time. Because of this limitation, the Amazon S3 Transfer Utility enforces 50 minute transfer timeouts, leaving a 10 minute buffer before AWS temporary credentials are regenerated. After **50 minutes**, you receive a transfer failure.
+
+Android - Kotlin
+
+If you expect your app to perform transfers that take longer than 50 minutes, use `AmazonS3Client (http://docs.aws.amazon.com/AWSAndroidSDK/latest/javadoc/com/amazonaws/services/s3/AmazonS3Client.html) instead of `TransferUtility (http://docs.aws.amazon.com/AWSAndroidSDK/latest/javadoc/com/amazonaws/mobileconnectors/s3/transferutility/TransferUtility.html).
+
+`TransferUtility` generates Amazon S3 pre-signed URLs to use for background data transfer. Using |COG| Identity, you receive AWS temporary credentials. The credentials are valid for up to 60 minutes. Generated Amazon S3 pre-signed URLs cannot last longer than that time. Because of this limitation, the Amazon S3 Transfer Utility enforces 50 minute transfer timeouts, leaving a 10 minute buffer before AWS temporary credentials are regenerated. After **50 minutes**, you receive a transfer failure.
+
+iOS - Swift
+
+If you expect your app to perform transfers that take longer than 50 minutes, use `AWSS3 (https://docs.aws.amazon.com/AWSiOSSDK/latest/Classes/AWSS3.html) instead of `AWSS3TransferUtility (https://docs.aws.amazon.com/AWSiOSSDK/latest/Classes/AWSS3TransferUtility.html).
+
+`AWSS3TransferUtility` generates Amazon S3 pre-signed URLs to use for background data transfer. Using Amazon Cognito Identity, you receive AWS temporary credentials. The credentials are valid for up to 60 minutes. At the same time, generated S3 pre-signed URLs cannot last longer than that time. Because of this limitation, the AWSS3TransferUtility enforces **50 minutes** transfer timeout, leaving a 10 minute buffer before AWS temporary credentials are regenerated. After 50 minutes, you receive a transfer failure.
diff --git a/ios/media/add-aws-mobile-sdk-android-studio-res-raw.png b/ios/media/add-aws-mobile-sdk-android-studio-res-raw.png
new file mode 100755
index 00000000000..d2975edaf65
Binary files /dev/null and b/ios/media/add-aws-mobile-sdk-android-studio-res-raw.png differ
diff --git a/ios/media/conversational-bots-voice-ui.png b/ios/media/conversational-bots-voice-ui.png
new file mode 100755
index 00000000000..4e44555238d
Binary files /dev/null and b/ios/media/conversational-bots-voice-ui.png differ
diff --git a/ios/media/facebook-app-id-console-entry.png b/ios/media/facebook-app-id-console-entry.png
new file mode 100755
index 00000000000..43b30109c57
Binary files /dev/null and b/ios/media/facebook-app-id-console-entry.png differ
diff --git a/ios/media/getting-started-analytics.png b/ios/media/getting-started-analytics.png
new file mode 100755
index 00000000000..5c98bf6cb01
Binary files /dev/null and b/ios/media/getting-started-analytics.png differ
diff --git a/ios/media/new-facebook-add-platform-ios.png b/ios/media/new-facebook-add-platform-ios.png
new file mode 100755
index 00000000000..b56dd6a7c08
Binary files /dev/null and b/ios/media/new-facebook-add-platform-ios.png differ
diff --git a/ios/media/new-facebook-add-platform.png b/ios/media/new-facebook-add-platform.png
new file mode 100755
index 00000000000..cdcc6f326dd
Binary files /dev/null and b/ios/media/new-facebook-add-platform.png differ
diff --git a/ios/media/new-facebook-add-testers.png b/ios/media/new-facebook-add-testers.png
new file mode 100755
index 00000000000..8abf88e23eb
Binary files /dev/null and b/ios/media/new-facebook-add-testers.png differ
diff --git a/ios/media/new-facebook-app-id.png b/ios/media/new-facebook-app-id.png
new file mode 100755
index 00000000000..67c5ad7149a
Binary files /dev/null and b/ios/media/new-facebook-app-id.png differ
diff --git a/ios/media/new-facebook-app-new-app-id.png b/ios/media/new-facebook-app-new-app-id.png
new file mode 100755
index 00000000000..b95f1829640
Binary files /dev/null and b/ios/media/new-facebook-app-new-app-id.png differ
diff --git a/ios/media/new-facebook-app.png b/ios/media/new-facebook-app.png
new file mode 100755
index 00000000000..53e29bf2f57
Binary files /dev/null and b/ios/media/new-facebook-app.png differ
diff --git a/ios/media/ss1.png b/ios/media/ss1.png
new file mode 100755
index 00000000000..7b1b00fd5a5
Binary files /dev/null and b/ios/media/ss1.png differ
diff --git a/ios/new-facebook-add-testers.png b/ios/new-facebook-add-testers.png
new file mode 100755
index 00000000000..8abf88e23eb
Binary files /dev/null and b/ios/new-facebook-add-testers.png differ
diff --git a/ios/push-notifications.md b/ios/push-notifications.md
new file mode 100755
index 00000000000..c8e15fc92db
--- /dev/null
+++ b/ios/push-notifications.md
@@ -0,0 +1,187 @@
+# Add Push Notifications to Your Mobile App with Amazon Pinpoint
+
+## Overview
+
+Enable your users to receive mobile push messages sent from the Apple (APNs) and Google (FCM/GCM) platforms. The CLI deploys your push notification backend using [Amazon Pinpoint](http://docs.aws.amazon.com/pinpoint/latest/developerguide/).
+You can also create Amazon Pinpoint campaigns that tie user behavior to push or other forms of messaging.
+
+## Set Up Your Backend
+
+1. Complete the [Get Started](./getting-started) steps before you proceed.
+
+2. Use the CLI to add storage to your cloud-enabled backend and app.
+
+ In a terminal window, navigate to your project folder (the folder that typically contains your project level `xcodeproj` file), and add the SDK to your app.
+
+ ```bash
+ $ cd ./YOUR_PROJECT_FOLDER
+ $ amplify add notifications
+ ```
+
+3. Set up your backend to support receiving push notifications:
+
+ - Choose Apple Push Notification Service (APNs).
+
+ ```
+ > APNS
+ ```
+
+ - Choose Certificate as your authentication method.
+
+ ```
+ > Certificate
+ ```
+
+ - Provide the path to your P12 certificate. For information on creating your APNs certificate, see [Setting Up iOS Push Notifications](http://docs.aws.amazon.com/pinpoint/latest/developerguide/apns-setup.html).
+
+ Use the steps in the next section to connect your app to your backend.
+
+
+## Connect to Your Backend
+
+Use the following steps to connect add push notification backend services to your app.
+
+1. `Podfile` that you configure to install the AWS Mobile SDK must contain:
+
+ ```ruby
+ platform :ios, '9.0'
+
+ target :'YOUR-APP-NAME' do
+ use_frameworks!
+
+ pod 'AWSPinpoint', '~> 2.6.13'
+ # other pods
+
+ end
+ ```
+
+ Run `pod install --repo-update` before you continue.
+
+ If you encounter an error message that begins `[!] Failed to connect to GitHub to update the CocoaPods/Specs . . .`, and your internet connectivity is working, you may need to [update openssl and Ruby](https://stackoverflow.com/questions/38993527/cocoapods-failed-to-connect-to-github-to-update-the-cocoapods-specs-specs-repo/48962041#48962041).
+
+2. Classes that call Amazon Pinpoint APIs must use the following import statements:
+
+ ```
+ import AWSCore
+ import AWSPinpoint
+ ```
+
+3. Create an Amazon Pinpoint client by using the following code into the
+ `didFinishLaunchwithOptions` method of your app's `AppDelegate.swift`. This
+ will also register your device token with Amazon Pinpoint.
+
+ Note: If you have already integrated `Analytics`, you can skip this step.
+
+ ```swift
+ /** start code copy **/
+ var pinpoint: AWSPinpoint?
+ /** end code copy **/
+
+
+ func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions:
+ [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
+
+ /** start code copy **/
+ pinpoint = AWSPinpoint(configuration:
+ AWSPinpointConfiguration.defaultPinpointConfiguration(launchOptions: launchOptions))
+ /** end code copy **/
+
+ return true
+ }
+ ```
+
+## Add Amazon Pinpoint Targeted and Campaign Push Messaging
+
+The [Amazon Pinpoint console](https://console.aws.amazon.com/pinpoint/) enables you to target your app users with push messaging. You can send individual messages or configure campaigns that target a group of users that match a profile that you define.
+For instance, you could email users that have not used the app in 30 days, or send an SMS to those that frequently use a given feature of your app.
+
+The following steps show how to receive push notifications targeted for your app.
+
+1. In your `AppDelegate` with `PinpointManager` instantiated, make sure the push
+ listening code exists in the following functions.
+
+ ```swift
+
+ // . . . other app delegate methods
+
+ func application(
+ _ application: UIApplication,
+ didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
+
+ pinpoint!.notificationManager.interceptDidRegisterForRemoteNotifications(
+ withDeviceToken: deviceToken)
+ }
+
+ func application(
+ _ application: UIApplication,
+ didReceiveRemoteNotification userInfo: [AnyHashable: Any],
+ fetchCompletionHandler completionHandler:
+ @escaping (UIBackgroundFetchResult) -> Void) {
+
+ pinpoint!.notificationManager.interceptDidReceiveRemoteNotification(
+ userInfo, fetchCompletionHandler: completionHandler)
+
+ if (application.applicationState == .active) {
+ let alert = UIAlertController(title: "Notification Received",
+ message: userInfo.description,
+ preferredStyle: .alert)
+ alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil))
+
+ UIApplication.shared.keyWindow?.rootViewController?.present(
+ alert, animated: true, completion:nil)
+ }
+ }
+
+ // . . . other app delegate methods
+ }
+ ```
+
+> If you already have push notification delegate methods, you can just add the `interceptDidRegisterForRemoteNotifications` and `interceptDidReceiveRemoteNotification` callbacks to Pinpoint client.
+
+2. Add the following code in the `ViewController` where you want to request notification permissions. Adding this code will prompt the end user to give permissions for receiving push notifications.
+
+```swift
+
+ var userNotificationTypes : UIUserNotificationType
+ userNotificationTypes = [.alert , .badge , .sound]
+ let notificationSettings = UIUserNotificationSettings.init(types: userNotificationTypes, categories: nil)
+ UIApplication.shared.registerUserNotificationSettings(notificationSettings)
+ UIApplication.shared.registerForRemoteNotifications()
+```
+
+3. In Xcode Project Navigator, choose your app name at the top, choose your app name under `Targets`, choose the `Capabilities` tab, and then turn on `Push Notifications`.
+
+ 
+
+4. Configure the app to run in the `Release` profile instead of the default `Debug` profile. Perform the following steps to get a notification to the device:
+
+ 1. For your app target, go to the `General` tab of project configuration and make sure `Automatically Manage Signing` check box is not selected.
+
+ 2. In the `Signing(Release)` section, choose the production provisioning profile you created on Apple developer console. For testing push notifications on a device, you will need an `Ad Hoc Provisioining Profile `__ configured with a Production AppStore and Ad Hoc certificate, and with the device(s) to be used for testing.
+
+ 3. In the top left corner of Xcode (where your app name is displayed next to the current build target device), choose on your app name and then select `Edit Scheme`, and then set `Build configuration` to `Release`
+
+ Run your app on an iPhone device to test. Push notifications are not supported on simulators.
+
+ 4. Xcode will give an error that it could not run the app, this is due to production profile apps not being allowed to debug. Click `Ok` and launch the app directly from the device.
+
+ 5. When prompted, chose to allow notifications for the device.
+
+ 6. To create a new campaign to send notifications to your app from the Amazon Pinpoint console run the following command from your app project folder.
+
+ ```bash
+ $ cd YOUR_APP_PROJECT_FOLDER
+ $ amplify notifications console
+ ```
+
+ 7. Provide a campaign name, choose `Next`, choose `Filter by standard attributes`, and then choose iOS as the platform.
+
+ 8. You should see 1 device as a targeted endpoint, which is the app we are running on the iPhone device. Choose the option and then choose `Next Step`.
+
+ 9. Provide text for a sample title and body for push notification, and then choose `Next Step`.
+
+ 10. Choose `Immediate`, and then choose `Next Step`.
+
+ 11. Review the details on the screen, and then choose `Launch Campaign`.
+
+ 12. A notification should appear on the iPhone device. You may want to try testing your app receiving notifications when it is in the foreground and when closed.
diff --git a/ios/storage.md b/ios/storage.md
new file mode 100755
index 00000000000..e60e7b18be7
--- /dev/null
+++ b/ios/storage.md
@@ -0,0 +1,173 @@
+# Add User File 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. The CLI deploys and configures cloud storage buckets using [Amazon Simple Storage Service](http://docs.aws.amazon.com/AmazonS3/latest/dev/).
+
+## Storage Access
+
+The CLI configures three different access levels on the storage bucket; public, protected and private.
+
+- Files with public access level can be accessed by all users who are using your app. In S3, they are stored under the ``public/`` path in your S3 bucket.
+
+- Files with protected access level are readable by all users but writable only by the creating user. In S3, they are stored under ``protected/{user_identity_id}/`` where the user_identity_id corresponds to a unique Amazon Cognito Identity ID for that user.
+
+- Files with private access level are only accessible for specific authenticated users only. In S3, they are stored under ``private/{user_identity_id}/`` where the user_identity_id corresponds to a unique Amazon Cognito Identity ID for that user.
+
+## Set Up Your Backend
+
+1. Complete the [Get Started](./getting-started) steps before you proceed.
+
+2. Use the CLI to add storage to your cloud-enabled backend and app.
+
+ In a terminal window, navigate to your project folder (the folder that typically contains your project level build.gradle), and add the SDK to your app.
+
+ ```bash
+ $ cd ./YOUR_PROJECT_FOLDER
+ $ amplify add storage
+ ```
+
+ In a terminal window, navigate to your project folder (the folder that contains your app `.xcodeproj` file), and add the SDK to your app.
+
+ ```bash
+ $ cd ./YOUR_PROJECT_FOLDER
+ $ amplify add storage
+ ```
+
+3. Choose `Content` as your storage service.
+
+ `❯ Content (Images, audio, video, etc.)`
+
+4. The CLI walks you through the options to enable Auth (if not enabled previously), to name your S3 bucket, and to decide who should have access (select `Auth and guest users` and `read/write` for both auth and guest users).
+
+5. Confirm that you have storage and auth set up.
+
+ ```bash
+ $ amplify status
+ | Category | Resource name | Operation | Provider plugin |
+ | --------- | --------------- | --------- | ----------------- |
+ | Auth | cognito2e202b09 | Create | awscloudformation |
+ | Storage | sabc0123de | Create | awscloudformation |
+ ```
+6. To create your backend run:
+
+ ```bash
+ $ amplify push
+ ```
+
+ The CLI will create the awsconfiguration.json file in your project's `res/raw` directory.
+
+iOS - Swift
+ ```bash
+ $ amplify push
+ ```
+
+ The CLI will create the awsconfiguration.json file in your project directory. Add it to your project using XCode.
+
+## Connect to Your Backend
+
+Use the following steps to connect add file storage backend services to your app.
+
+1. Add the following to :file:`Podfile` that you configure to install the AWS Mobile SDK:
+
+ ```ruby
+ platform :ios, '9.0'
+
+ target :'YOUR-APP-NAME' do
+ use_frameworks!
+
+ pod 'AWSS3', '~> 2.6.13' # For file transfers
+ pod 'AWSMobileClient', '~> 2.6.13'
+ pod 'AWSUserPoolsSignIn', '~> 2.6.13'
+
+ # other pods . . .
+
+ end
+ ```
+ Run `pod install --repo-update` before you continue.
+
+2. Add the following import to the classes that perform user file storage operations:
+
+ ```swift
+ import AWSS3
+ ```
+
+## Upload a File
+
+The following example shows how to upload data to an |S3| bucket.
+
+```swift
+
+ func uploadData() {
+
+ let data: Data = "TestData".data(using: .utf8) // Data to be uploaded
+
+ //Create an expression object for progress tracking, to pass in request headers etc.
+ let expression = AWSS3TransferUtilityUploadExpression()
+ expression.progressBlock = {(task, progress) in
+ // Do something e.g. Update a progress bar.
+ }
+
+ //Create a completion handler to be called when the transfer completes
+ var completionHandler: AWSS3TransferUtilityUploadCompletionHandlerBlock?
+ completionHandler = { (task, error) -> Void in
+ // Do something e.g. Alert a user that the transfer has completed.
+ // On failed uploads, `error` contains the error object.
+ }
+
+ //Instantiate the transferUtility object. This will pick up the bucketName, region,
+ //and auth configuration from the awsconfiguration.json file
+ let transferUtility = AWSS3TransferUtility.default()
+
+ //Upload the data. Pass in the expression to get progress updates and completion handler to get notified
+ //when the transfer is completed.
+ let task = transferUtility.uploadData(data!,
+ key: "public/YourFileName"
+ contentType: "text/plain",
+ expression: expression,
+ completionHandler: completionHandler)
+ }
+```
+
+## Download a File
+
+The following example shows how to download a file from an |S3| bucket.
+
+```swift
+func downloadData() {
+
+ //Create an expression object for progress tracking, to pass in request headers etc.
+ let expression = AWSS3TransferUtilityDownloadExpression()
+ expression.progressBlock = {(task, progress) in
+ // Do something e.g. Update a progress bar.
+ }
+
+//Create a completion handler to be called when the transfer completes
+ var completionHandler: AWSS3TransferUtilityDownloadCompletionHandlerBlock?
+ completionHandler = { (task, URL, data, error) -> Void in
+ // Do something e.g. Alert a user for transfer completion.
+ // On failed downloads, `error` contains the error object.
+ }
+
+
+ //Instantiate the transferUtility object. This will pickup the bucketName, region, and auth configuration
+ //from the awsconfiguration.json file
+ let transferUtility = AWSS3TransferUtility.default()
+
+ //Download the data. Pass in the expression to get progress updates and completion handler to get notified
+ //when the transfer is completed.
+ let task = transferUtility.downloadData(
+ fromKey: "public/YourFileName",
+ expression: expression,
+ completionHandler: completionHandler
+ )
+
+}
+```
+
+Next Steps
+==========
+
+* For sample apps that demonstrate TransferUtility capabilities, see [iOS S3 TransferUtility Sample](https://github.com/awslabs/aws-sdk-ios-samples/tree/master/S3TransferUtility-Sample).
+
+* Looking for Amazon Cognito Sync? If you are a new user, use [AWS AppSync](https://aws.amazon.com/appsync/) instead. AppSync is a new service for synchronizing application data across devices. Like Cognito Sync, AppSync enables synchronization of a user's own data, such as game state or app preferences. AppSync extends these capabilities by allowing multiple users to synchronize and collaborate in real time on shared data, such as a virtual meeting space or chat room. [Start building with AWS AppSync now](https://aws.amazon.com/appsync/)