Developer Console

SDK for iOS Getting Started

Getting started with an example app

Creating a New Amazon Drive App

ACDSKitHelloWorld App

To illustrate the steps necessary to create a new Amazon Drive app, we'll create a simple iOS app that enables a user to log in and view a listing of the contents of their Amazon Drive account. First, we will use the Amazon Developer Console to create the necessary security profile and API key. Then, we will set up a new Xcode project with the LoginWithAmazon and ACDSKit frameworks.

Registration and Being Added to the Allow List

Create a Security Profile

The Amazon Drive API uses Login with Amazon for authentication. You can learn more about Login with Amazon or begin by registering your security profile.

  1. Navigate to the Login with Amazon section of the Amazon Developer Console.
  2. Click the button to create a new security profile.
  3. Enter security profile information including name, description, and privacy policy URL. For now, use any URL for the privacy policy - you can update it later.

Create an API Key

An API key allows Amazon to verify your app's identity. You should create an API key for every iOS app bundle ID.

  1. Select your security profile from the Security Profiles section of the Amazon Developer Console, or else use the settings icon next to your profile in the Login with Amazon section to navigate to the profile's iOS Settings.
  2. Enter your app's name and bundle ID. Remember the bundle ID you enter here - it must match the bundle ID of your Xcode project.
  3. Click the button to generate a new API key.

Adding your Security Profile to the Allow List with Amazon Drive

To develop with Amazon Drive, you need to be invited to use the service to add your security profile to the allow list.

Creating a New Project

Create a New iOS Project

First, create a new iOS project using Xcode.

  1. Launch Xcode.
  2. Select File > New > Project….
  3. Select an iOS > Application > Single View Application.
  4. Enter your product name, organization name, and organization identifier. Your product name and organization identifier are used to automatically construct your bundle identifier. Remember that your bundle ID must match the one entered when creating your API key. To retrieve that bundle ID, select your security profile from the Security Profiles section of the Amazon Developer Console, or else use the settings icon next to your profile in the Login with Amazon section to navigate to the profile's iOS Settings.
  5. Select Objective-C as the language (or follow the guide on mixing Objective-C and Swift code).
  6. Click the button to continue and create the project.

Set the API Key

In order for Amazon to verify your app's identity, you need to add your Amazon API key to the Xcode project.

  1. Make sure you have your API key on hand. To find your API key, select your security profile from the Security Profiles section of the Amazon Developer Console, or else use the settings icon next to your profile in the Login with Amazon section to navigate to the profile's iOS Settings.
  2. Open your Xcode project's Info.plist file. You can find this file in the project navigator in Supporting Files. You can also find it in the Info tab for your target.
  3. Make sure none of the entries are selected. Then select Editor > Add Item and enter the following values:
    • Key : APIKey
    • Type : String
    • Value : Copy and paste your API key from the Amazon Developer Console.
  4. Save your changes to the plist file. For troubleshooting, see the Login with Amazon Getting Started guide.

Add a URL Scheme for Login

Upon initiating login, the user will be presented with a login page using Safari. In order for your app to receive confirmation of their login, you must add a URL scheme so the web page can redirect back to your app.

  1. Open your Xcode project's Info.plist file. You can find this file in the project navigator in Supporting Files. You can also find it in the Info tab for your target.
  2. Make sure none of the entries are selected. Then select Editor > Add Item and for Key select URL types
  3. Expand URL types and its one item Item 0
  4. If URL identifier exists under Item 0, select it. Otherwise, select Item 0 under URL types and then select Editor > Add Item
  5. Enter the following values:
    • Key : Select URL identifier
    • Type : String (selected automatically)
    • Value : Copy and paste the value of your Bundle identifier, which is also listed in this same plist file (for example com.example.ACDSKitHelloWorld)
  6. Select Item 0 under URL types and then select Editor > Add Item and enter the following values:
    • Key : Select URL Schemes
    • Type : Array (selected automatically)
  7. Expand URL Schemes
  8. For Item 0 under URL Schemes, enter the following values:
    • Type : String (selected automatically)
    • Value : Copy and paste the value of your Bundle identifier, which is also listed in this same plist file, and add the prefix amzn- (for example amzn-com.example.ACDSKitHelloWorld)
  9. Save your changes to the plist file. For troubleshooting, see the Login with Amazon Getting Started guide.

Add Required Frameworks

To develop with Amazon Drive, your Xcode project will need to depend on both the LoginWithAmazon and ACDSKit frameworks.

  1. Download and unzip the Amazon Drive SDK for iOS.
  2. To add Login with Amazon to your Xcode project, select File > Add Files…
    1. Under the Destination options, click on the Copy items if needed option to select it.
    2. Select LoginWithAmazon.framework in the unzipped SDK folder at Apps-SDK/iOS/LoginWithAmazon/LoginWithAmazon.framework
  3. Login with Amazon also requires that you add the Security framework to your project.
    1. Select your project in the project navigator.
    2. Select your target in the list of targets.
    3. Select the Build Phases tab.
    4. Expand the section labeled Link Binary With Libraries
    5. Click the + button and add Security.framework
  4. To add Amazon Drive to your Xcode project, select File > Add Files…
    1. Under the Destination options, click on the Copy items if needed option to select it.
    2. Select ACDSKit.framework in the unzipped SDK folder at Apps-SDK/iOS/AmazonCloudDrive/1.0.0/ACDSKit.framework
  5. The Amazon Drive framework requires that you add a Other Linker Flag to your target's Build Settings. For more information, see this technical document.
    1. Select your project in the project navigator.
    2. Select your target in the list of targets.
    3. Select the Build Settings tab.
    4. Find the setting under Linking called Other Linker Flags
    5. Double click the value of the setting to reveal the list of linker flags.
    6. Click the + button and add -ObjC

