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
#importstatements to your source file:#import <LoginWithAmazon/LoginWithAmazon.h> -
Create the
AMZNAuthorizeUserDelegateclass to implementAIAuthenticationDelegate.When
authorizeUserForScopes:delegate:completes, it will call therequestDidSucceed:orrequestDidFail:method on an object that implements theAIAuthenticationDelegateprotocol.@interface AMZNAuthorizeUserDelegate : NSObject<AIAuthenticationDelegate> @endFor 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 theAIAuthenticationDelegateprotocol, in this case an instance of theAMZNAuthorizeUserDelegateclass.- (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.AMZNGetProfileDelegateis our name for a class that implements theAIAuthenticationDelegateprotocol, and will process the result of thegetProfile:call. LikeauthorizeUserForScopes:delegate:,getProfile:supports therequestDidSucceed:andrequestDidFail:protocol methods.requestDidSucceed:receives anAPIResultobject with profile data in theresultproperty.requestDidFail:receives anAIErrorobject with information on the error in theerrorproperty.To create a delegate class from a normal class declaration, import
AIAuthenticationDelegate.hand 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 theAIAuthenticationDelegateprotocol.- (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 theresultproperty. For agetProfile:response, that property will contain a dictionary of property values for the user profile properties. The profile properties arename,email, anduser_idfor theprofilescope andpostal_codefor thepostal_codescope.- (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 anAPIErrorobject containing details about the error.showLogInPageis 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 theUIApplicationDelegateprotocol (by default this will be theAppDelegateclass 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 returnsYESif 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
AMZNGetAccessTokenDelegateclass.AMZNGetAccessTokenDelegateimplements theAIAuthenticationDelegateprotocol, and will process the result of thegetAccessTokenForScopes:withOverrideParams:delegate:call.AIAuthenticationDelegatecontains two methods,requestDidSucceed:andrequestDidFail:.requestDidSucceed:receives anAPIResultobject with token data, whilerequestDidFail:receives anAPIErrorobject with information on the error.#import <LoginWithAmazon/LoginWithAmazon.h> @interface AMZNGetAccessTokenDelegate : NSObject<AIAuthenticationDelegate> @endAdd 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 theAIAuthenticationDelegateprotocol in the same manner asauthorizeUserForScopes:delegate:. Pass the object implementing the protocol as thedelegateparameter.- (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 anAPIErrorobject 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 theAIAuthenticationDelegateprotocol. 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
logoutButtonClickedmethod 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
AIAuthenticationDelegatethat 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.
