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:
リスナーを作成することが含まれます。
-
ソースファイルにLogin with Amazon APIをインポートします。Login with Amazon APIをインポートするには、ソースファイルに次の
#import
ステートメントを追加します。#import <LoginWithAmazon/LoginWithAmazon.h>
-
AMZNAuthorizeUserDelegate
クラスを作成して、AIAuthenticationDelegate
を実装します。authorizeUserForScopes:delegate:
が完了すると、requestDidSucceed:
メソッドまたはrequestDidFail:
メソッドを呼び出し、AIAuthenticationDelegate
プロトコルを実装します。@interface AMZNAuthorizeUserDelegate : NSObject<AIAuthenticationDelegate> @end
詳細については、developer.apple.comのWorking with Protocols(プロトコルの使用)を参照してください。
-
authorizeUserForScopes:delegate:
をonLoginButtonClicked
で呼び出します。アプリに [Login with Amazon] ボタンを追加するの手順を実行していれば、
onLoginButtonClicked:
メソッドが [Login with Amazon] ボタンにリンクされているはずです。そのメソッドでauthorizeUserForScopes:delegate:
を呼び出して、ユーザーにログインとアプリの認可を求める画面を表示します。この場合、ユーザーは次のいずれかの方法でサインインとリクエストされた情報への同意を行うことができます。
- 安全なコンテキストでウェブ表示に切り替える(デバイスにAmazonショッピングアプリがインストールされている場合)
- Safari View Controllerに切り替える(iOS 9以降)
- システムブラウザに切り替える(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]; }
authorizeUserForScopes:
を呼び出しているクラスにdelegate実装ヘッダーを追加します。次に例を示します。#import "AMZNAuthorizeUserDelegate.h"
-
AMZNGetProfileDelegate
を作成します。AMZNGetProfileDelegate
はAIAuthenticationDelegate
プロトコルを実装するクラスの名前で、getProfile:
呼び出しの結果を処理します。authorizeUserForScopes:delegate:
と同じように、getProfile:
はrequestDidSucceed:
プロトコルとrequestDidFail:
プロトコルのメソッドをサポートします。requestDidSucceed:
は、プロファイルデータが含まれるAPIResult
オブジェクトをresult
プロパティ内に受け取ります。requestDidFail:
は、エラーの情報が含まれるAIError
オブジェクトをerror
プロパティ内に受け取ります。通常のクラス宣言からdelegateクラスを作成するには、
AIAuthenticationDelegate.h
をインポートして、クラスヘッダーファイルの宣言にプロトコルを追加します。#import <LoginWithAmazon/LoginWithAmazon.h> @interface AMZNGetProfileDelegate : NSObject<AIAuthenticationDelegate> @end
-
requestDidSucceed:
をAMZNAuthorizeUserDelegate
に実装します。requestDidSucceed:
で、getProfile:
を呼び出してユーザープロファイルを受け取ります。getProfile:
は、authorizeUserForScopes:delegate:
と同じように、AIAuthenticationDelegate
プロトコルを使用します。- (void)requestDidSucceed:(APIResult *)apiResult { // リクエストされたスコープに対してユーザーがアプリを認可した後の // コード。 // ユーザーのログインに成功したため、 // ユーザーを特定する情報とともに新しいビューコントローラーを読み込む。 AMZNGetProfileDelegate* delegate = [[[AMZNGetProfileDelegate alloc] initWithParentController:parentViewController] autorelease]; [AIMobileLib getProfile:delegate]; }
getProfile:
を呼び出しているクラスにdelegate実装ヘッダーを追加します。次に例を示します。#import "AMZNGetProfileDelegate.h"
-
requestDidSucceed:
をAMZNGetProfileDelegate
に実装します。requestDidSucceed:
には主に、APIResult
からプロファイルデータを取得することと、そのデータをUIに渡すことの2つのタスクがあります。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"]; // データをビューコントローラーに渡す }
-
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:@"次の理由でエラーが発生しました: %@", errorResponse.error.message] delegate:nil cancelButtonTitle:@"OK"otherButtonTitles:nil] autorelease] show]; } }
-
requestDidFail:
をAMZNAuthorizeUserDelegate
に実装します。- (void)requestDidFail:(APIError *)errorResponse { NSString *message = errorResponse.error.message; // 認可に失敗したときのコード。 [[[[UIAlertView alloc] initWithTitle:@"" message:[NSString stringWithFormat:@"ユーザーの認可は次の理由で失敗しました: %@", errorResponse.error.message] delegate:nil cancelButtonTitle:@"OK"otherButtonTitles:nil] autorelease] show]; }
-
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; }
注: このメソッドはiOS 9で廃止されていますが、旧バージョンのプラットフォームを使用するユーザーに継続して対応するためにプロジェクトに取り込む必要があります。application:openURL:sourceApplication:annotation:
の詳細については、developer.apple.comのUIApplicationDelegateプロトコルのリファレンスを参照してください。
起動時のユーザーログインの確認
アプリにログインしたユーザーが、アプリをいったん終了した後で再度アプリを起動させた場合、アプリは引き続きデータを取得できます。ユーザーが自動的にログアウトされることはありません。起動時にアプリが認可されていれば、ユーザーにログイン後の状態を表示できます。このセクションでは、getAccessTokenForScopes:withOverrideParams:delegate:
を使用して、アプリがまだ認可されているかどうかを確認する方法について説明します。
-
AMZNGetAccessTokenDelegate
クラスを作成します。AMZNGetAccessTokenDelegate
はAIAuthenticationDelegate
プロトコルを実装し、getAccessTokenForScopes:withOverrideParams:delegate:
呼び出しの結果を処理します。AIAuthenticationDelegate
にはrequestDidSucceed:
とrequestDidFail:
の2つのメソッドがあります。requestDidSucceed:
はAPIResult
オブジェクトとトークンデータを受け取り、requestDidFail:
はAPIError
オブジェクトとエラーに関する情報を受け取ります。#import <LoginWithAmazon/LoginWithAmazon.h> @interface AMZNGetAccessTokenDelegate : NSObject<AIAuthenticationDelegate> @end
getAccessTokenForScopes:withOverrideParams:delegate:
を呼び出しているクラスにdelegate実装ヘッダーを追加します。次に例を示します。#import "AMZNGetAccessTokenDelegate.h"
-
アプリの起動時に
getAccessTokenForScopes:withOverrideParams:delegate:
を呼び出し、アプリがまだ認可されているかどうかを確認します。getAccessTokenForScopes:withOverrideParams:delegate:
は未処理のアクセストークンを受け取り、Login with Amazonはそれを使用してユーザープロファイルにアクセスします。このメソッドが正常に処理された場合、アプリはまだ認可されており、getProfile:
の呼び出しに成功します。getAccessTokenForScopes:withOverrideParams:delegate:
は、authorizeUserForScopes:delegate:
と同じようにAIAuthenticationDelegate
プロトコルを使用します。このプロトコルを実装しているオブジェクトを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]; }
-
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]; }
-
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:@"次の理由でエラーが発生しました: %@", 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> delegate実装ヘッダーを`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:@"ユーザーがログアウトしました。" delegate:nil cancelButtonTitle:@"OK"otherButtonTitles:nil] show]; }
-
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の認証情報を使用してログインできることを確認します。
authorizeUserForScopes
リクエストに対して表示されたり、「Unknown Error Code」がclearAuthorizationState
リクエストに対して表示されたりする場合があります。これは、SDKがキーチェーンにアクセスするときに発生するAppleの既知のバグです。Appleがバグを解決するまで、アプリのターゲットの [Capabilities] タブでアプリの [Keychain Sharing] を有効にすることで問題に対応してください。このバグの影響を受けるのはシミュレーターのみです。実際のiOS10デバイスでテストをする場合は、こうした回避策は必要ありません。