Use the Login with Amazon SDK for iOS APIs (v2.1.2 and below)
Older SDKs are no longer available for download, but we have preserved the instructions here for the convenience of our developers who are still using them.
- Requirements
- Handle the Login Button and Get User Profile Data
- Check for User Login at Startup
- Clear Authorization State and Log Out Users
- Test your Integration
Requirements
The Login with Amazon SDK for iOS (version 2.1.2 and below) supports apps running on iOS 7.0 and later using ARMv7, ARMv7s, ARM64, i386, and x86_64. The SDK is intended to be used with the Xcode development environment.
You can install Xcode from https://developer.apple.com/xcode.
Handle the Login Button and Get User Profile Data
This section explains how to call the authorizeUserForScopes:delegate:
and getProfile:
APIs to login a user and retrieve their profile data. This includes creating an onLoginButtonClicked:
listener for your Login with Amazon button.
-
Import the Login with Amazon API to your source file. To import the Login with Amazon API, add the following
#import
statements to your source file:#import <LoginWithAmazon/LoginWithAmazon.h>
-
Create the
AMZNAuthorizeUserDelegate
class to implementAIAuthenticationDelegate
.When
authorizeUserForScopes:delegate:
completes, it will call therequestDidSucceed:
orrequestDidFail:
method on an object that implements theAIAuthenticationDelegate
protocol.@interface AMZNAuthorizeUserDelegate : NSObject<AIAuthenticationDelegate> @end
For more information, see Working with Protocols on developer.apple.com.
-
Call
authorizeUserForScopes:delegate:
inonLoginButtonClicked
.If you followed the steps in Add a Login with Amazon Button to Your App, you should have an
onLoginButtonClicked:
method linked to a Login with Amazon button. In that method, callauthorizeUserForScopes:delegate:
to prompt the user to login and authorize your application.This method will enable the user to sign in and consent to the requested information in one of the following ways:
- Switches to web view in a secure context (if the Amazon Shopping app is installed to the device)
- Switches to Safari View Controller (on iOS 9 and later)
- Switches to the system browser (on iOS 8 and earlier)
The secure context for the first option is available when the Amazon Shopping app is installed to the device. If the user is already signed in to the Amazon Shopping app, the sign in page is skipped, leading to a Single Sign-On (SSO) experience.
When your application is authorized, it is authorized for one or more data sets known as scopes. The first parameter is an array of scopes that encompass the user data you are requesting from Login with Amazon. The first time a user logs in to your app, they will be presented with a list of the data you are requesting and asked for approval. Login with Amazon currently supports three scopes:
profile
, which contains the user's name, email address, and Amazon account id;profile:user_id
, which contains only the Amazon account id; andpostal_code
, which contains the user's zip/postal code.The second parameter to
authorizeUserForScopes:delegate:
is an object that implements theAIAuthenticationDelegate
protocol, in this case an instance of theAMZNAuthorizeUserDelegate
class.- (IBAction)onLogInButtonClicked:(id)sender { // Make authorize call to SDK to get secure access token for the user. // While making the first call you can specify the minimum basic // scopes needed. // Requesting both scopes for the current user. NSArray *requestScopes = [NSArray arrayWithObjects:@"profile", @"postal_code", nil]; AMZNAuthorizeUserDelegate* delegate = [[AMZNAuthorizeUserDelegate alloc] initWithParentController:self]; [AIMobileLib authorizeUserForScopes:requestScopes delegate:delegate]; }
Add your delegate implementation header to the class calling
authorizeUserForScopes:
. For example:#import "AMZNAuthorizeUserDelegate.h"
-
Create an
AMZNGetProfileDelegate
.AMZNGetProfileDelegate
is our name for a class that implements theAIAuthenticationDelegate
protocol, and will process the result of thegetProfile:
call. LikeauthorizeUserForScopes:delegate:
,getProfile:
supports therequestDidSucceed:
andrequestDidFail:
protocol methods.requestDidSucceed:
receives anAPIResult
object with profile data in theresult
property.requestDidFail:
receives anAIError
object with information on the error in theerror
property.To create a delegate class from a normal class declaration, import
AIAuthenticationDelegate.h
and add the protocol to the declaration in your class header file:#import <LoginWithAmazon/LoginWithAmazon.h> @interface AMZNGetProfileDelegate : NSObject<AIAuthenticationDelegate> @end
-
Implement
requestDidSucceed:
for yourAMZNAuthorizeUserDelegate
.In
requestDidSucceed:
, callgetProfile:
to retrieve the customer profile .getProfile:
, likeauthorizeUserForScopes:delegate:
, uses theAIAuthenticationDelegate
protocol.- (void)requestDidSucceed:(APIResult *)apiResult { // Your code after the user authorizes application for // requested scopes. // Load new view controller with user identifying information // as the user is now successfully logged in. AMZNGetProfileDelegate* delegate = [[[AMZNGetProfileDelegate alloc] initWithParentController:parentViewController] autorelease]; [AIMobileLib getProfile:delegate]; }
Add your delegate implementation header to the class calling
getProfile:
. For example:#import "AMZNGetProfileDelegate.h"
-
Implement
requestDidSucceed:
for yourAMZNGetProfileDelegate
.requestDidSucceed:
has two main tasks; retrieve the profile data from theAPIResult
, and pass the data to the UI.To retrieve the profile data from the
APIResult
, access theresult
property. For agetProfile:
response, that property will contain a dictionary of property values for the user profile properties. The profile properties arename
,email
, anduser_id
for theprofile
scope andpostal_code
for thepostal_code
scope.- (void)requestDidSucceed:(APIResult *)apiResult { // Get profile request succeeded. Unpack the profile information // and pass it to the parent view controller NSString* name = [(NSDictionary*)apiResult.result objectForKey:@"name"]; NSString* email = [(NSDictionary*)apiResult.result objectForKey:@"email"]; NSString* user_id = [(NSDictionary*)apiResult.result objectForKey:@"user_id"]; NSString* postal_code = [(NSDictionary*)apiResult.result objectForKey:@"postal_code"]; // Pass data to view controller }
-
Implement
requestDidFail:
for yourAMZNGetProfileDelegate
.requestDidFail:
includes anAPIError
object containing details about the error.showLogInPage
is a hypothetical method that would reset the main view controller to show the Login with Amazon button.- (void)requestDidFail:(APIError *)errorResponse { // Get Profile request failed for profile scope. // If error code = kAIApplicationNotAuthorized, // allow user to log in again. if(errorResponse.error.code == kAIApplicationNotAuthorized) { // Show authorize user button. [parentViewController showLogInPage]; } else { // Handle other errors [[[[UIAlertView alloc] initWithTitle:@"" message:[NSString stringWithFormat:@"Error occured with message: %@", errorResponse.error.message] delegate:nil cancelButtonTitle:@"OK"otherButtonTitles:nil] autorelease] show]; } }
-
Implement
requestDidFail:
for yourAMZNAuthorizeUserDelegate
.- (void)requestDidFail:(APIError *)errorResponse { NSString *message = errorResponse.error.message; // Your code when the authorization fails. [[[[UIAlertView alloc] initWithTitle:@"" message:[NSString stringWithFormat:@"User authorization failed with message: %@", errorResponse.error.message] delegate:nil cancelButtonTitle:@"OK"otherButtonTitles:nil] autorelease] show]; }
-
Implement
application:openURL:sourceApplication:annotation:
in the class in your project that handles theUIApplicationDelegate
protocol (by default this will be theAppDelegate
class in your project). When 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 toapplication:openURL:sourceApplication:annotation:
, which returnsYES
if the URL was successfully handled.handleOpenURL:sourceApplication:
is an SDK library function that will handle Login with Amazon redirect URL for you. IfhandleOpenURL:sourceApplication:
returnsYES
, then the URL was handled.- (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 isValidRedirectSignInURL = [AIMobileLib handleOpenURL:url sourceApplication:sourceApplication]; if(!isValidRedirectSignInURL) return NO; // App may also want to handle url return YES; }
Note: This method is deprecated in iOS 9 but should be included in your project to maintain support for users on older platforms. For more information onapplication:openURL:sourceApplication:annotation:
, see UIApplicationDelegate Protocol Reference on developer.apple.com
Check for User Login at Startup
If a user logs into your app, closes the app, and restarts the app later, the app is still authorized to retrieve data. The user is not logged out automatically. At startup, you can show the user as logged in if your app is still authorized. This section explains how to use getAccessTokenForScopes:withOverrideParams:delegate:
to see if the app is still authorized.
-
Create an
AMZNGetAccessTokenDelegate
class.AMZNGetAccessTokenDelegate
implements theAIAuthenticationDelegate
protocol, and will process the result of thegetAccessTokenForScopes:withOverrideParams:delegate:
call.AIAuthenticationDelegate
contains two methods,requestDidSucceed:
andrequestDidFail:
.requestDidSucceed:
receives anAPIResult
object with token data, whilerequestDidFail:
receives anAPIError
object with information on the error.#import <LoginWithAmazon/LoginWithAmazon.h> @interface AMZNGetAccessTokenDelegate : NSObject<AIAuthenticationDelegate> @end
Add your delegate implementation header to the class calling
getAccessTokenForScopes:withOverrideParams:delegate:
. For example:#import "AMZNGetAccessTokenDelegate.h"
-
On app startup, call
getAccessTokenForScopes:withOverrideParams:delegate:
to see if the application is still authorized.getAccessTokenForScopes:withOverrideParams:delegate:
retrieves the raw access token that Login with Amazon uses to access a customer profile. If the method succeeds, the app is still authorized and a call togetProfile:
should succeed.getAccessTokenForScopes:withOverrideParams:delegate:
uses theAIAuthenticationDelegate
protocol in the same manner asauthorizeUserForScopes:delegate:
. Pass the object implementing the protocol as thedelegate
parameter.- (void)checkIsUserSignedIn { AMZNGetAccessTokenDelegate* delegate = [[[AMZNGetAccessTokenDelegate alloc] initWithParentController:self] autorelease]; NSArray *requestScopes = [NSArray arrayWithObjects:@"profile", @"postal_code", nil]; [AIMobileLib getAccessTokenForScopes:requestScopes withOverrideParams:nil delegate:delegate]; }
-
Implement
requestDidSucceed:
on yourAMZNGetAccessTokenDelegate
.requestDidSucceed:
has one task: to callgetProfile:
. This example callsgetProfile:
using the same listener you declared in the previous section (see steps 6-8).#import "AMZNGetProfileDelegate.h" #import <LoginWithAmazon/LoginWithAmazon.h> - (void)requestDidSucceed:(APIResult *)apiResult { // Your code to use access token goes here. // Since the application has authorization for our scopes, we can // get the user profile. AMZNGetProfileDelegate* delegate = [[[AMZNGetProfileDelegate alloc] initWithParentController:parentViewController] autorelease]; [AIMobileLib getProfile:delegate]; }
-
Implement
requestDidFail:
on yourAMZNGetAccessTokenDelegate
.requestDidFail:
includes anAPIError
object containing details about the error. If you recieve an error, you can reset the main view controller to show the Login with Amazon button.- (void)requestDidFail:(APIError *)errorResponse { // Your code to handle failed retrieval of access token. // If error code = kAIApplicationNotAuthorized, allow user // to log in again. if(errorResponse.error.code == kAIApplicationNotAuthorized) { // Show Login with Amazon button. } else { // Handle other errors [[[[UIAlertView alloc] initWithTitle:@"" message:[NSString stringWithFormat:@"Error occurred with message: %@", errorResponse.error.message] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease] show]; } }
Clear Authorization State and Log Out Users
The clearAuthorizationState:
method will clear the user's authorization data from the AIMobileLib
local data store. A user will have to log in again in order for the app to retrieve profile data. Use this method to log out a user, or to troubleshoot login problems in the app.
-
Declare an
AMZNLogoutDelegate
. This is a class that implements theAIAuthenticationDelegate
protocol. For our purposes, we can inherit the class fromNSObject
:#import <LoginWithAmazon/LoginWithAmazon.h> @interface AMZNLogoutDelegate : NSObject<AIAuthenticationDelegate> @end</pre> Add your delegate implementation header to the class calling `clearAuthorizationState:`. For example: <pre>#import "AMZNLogoutDelegate.h"
-
Call
clearAuthorizationState:
.After a user has successfully logged in, you may provide a logout mechanism so they can clear their authorization data. Your mechanism might be a hyperlink, or a menu item, but for this scenario the example will create a
logoutButtonClicked
method for a logout button.- (IBAction)logoutButtonClicked:(id)sender { AMZNLogoutDelegate* delegate = [[[AMZNLogoutDelegate alloc] initWithParentController:self] autorelease]; [AIMobileLib clearAuthorizationState:delegate]; }
The only parameter to clearAuthorizationState is an
AIAuthenticationDelegate
that implementsrequestDidSucceed:
andrequestDidFail:
. -
Implement
requestDidSucceed:
. This method will be called when the user's information is cleared. You should then show them as logged out.- (void)requestDidSucceed:(APIResult *)apiResult { // Your additional logic after the user authorization state is cleared. [[[UIAlertView alloc] initWithTitle:@"" message:@"User Logged out." delegate:nil cancelButtonTitle:@"OK"otherButtonTitles:nil] show]; }
-
Implement
requestDidFail:
. This method will be called if for some reason the user's information cannot be cleared from the cache. In that case, you should not show them as logged out.- (void)requestDidFail:(APIError *)errorResponse { // Your additional logic after the SDK failed to clear // the authorization state. [[[[UIAlertView alloc] initWithTitle:@"" message:[NSString stringWithFormat:@"User Logout failed with message: %@", errorResponse.error.message] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease] show]; }
Test your Integration
Launch your app in an iOS device or simulator and confirm you can log in with your Amazon.com credentials.
authorizeUserForScopes
request, or Unknown Error Code for an clearAuthorizationState request
. This is a known bug with Apple which occurs when the SDK tries to access the keychain. Until Apple resolves the bug, you can work around it by enabling Keychain Sharing for your app under the Capabilities tab of your app's target. This bug only impacts simulators. You can test on actual iOS10 devices without using any workaround.