Add Login Helper Code

It is entirely possible to work directly with Login with Amazon, and you can learn how to do so with the Login with Amazon Getting Started guide. If you'd rather focus on developing the rest of your app functionality however, an extra package of open source code is available to be added to your project which makes working with Login with Amazon much easier.

  1. In your Xcode project, click on the File drop-down menu and select the Add Files... option.
  2. Under the Destination options, click on the Copy items if needed option to select it.
  3. Navigate to the location that you unzipped the SDK for iOS and select the directory named LoginHelper. It should be located at SDK-iOS/iOS/AmazonCloudDrive/1.0.0/samples/ACDSKitSampleApp/ACDSKitSampleApp/LoginHelper.
  4. Open AMZNLoginWithAmazonConstants.h and set the value of the macro kAMZNCloudDriveAccessTokenActiveScope to an array of the scopes for which your app is requesting access from the user. The default value is kAMZNCloudDriveAccessTokenAllScope, but you should only request the scopes that are required for your app to function.

    To request all scopes:

        #define kAMZNCloudDriveAccessTokenActiveScope kAMZNCloudDriveAccessTokenAllScope
    

    To request read-only scopes:

        #define kAMZNCloudDriveAccessTokenActiveScope @[kAMZNCloudDriveAccessTokenReadScope]
    

This provides a [AMZNAccountManager sharedProvider] object that you can use for easy asynchronous calls to trigger login and logout. It also provides a [AMZNAuthorizationProvider sharedProvider] object that you can use as the required auth token provider for ACDSKClient.

Implementing Login and Logout

Update AppDelegate

After the app presents the Amazon login page using the Safari browser and the user completes login, the browser will redirect to the app using the URL Scheme the app registered earlier. That redirect is passed to application:openURL:sourceApplication:annotation: which should return YES if the URL was successfully handled. LoginWithAmazon has an SDK library function handleOpenURL:sourceApplication: that will handle Login with Amazon redirect URLs for you.

  1. In AppDelegate.m, import LoginWithAmazon:

    #import <LoginWithAmazon/LoginWithAmazon.h>
    
  2. Update AppDelegate.m to include the following:

    - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
    
    // Pass on the url to the SDK to parse authorization code from the url.
    BOOL isValidRedirectLogInURL = [AIMobileLib handleOpenURL:url sourceApplication:sourceApplication];
    
    if(!isValidRedirectLogInURL)
        return NO;
    
    // App may also want to handle url
    return YES;
    
    }
    

Add Login Controls

Our first goal is to enable the user to log in and out of an Amazon account. For help with creating a user interface in Xcode, refer to this iOS Getting Started guide.

  1. In ViewController.m, import AMZNAccountManager:

    #import "AMZNAccountManager.h"
    
  2. Open the Main.storyboard interface and find the one scene for the view controller.
  3. Add two buttons to the view controller scene - one each for login and logout.
  4. Add a text view to the view controller scene as well for simple output. Disable editing on the text view.
  5. Add an outlet for the text view pointing to the scene's implementation file ViewController.m:

    @property (weak, nonatomic) IBOutlet UITextView *outputTextView;
    
  6. Clear the text view output in ViewController.m viewDidLoad:

    - (void)viewDidLoad {
          [super viewDidLoad];
          self.outputTextView.text = @"";
      }
    
  7. Add an action for each button pointing to the scene's implementation file ViewController.m and use the shared instance of AMZNAccountManager to respond accordingly. When updating UI in response to an asynchrounous AMZNAccountManager callback, be sure to do so on the main thread.

        - (IBAction)loginButtonPressed:(id)sender {
              [[AMZNAccountManager sharedProvider] loginAsynchronously:^(id result, NSError *error) {
                  dispatch_async(dispatch_get_main_queue(), ^{
                      // Add to output
                      if (error) {
                          self.outputTextView.text = [self.outputTextView.text stringByAppendingFormat:@"login failure: %@\n", error];
                      } else {
                          self.outputTextView.text = [self.outputTextView.text stringByAppendingFormat:@"login success: %@\n", result];
                      }
                  });
              }];
          }
    
          - (IBAction)logoutButtonPressed:(id)sender {
              [[AMZNAccountManager sharedProvider] logoutAsynchronously:^(id result, NSError *error) {
                  dispatch_async(dispatch_get_main_queue(), ^{
                      // Add to output
                      if (error) {
                          self.outputTextView.text = [self.outputTextView.text stringByAppendingFormat:@"logout failure: %@\n", error];
                      } else {
                          self.outputTextView.text = [self.outputTextView.text stringByAppendingFormat:@"logout success: %@\n", result];
                      }
                  });
              }];
          }
    
  8. Build and run. You should be able to log in and log out and see corresponding output in the text view.

