使用适用于iOS API的Login with Amazon SDK(v2.1.2及更低版本)

使用适用于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:侦听器。

  1. 将Login with Amazon API导入到源文件。要导入Login with Amazon API,需要为源文件添加以下#import语句:

    #import <LoginWithAmazon/LoginWithAmazon.h>
    
  2. 创建AMZNAuthorizeUserDelegate类以实现AIAuthenticationDelegate

    authorizeUserForScopes:delegate:完成后,将在实现AIAuthenticationDelegate协议的对象上调用requestDidSucceed:requestDidFail:方法。

    @interface AMZNAuthorizeUserDelegate : NSObject<AIAuthenticationDelegate>
    @end
    

    有关更多信息,请参阅developer.apple.com中的使用协议

  3. 调用onLoginButtonClicked中的authorizeUserForScopes:delegate:

    如果您按照为您的应用添加Login with Amazon按钮中的步骤操作,则onLoginButtonClicked:方法应链接到Login with Amazon按钮。在此方法中,调用authorizeUserForScopes:delegate:来提示用户登录并授权应用。

    此方法将使用以下其中一种方式来实现用户登录并同意请求信息:

    1. 切换到安全环境下的网页视图(适用于已安装亚马逊购物应用的设备)
    2. 切换到Safari视图控制器(适用于iOS 9及更高版本)
    3. 切换到系统浏览器(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"
    
  4. 创建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
    
  5. 为您的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"
    
  6. 为您的AMZNGetProfileDelegate实现requestDidSucceed:

    requestDidSucceed:有两个主要任务:从APIResult检索个人资料数据,以及将数据传递到UI。

    要从APIResult中检索个人资料数据,需要访问result属性。对于getProfile:响应,该属性将包含用户个人资料属性的属性值词典。profile范围的个人资料属性为nameemailuser_idpostal_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"];
    
        // 向视图控制器传递数据
    }
    
  7. 为您的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];
        }
    }
    
  8. 为您的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];
    }
    
  9. 在处理UIApplicationDelegate协议的项目类中(默认为项目中的AppDelegate类),实现application:openURL:sourceApplication:annotation:。如果应用使用Safari浏览器来显示亚马逊登录页面,且用户已完成登录,则浏览器将使用应用之前注册的URL方案来重定向到该应用。重定向将被传递给application:openURL:sourceApplication:annotation:,如果URL处理成功将返回YEShandleOpenURL: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;
    }
    

检查首次登录的用户

如果用户登录并关闭您的应用,并在之后重新启动,应用仍然有权检索数据。用户不会自动注销。如果您的应用仍处于授权状态,可在启动时将用户显示为已登录。本部分介绍了如何使用getAccessTokenForScopes:withOverrideParams:delegate:来确定应用是否仍处于授权状态。

  1. 创建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"
    
  2. 在应用首次启动时,调用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];
    }
    
  3. 在您的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];
    }
    
  4. 在您的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本地数据存储中的用户授权数据。应用若要检索个人资料数据,必须令用户重新登录。使用此方法可注销用户,也可以对应用中的登录问题进行故障排除。

  1. 声明 AMZNLogoutDelegate。这是一个实现AIAuthenticationDelegate协议的类。为实现我们的目的,可以从NSObject中继承此类:

    #import <LoginWithAmazon/LoginWithAmazon.h>
    
    @interface AMZNLogoutDelegate : NSObject<AIAuthenticationDelegate>
    
    @end</pre>
    
    调用clearAuthorizationState的类委托实现标头 
    
    <pre>#import "AMZNLogoutDelegate.h"
    
  2. 调用clearAuthorizationState:

    您应在用户成功登录后提供注销机制,以便用户清除授权数据。您的机制可以是超链接,也可以是菜单项,但在本示例情景下,将为注销按钮创建logoutButtonClicked方法。

    - (IBAction)logoutButtonClicked:(id)sender {
        AMZNLogoutDelegate* delegate = [[[AMZNLogoutDelegate alloc]
          initWithParentController:self] autorelease];
    
        [AIMobileLib clearAuthorizationState:delegate];
    }
    

    clearAuthorizationState仅有的一项参数为AIAuthenticationDelegate,用于实现requestDidSucceed:requestDidFail:

  3. 实现requestDidSucceed:。此方法将在用户信息清除后进行调用。然后,应将其显示为已注销。

    - (void)requestDidSucceed:(APIResult *)apiResult {
        // 清除用户授权状态后的额外逻辑。
        [[[UIAlertView alloc] initWithTitle:@"" message:@"User Logged out."
            delegate:nil cancelButtonTitle:@"OK"otherButtonTitles:nil] show];
    }
    
  4. 实现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的凭证进行登录。