使用适用于iOS API的Login with Amazon SDK(v2.1.2及更低版本)
较低版本的SDK虽然已不可下载,但本文将保留与之相关的说明,以便为正在使用这些SDK的开发者提供帮助。
要求
适用于iOS的Login with Amazon SDK(2.1.2及更低版本)支持允许iOS 7.0的应用,以及使用ARMv7、ARMv7s、ARM64、i386和x86_64的应用。SDK仅适用于Xcode开发环境。
您可以在此处 https://developer.apple.com/xcode安装Xcode。
处理登录按钮并获取用户个人资料数据
本部分介绍了如何调用authorizeUserForScopes:delegate:
和getProfile:
API来登录用户和检索其个人资料数据。这包括为Login with Amazon按钮创建onLoginButtonClicked:
侦听器。
-
将Login with Amazon API导入到源文件。要导入Login with Amazon API,需要为源文件添加以下
#import
语句:#import <LoginWithAmazon/LoginWithAmazon.h>
-
创建
AMZNAuthorizeUserDelegate
类以实现AIAuthenticationDelegate
。authorizeUserForScopes:delegate:
完成后,将在实现AIAuthenticationDelegate
协议的对象上调用requestDidSucceed:
或requestDidFail:
方法。@interface AMZNAuthorizeUserDelegate : NSObject<AIAuthenticationDelegate> @end
有关更多信息,请参阅developer.apple.com中的使用协议。
-
调用
onLoginButtonClicked
中的authorizeUserForScopes:delegate:
。如果您按照为您的应用添加Login with Amazon按钮中的步骤操作,则
onLoginButtonClicked:
方法应链接到Login with Amazon按钮。在此方法中,调用authorizeUserForScopes:delegate:
来提示用户登录并授权应用。此方法将使用以下其中一种方式来实现用户登录并同意请求信息:
- 切换到安全环境下的网页视图(适用于已安装亚马逊购物应用的设备)
- 切换到Safari视图控制器(适用于iOS 9及更高版本)
- 切换到系统浏览器(iOS 8及更低版本)
如果设备已安装马逊购物应用,可实现第一个选项中的安全环境。如果用户已登录到亚马逊购物应用,此API将跳过登录页面,直接提供单点登录(SSO)体验。
如果您的应用已获得授权,则将会得到一个或多个数据集的授权,即范围。第一个参数是一个范围数组,包含了向Login with Amazon请求的用户数据。用户首次登录您的应用时,将看到您请求的数据列表并会询问是否批准。Login with Amazon目前支持三个范围:
profile
包含用户的名称、电子邮件地址和亚马逊账户ID,profile:user_id
仅包含亚马逊账户ID,postal_code
包含用户的邮政编码。authorizeUserForScopes:delegate:
的第二个参数为实现AIAuthenticationDelegate
协议的对象,在此情景下,属于一项AMZNAuthorizeUserDelegate
类实例。- (IBAction)onLogInButtonClicked:(id)sender { // 向SDK作出授权调用,为用户获取安全的访问令牌。 // 作出第一个调用时,您可以指定所需的最小基本 // 范围。 // 为当前用户请求两个范围。 NSArray *requestScopes = [NSArray arrayWithObjects:@"profile", @"postal_code", nil]; AMZNAuthorizeUserDelegate* delegate = [[AMZNAuthorizeUserDelegate alloc] initWithParentController:self]; [AIMobileLib authorizeUserForScopes:requestScopes delegate:delegate]; }
为调用
authorizeUserForScopes:
的类添加委托实现标头。例如:#import "AMZNAuthorizeUserDelegate.h"
-
创建
AMZNGetProfileDelegate
。AMZNGetProfileDelegate
是实现AIAuthenticationDelegate
协议的类的名称,将处理getProfile:
调用的结果。与authorizeUserForScopes:delegate:
类似,getProfile:
支持requestDidSucceed:
和requestDidFail:
协议方法。requestDidSucceed:
将在result
属性中收到包含个人资料数据的APIResult
对象。requestDidFail:
将在error
属性中收到包含错误信息的AIError
对象。要从正常类声明中创建委托,需要导入
AIAuthenticationDelegate.h
,并在类标头文件中为声明添加协议:#import <LoginWithAmazon/LoginWithAmazon.h> @interface AMZNGetProfileDelegate : NSObject<AIAuthenticationDelegate> @end
-
为您的
AMZNAuthorizeUserDelegate
实现requestDidSucceed:
。在
requestDidSucceed:
中,调用getProfile:
来检索客户个人资料。getProfile:
与authorizeUserForScopes:delegate:
类似,都使用AIAuthenticationDelegate
协议。- (void)requestDidSucceed:(APIResult *)apiResult { // 用户为应用授权 // 请求范围后的代码。 // 加载包含用户识别信息的新的视图控制器 // 用户现已成功登录。 AMZNGetProfileDelegate* delegate = [[[AMZNGetProfileDelegate alloc] initWithParentController:parentViewController] autorelease]; [AIMobileLib getProfile:delegate]; }
为调用
getProfile:
的类添加委托实现标头。例如:#import "AMZNGetProfileDelegate.h"
-
为您的
AMZNGetProfileDelegate
实现requestDidSucceed:
。requestDidSucceed:
有两个主要任务:从APIResult
检索个人资料数据,以及将数据传递到UI。要从
APIResult
中检索个人资料数据,需要访问result
属性。对于getProfile:
响应,该属性将包含用户个人资料属性的属性值词典。profile
范围的个人资料属性为name
、email
和user_id
,postal_code
范围的个人资料属性为postal_code
。- (void)requestDidSucceed:(APIResult *)apiResult { // 获取个人资料请求成功。解析个人资料信息 // 并将其传递到根视图控制器 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"]; // 向视图控制器传递数据 }
-
为您的
AMZNGetProfileDelegate
实现requestDidFail:
。requestDidFail:
包括一个含有错误相关详细信息的APIError
对象。showLogInPage
是一个假想方法,可重置主视图控制器以显示Login with Amazon按钮。- (void)requestDidFail:(APIError *)errorResponse { // 获取个人资料范围的个人资料请求失败。 // 如果error code = kAIApplicationNotAuthorized, // 则允许用户重新登录。 if(errorResponse.error.code == kAIApplicationNotAuthorized) { // 显示授权用户按钮。 [parentViewController showLogInPage]; } else { // 处理其他错误 [[[[UIAlertView alloc] initWithTitle:@"" message:[NSString stringWithFormat:@"Error occured with message: %@", errorResponse.error.message] delegate:nil cancelButtonTitle:@"OK"otherButtonTitles:nil] autorelease] show]; } }
-
为您的
AMZNAuthorizeUserDelegate
实现requestDidFail:
。- (void)requestDidFail:(APIError *)errorResponse { NSString *message = errorResponse.error.message; // 授权失败时的代码。 [[[[UIAlertView alloc] initWithTitle:@"" message:[NSString stringWithFormat:@"User authorization failed with message: %@", errorResponse.error.message] delegate:nil cancelButtonTitle:@"OK"otherButtonTitles:nil] autorelease] show]; }
-
在处理
UIApplicationDelegate
协议的项目类中(默认为项目中的AppDelegate
类),实现application:openURL:sourceApplication:annotation:
。如果应用使用Safari浏览器来显示亚马逊登录页面,且用户已完成登录,则浏览器将使用应用之前注册的URL方案来重定向到该应用。重定向将被传递给application:openURL:sourceApplication:annotation:
,如果URL处理成功将返回YES
。handleOpenURL:sourceApplication:
是处理Login with Amazon重定向URL的SDK库l功能重定向URL。如果handleOpenURL:sourceApplication:
返回YES
,则表示URL已完成处理。- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { // 向SDK传递URL,以解析URL的授权码。 BOOL isValidRedirectSignInURL = [AIMobileLib handleOpenURL:url sourceApplication:sourceApplication]; if(!isValidRedirectSignInURL) return NO; // 应用可能还需要处理url return YES; }
注意: iOS 9已弃用此方法,但您的项目可保留此方法,以便为低版本平台的用户提供支持。有关更多关于application:openURL:sourceApplication:annotation:
的信息,请参阅developer.apple.com中的UIApplicationDelegate Protocol Reference
检查首次登录的用户
如果用户登录并关闭您的应用,并在之后重新启动,应用仍然有权检索数据。用户不会自动注销。如果您的应用仍处于授权状态,可在启动时将用户显示为已登录。本部分介绍了如何使用getAccessTokenForScopes:withOverrideParams:delegate:
来确定应用是否仍处于授权状态。
-
创建
AMZNGetAccessTokenDelegate
类。AMZNGetAccessTokenDelegate
实现AIAuthenticationDelegate
协议,并处理getAccessTokenForScopes:withOverrideParams:delegate:
调用的结果。AIAuthenticationDelegate
包含两种方法,即requestDidSucceed:
和requestDidFail:
。requestDidSucceed:
将收到包含令牌数据的APIResult
对象,requestDidFail:
将受到包含错误信息的APIError
对象。#import <LoginWithAmazon/LoginWithAmazon.h> @interface AMZNGetAccessTokenDelegate : NSObject<AIAuthenticationDelegate> @end
为调用
getAccessTokenForScopes:withOverrideParams:delegate:
的类添加委托实现标头。例如:#import "AMZNGetAccessTokenDelegate.h"
-
在应用首次启动时,调用
getAccessTokenForScopes:withOverrideParams:delegate:
来确定应用是否仍处于授权状态。getAccessTokenForScopes:withOverrideParams:delegate:
将检索Login with Amazon用来访问客户个人资料的原始访问令牌访问令牌。如果方法成功,应用仍处于授权状态,可成功调用getProfile:
。getAccessTokenForScopes:withOverrideParams:delegate:
使用AIAuthenticationDelegate
协议的方式与authorizeUserForScopes:delegate:
相同。将实现协议的对象传递为delegate
参数。- (void)checkIsUserSignedIn { AMZNGetAccessTokenDelegate* delegate = [[[AMZNGetAccessTokenDelegate alloc] initWithParentController:self] autorelease]; NSArray *requestScopes = [NSArray arrayWithObjects:@"profile", @"postal_code", nil]; [AIMobileLib getAccessTokenForScopes:requestScopes withOverrideParams:nil delegate:delegate]; }
-
在您的
AMZNGetAccessTokenDelegate
中实现requestDidSucceed:
。requestDidSucceed:
只有一项任务:调用getProfile:
。此示例调用getProfile:
时所用的侦听器是您在上文中声明的侦听器(请参阅步骤6-8)。#import "AMZNGetProfileDelegate.h" #import <LoginWithAmazon/LoginWithAmazon.h> - (void)requestDidSucceed:(APIResult *)apiResult { // 这是您用于访问令牌的代码。 // 由于应用已为范围授权,我们可以 // 获取用户个人资料。 AMZNGetProfileDelegate* delegate = [[[AMZNGetProfileDelegate alloc] initWithParentController:parentViewController] autorelease]; [AIMobileLib getProfile:delegate]; }
-
在您的
AMZNGetAccessTokenDelegate
中实现requestDidFail:
。requestDidFail:
包括一个含有错误相关详细信息的APIError
对象。如果您收到错误,则可以重置主视图控制器来显示Login with Amazon按钮。- (void)requestDidFail:(APIError *)errorResponse { // 用于处理访问令牌检索失败的代码。 // 如果error code = kAIApplicationNotAuthorized,则允许用户 // 重新登录。 if(errorResponse.error.code == kAIApplicationNotAuthorized) { // 显示Login with Amazon按钮。 } else { // 处理其他错误 [[[[UIAlertView alloc] initWithTitle:@"" message:[NSString stringWithFormat:@"Error occurred with message: %@", errorResponse.error.message] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease] show]; } }
清除授权状态并注销用户
clearAuthorizationState
方法将清除AIMobileLib
本地数据存储中的用户授权数据。应用若要检索个人资料数据,必须令用户重新登录。使用此方法可注销用户,也可以对应用中的登录问题进行故障排除。
-
声明
AMZNLogoutDelegate
。这是一个实现AIAuthenticationDelegate
协议的类。为实现我们的目的,可以从NSObject
中继承此类:#import <LoginWithAmazon/LoginWithAmazon.h> @interface AMZNLogoutDelegate : NSObject<AIAuthenticationDelegate> @end</pre> 为调用clearAuthorizationState的类添加委托实现标头: 例如: <pre>#import "AMZNLogoutDelegate.h"
-
调用
clearAuthorizationState:
。您应在用户成功登录后提供注销机制,以便用户清除授权数据。您的机制可以是超链接,也可以是菜单项,但在本示例情景下,将为注销按钮创建
logoutButtonClicked
方法。- (IBAction)logoutButtonClicked:(id)sender { AMZNLogoutDelegate* delegate = [[[AMZNLogoutDelegate alloc] initWithParentController:self] autorelease]; [AIMobileLib clearAuthorizationState:delegate]; }
clearAuthorizationState仅有的一项参数为
AIAuthenticationDelegate
,用于实现requestDidSucceed:
和requestDidFail:
。 -
实现
requestDidSucceed:
。此方法将在用户信息清除后进行调用。然后,应将其显示为已注销。- (void)requestDidSucceed:(APIResult *)apiResult { // 清除用户授权状态后的额外逻辑。 [[[UIAlertView alloc] initWithTitle:@"" message:@"User Logged out." delegate:nil cancelButtonTitle:@"OK"otherButtonTitles:nil] show]; }
-
实现
requestDidFail:
。如果因为某些原因,用户信息无法从缓存中清除,则调用此方法。在这种情况下,不应将其显示为已注销。- (void)requestDidFail:(APIError *)errorResponse { // SDK清除 // 授权状态失败后的额外逻辑。 [[[[UIAlertView alloc] initWithTitle:@"" message:[NSString stringWithFormat:@"User Logout failed with message: %@", errorResponse.error.message] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease] show]; }
测试集成
在iOS设备或模拟器中启动您的应用,并确认您可以使用Amazon.com的凭证进行登录。
authorizeUserForScopes
请求的错误消息APIKey for the Application is invalid(此应用的APIKey无效),或是关于clearAuthorizationState
请求的错误消息Unknown Error Code(未知错误代码)。这是苹果系统中的已知错误,见于SDK尝试访问密钥链的情况。在苹果解决此错误之前,您可以在应用目标的Capabilities(功能)选项卡下为应用启用Keychain Sharing(密钥链分享)来实现变通。此错误仅影响模拟器。在实际的iOS10设备中测试时无需使用变通方法。