Viewing Nodes

Add Client Property

We need to keep a strong reference to an instance of ACDSKClient so that it is not deallocated before our request is sent. An easy way to do this is to create a shared instance of ACDSKClient that we can use throughout our app. For details on how to do so, see the ACDSKClient section of the iOS Best Practices documentation. For now, we'll just lazily instantiate an ACDSKClient object in the view controller and hold onto it as a strong property.

  1. In ViewController.m, import ACDSKit and AMZNAuthorizationProvider:

        #import <ACDSKit/ACDSKit.h>
        #import "AMZNAuthorizationProvider.h"
    
  2. Add a strong property of type ACDSKClient to ViewController.m:

        @property (strong, nonatomic) ACDSKClient *client;
    
  3. Lazily instantiate the ACDSKClient property in ViewController.m by creating the object on demand in the property getter implementation.

        - (ACDSKClient *)client {
              if (_client == nil) {
                  _client = [ACDSKClient clientWithTokenProvider:^NSString *{
                      NSError *error = nil;
                      return [[AMZNAuthorizationProvider sharedProvider] fetchAuthTokenSynchronously:&error];
                  }];
              }
              return _client;
          }
    
  4. We need to deallocate our instance of ACDSKClient on logout. In the implementation of logoutButtonPressed: in ViewController.m, add a line to set client to nil.

        - (IBAction)logoutButtonPressed:(id)sender {
              [[AMZNAccountManager sharedProvider] logoutAsynchronously:^(id result, NSError *error) {
                  dispatch_async(dispatch_get_main_queue(), ^{
                      // Deallocate the client
                      self.client = nil;
                      // Add to output
                  });
              }];
    

Add Button to List Nodes

Finally, we can provide a button to list nodes from the user's Amazon Drive. We'll do this by creating a request object and sending it with our client.

  1. It's useful to have a reference to the task that will be created when sending our request. Add a strong property of type ACDSKTask to ViewController.m

          @property (strong, nonatomic) ACDSKTask *listNodesTask;
    
  2. We should cancel our client task on logout. In the implementation of logoutButtonPressed: in ViewController.m, add a couple lines to cancel listNodesTask and set it to nil.

          - (IBAction)logoutButtonPressed:(id)sender {
              [[AMZNAccountManager sharedProvider] logoutAsynchronously:^(id result, NSError *error) {
                  dispatch_async(dispatch_get_main_queue(), ^{
                      // Cancel the task
                      [self.listNodesTask cancel];
                      self.listNodesTask = nil;
                      // Deallocate the client
                      self.client = nil;
                      // Add to output
                      // ...
                  });
              }];
    
  3. Open the Main.storyboard interface and find the one scene for the view controller.
  4. Add another button to the view controller scene for listing nodes.
  5. Add an action for the button pointing to the scene's implementation file ViewController.m and use its ACDSKClient property to respond accordingly. We'll use listNodesTask to keep a reference to the task and only allow one such task to run at a time. When updating UI in response to an asynchrounous ACDSKClient callback, be sure to do so on the main thread.

          - (IBAction)listNodesButtonPressed:(id)sender {
    
              // Only allow one listNodesTask at a time
              if (self.listNodesTask == nil) {
    
                  // Create a request to list nodes
                  ACDSKListNodesRequest *listNodesRequest = [ACDSKListNodesRequest new];
    
                  // Send the request, and keep a reference to the task
                  self.listNodesTask = [self.client listNodes:listNodesRequest fail:^(NSError *error) {
                      dispatch_async(dispatch_get_main_queue(), ^{
                          // Drop the reference to the task
                          self.listNodesTask = nil;
                          // Add to output
                          self.outputTextView.text = [self.outputTextView.text stringByAppendingFormat:@"list nodes failure: %@\n", error];
                      });
                  } success:^(ACDSKListNodesResponse *response) {
                      // Construct the output
                      NSString *nodesDescription = @"";
                      for (ACDSKNode *node in response.data) {
                          nodesDescription = [nodesDescription stringByAppendingFormat:@"%@ (%@ - %@)\n", node.name, node.kind, node.contentProperties.contentType];
                      }
                      dispatch_async(dispatch_get_main_queue(), ^{
                          // Drop the reference to the task
                          self.listNodesTask = nil;
                          // Add to output
                          self.outputTextView.text = [self.outputTextView.text stringByAppendingFormat:@"list nodes success: %@ nodes:\n%@", @(response.data.count), nodesDescription];
                      });
                  }];
    
              }
    
          }
    
  6. Build and run. Once logged in, you should be able to list nodes and see a list of nodes (including their name and kind) in the text view.
hello world screenshot

Support

If you have any questions, see the Developer Forum.