iOS用のLogin with Amazon SDK APIを使用する(v2.1.2以下)


iOS用のLogin with Amazon SDK APIを使用する(v2.1.2以下)

古いSDKは既にダウンロードできなくなっていますが、使用を継続している開発者向けに手順を保存しています。

要件

iOS用のLogin with Amazon SDK(バージョン2.1.2以下)は、ARMv7、ARMv7s、ARM64、i386、x86_64を使用してiOS 7.0以降を実行するアプリをサポートしています。このSDKは、Xcode開発環境向けです。

Xcodeは、https://developer.apple.com/xcodeからインストールできます。

ログインボタンの処理とユーザープロファイルデータの取得

このセクションでは、authorizeUserForScopes:delegate: APIと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:が完了すると、requestDidSucceed:メソッドまたはrequestDidFail:メソッドを呼び出し、AIAuthenticationDelegateプロトコルを実装します。

    @interface AMZNAuthorizeUserDelegate : NSObject<AIAuthenticationDelegate>
    @end
    

    詳細については、developer.apple.comのWorking with Protocols(プロトコルの使用)を参照してください。

  3. authorizeUserForScopes:delegate:onLoginButtonClickedで呼び出します。

    アプリに [Login with Amazon] ボタンを追加するの手順を実行していれば、onLoginButtonClicked:メソッドがLogin with Amazonボタンにリンクされているはずです。そのメソッドでauthorizeUserForScopes:delegate:を呼び出して、ユーザーにログインとアプリの認可を求める画面を表示します。

    この場合、ユーザーは次のいずれかの方法でサインインとリクエストされた情報への同意を行うことができます。

    1. 安全なコンテキストでウェブ表示に切り替える(デバイスにAmazonショッピングアプリがインストールされている場合)
    2. Safari View Controllerに切り替える(iOS 9以降)
    3. システムブラウザに切り替える(iOS 8以前)

    最初の選択肢にある安全なコンテキストは、Amazonショッピングアプリをデバイスにインストールしている場合に使用できます。ユーザーがAmazonショッピングアプリにサインインしている場合、サインインのページはスキップされ、シングルサインオン(SSO)が実行されます。

    アプリの認可時には、スコープと呼ばれるデータセット(1つ以上)に対して認可されます。最初のパラメーターは、Login with Amazonに対してリクエストしているユーザーデータを含むスコープの配列です。ユーザーが初めてアプリにログインするときに、開発者がリクエストして承認を求めているデータの一覧と一緒に提示されます。Login with Amazonで現在サポートしているスコープは次の3つです。profileには、ユーザー名、Eメールアドレス、AmazonアカウントIDが含まれます。profile:user_idには、AmazonアカウントIDのみが含まれます。postal_codeには、ユーザーの郵便番号が含まれます。

    authorizeUserForScopes:delegate:の2番目のパラメーターは、AIAuthenticationDelegateプロトコルを実装するオブジェクトです。この場合は、AMZNAuthorizeUserDelegateクラスのインスタンスです。

    - (IBAction)onLogInButtonClicked:(id)sender {
        // ユーザーのセキュアなアクセストークンを取得するためにSDKにauthorize呼び出しを実行。
        // 最初の呼び出し中に、最小限必要の基本的なスコープを
        // 指定できる。
    
        // 現在のユーザーに対して両方のスコープをリクエスト。
        NSArray *requestScopes =
            [NSArray arrayWithObjects:@"profile", @"postal_code", nil];
        AMZNAuthorizeUserDelegate* delegate =
            [[AMZNAuthorizeUserDelegate alloc] initWithParentController:self];
        [AIMobileLib authorizeUserForScopes:requestScopes delegate:delegate];
    }
    

    delegate実装ヘッダーをauthorizeUserForScopes:を呼び出しているクラスに実装します。次に例を示します。

    #import "AMZNAuthorizeUserDelegate.h"
    
  4. AMZNGetProfileDelegateを作成します。

    AMZNGetProfileDelegateAIAuthenticationDelegateプロトコルを実装するクラスの名前で、getProfile:呼び出しの結果を処理します。authorizeUserForScopes:delegate:と同じように、getProfile:requestDidSucceed:プロトコルとrequestDidFail:プロトコルのメソッドをサポートします。requestDidSucceed:はプロファイルデータが含まれるAPIResultオブジェクトをresultプロパティ内に受け取ります。requestDidFail:はエラーの情報が含まれるAIErrorオブジェクトをerrorプロパティ内に受け取ります。

    通常のクラス宣言からdelegateクラスを作成するには、AIAuthenticationDelegate.hをインポートして、クラスヘッダーファイルの宣言にプロトコルを追加します。

    #import <LoginWithAmazon/LoginWithAmazon.h>
    
    @interface AMZNGetProfileDelegate : NSObject<AIAuthenticationDelegate>
    
    @end
    
  5. requestDidSucceed:AMZNAuthorizeUserDelegateに対して実装します。

    requestDidSucceed:で、getProfile:を呼び出してユーザープロファイルを受け取ります。getProfile:は、authorizeUserForScopes:delegate:と同じように、AIAuthenticationDelegateプロトコルを使用します。

    - (void)requestDidSucceed:(APIResult *)apiResult {
        // リクエストされたスコープに対してユーザーがアプリを認可した後の
        // コード。
    
        // ユーザーのログインに成功したため、
        // ユーザーを特定する情報とともに新しいビューコントローラーを読み込む。
    
        AMZNGetProfileDelegate* delegate =
            [[[AMZNGetProfileDelegate alloc]
              initWithParentController:parentViewController] autorelease];
        [AIMobileLib getProfile:delegate];
    }
    

    delegate実装ヘッダーをgetProfile:を呼び出しているクラスに実装します。次に例を示します。

    #import "AMZNGetProfileDelegate.h"
    
  6. requestDidSucceed:AMZNGetProfileDelegateに対して実装します。

    requestDidSucceed:には主に、APIResultからプロファイルデータを取得することと、そのデータをUIに渡すことの2つのタスクがあります。

    APIResultからプロファイルデータを取得するには、resultプロパティにアクセスします。getProfile:レスポンスの場合、そのプロパティには、ユーザープロファイルプロパティのプロパティ値の辞書が含まれます。プロファイルプロパティは、profileスコープについてはnameemail、および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"];
    
        // データをビューコントローラーに渡す
    }
    
  7. requestDidFail:AMZNGetProfileDelegateに対して実装します。requestDidFail:にはエラーの情報を含むAPIErrorオブジェクトなどが入ります。showLogInPageは、Login with Amazonボタンを表示するためにメインビューコントローラーをリセットする仮想メソッドです。

    - (void)requestDidFail:(APIError *)errorResponse {
        // profileスコープに対するプロファイル取得リクエストに失敗。
    
        // エラーコード = 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. requestDidFail:AMZNAuthorizeUserDelegateに対して実装します。

    - (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. application:openURL:sourceApplication:annotation:UIApplicationDelegateプロトコルを処理するプロジェクトのクラスに実装します(デフォルトでは、プロジェクトのAppDelegateクラスになります)。Safariブラウザに表示されたAmazonログインページでユーザーがログインを完了すると、アプリに事前に登録していたURLスキームによってブラウザがリダイレクトされ、アプリが表示されます。そのリダイレクトはapplication:openURL:sourceApplication:annotation:に渡され、URLが正常に処理された場合にYESを返します。handleOpenURL:sourceApplication:は、Login with AmazonのリダイレクトURLを処理するSDKライブラリ関数です。handleOpenURL:sourceApplication:YESを返す場合、URLは処理されたことになります。

    - (BOOL)application:(UIApplication *)application
      openURL:(NSURL *)url
      sourceApplication:(NSString *)sourceApplication
      annotation:(id)annotation
    {
        // URLをSDKに渡して、URLからの認可コードを解析。
        BOOL isValidRedirectSignInURL =
          [AIMobileLib handleOpenURL:url sourceApplication:sourceApplication];
    
        if(!isValidRedirectSignInURL)
            return NO;
    
        // アプリはURLも処理
        return YES;
    }
    

起動時のユーザーログインの確認

アプリにログインしたユーザーが、アプリをいったん終了した後で再度アプリを起動させた場合、アプリは引き続きデータを取得できます。ユーザーが自動的にログアウトされることはありません。起動時にアプリが認可されていれば、ユーザーにログイン後の状態を表示できます。このセクションでは、getAccessTokenForScopes:withOverrideParams:delegate:を使用して、アプリがまだ認可されているかどうかを確認する方法について説明します。

  1. AMZNGetAccessTokenDelegateクラスを作成します。

    AMZNGetAccessTokenDelegateAIAuthenticationDelegateプロトコルを実装し、getAccessTokenForScopes:withOverrideParams:delegate:呼び出しの結果を処理します。AIAuthenticationDelegateにはrequestDidSucceed:requestDidFail:の2つのメソッドが入ります。requestDidSucceed:APIResultオブジェクトとトークンデータを受け取り、requestDidFail:APIErrorオブジェクトとエラーに関する情報を受け取ります。

    #import <LoginWithAmazon/LoginWithAmazon.h>
    
    @interface AMZNGetAccessTokenDelegate : NSObject<AIAuthenticationDelegate>
    
    @end
    

    delegate実装ヘッダーを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. requestDidSucceed:AMZNGetAccessTokenDelegateに実装します。

    requestDidSucceed:のタスクは1つで、getProfile:を呼び出すことです。この例は、前のセクション(手順6から8を参照)で宣言したものと同じリスナーを使用してgetProfile:を呼び出します。

    #import "AMZNGetProfileDelegate.h"
    #import <LoginWithAmazon/LoginWithAmazon.h>
    
    - (void)requestDidSucceed:(APIResult *)apiResult {
        // アクセストークンを使用するコードをここに挿入。
    
        // アプリがスコープを認可しているためユーザープロファイルを
        // 取得できる。
        AMZNGetProfileDelegate* delegate = [[[AMZNGetProfileDelegate alloc]
          initWithParentController:parentViewController] autorelease];
    
        [AIMobileLib getProfile:delegate];
    }
    
  4. requestDidFail:AMZNGetAccessTokenDelegateに実装します。requestDidFail:にはエラーの情報を含むAPIErrorオブジェクトなどが入ります。エラーが返された場合は、メインビューコントローラーをリセットして [Login with Amazon] ボタンを表示することができます。

    - (void)requestDidFail:(APIError *)errorResponse {
        // アクセストークンの取得失敗を処理するコード。
    
        // エラーコード = 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>
    
    delegate実装ヘッダーを`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:@"ユーザーがログアウトしました。"
            delegate:nil cancelButtonTitle:@"OK"otherButtonTitles:nil] show];
    }
    
  4. requestDidFail:を実装します。このメソッドは、何らかの理由でユーザーの情報をキャッシュから消去できない場合に呼び出されます。その場合、ログアウトした状態が表示されないようにする必要があります。

    - (void)requestDidFail:(APIError *)errorResponse {
    
        // SDKが認可状態の消去に失敗した後の
        // 追加のロジック。
    
        [[[[UIAlertView alloc] initWithTitle:@"" message:[NSString
          stringWithFormat:@"ユーザーのログアウトは次の理由で失敗しました: %@",
          errorResponse.error.message] delegate:nil
          cancelButtonTitle:@"OK" otherButtonTitles:nil]
          autorelease] show];
    }
    

    統合のテスト

iOSデバイスまたはシミュレーターでアプリを起動し、Amazon.comの認証情報を使用してログインできることを確認します。