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> @endgetAccessTokenForScopes: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デバイスでテストをする場合は、こうした回避策は必要ありません。
