# Apple

> Provide an Apple sign-in option to enable players to authenticate using their Apple accounts on iOS and macOS.

###### 最小 SDK バージョン: 2.0.0##minimum-sdk-version-200

このセクションでは、Apple アカウントを使用してゲーム内でのプレイヤーの認証を設定する以下のシナリオについて説明します。

* Apple サインインを設定する。
* 戻ってきたプレイヤーをサインインする、または新しいプレイヤーを作成する。
* 匿名ログインから Apple アカウントを介したプラットフォームログインへとプレイヤーを更新する。

> **Warning:**
>
> **重要**: Unity Authentication SDK の Apple サインインサポートは、iOS プラットフォームからの ID トークンを持つ単一のバンドル ID でのみ機能します。Android プラットフォームからの Service ID (サービス ID) と認証コードを使用するプレイヤーについては、Apple サインインはサポートされていません。

ゲーム内のプレイヤーに Apple サインインのオプションを提供するには、アプリケーションを設定して Apple でのサインインを有効にしてください。

> **Note:**
>
> **ノート**: 以下のコード例は、プレイヤーの Apple ID トークンをすでに取得済みであることを前提としています。

## Apple サインインを設定する##set-up-an-apple-sign-in

1. アプリケーションを設定して [Apple でのサインインを有効にします](https://developer.apple.com/help/account/)。**ノート**:Unity Authentication では **Bundle ID** (バンドル ID) ベースのサインインのみをサポートしています。Service ID (サービス ID) はサポートされていません。
2. Unity Authentication について、ID プロバイダーを Apple に設定します。
   1. Unity エディターメニューで、**Edit** (編集) > **Project Settings...** (プロジェクト設定...) を選択し、ナビゲーションメニューから **Services** (サービス) > **Authentication** を選択します。
   2. **ID Providers** (ID プロバイダー) を **Sign-in with Apple** (Apple でサインイン) に設定し、**Add** (追加) を選択します。
   3. Apple 開発者コンソールからの **バンドル ID** を **App ID** (アプリ ID) テキストフィールドに入力し、**Save** (保存) を選択します。バンドル ID は次のようになります: **com.something.somethingelse**。
3. Unity プロジェクト内で Apple サインインを統合するには、Unity Asset Store からの SDK ライブラリパッケージを利用することをお勧めします。例としては、[Sign in with the Apple Unity Plugin](https://assetstore.unity.com/packages/tools/integration/sign-in-with-apple-unity-plugin-152088) があります。
   1. インストールするには、パッケージのドキュメントに記載された [手順](https://github.com/lupidan/apple-signin-unity#perform-sign-in-with-apple) に従ってください。
   2. ノート: 参照先のパッケージは、Unity によって開発、所有、運営されているものではありません。非 Unity パッケージの扱いについては、Unity の ベストプラクティス を参照してください。
   3. 以下のコードスニペットは、上記の参考パッケージを Unity プロジェクト内で利用して、Apple サインインを有効にする方法を示したものです。

```cs
using System.Text;
using UnityEngine;

// External dependencies
using AppleAuth;
using AppleAuth.Enums;
using AppleAuth.Interfaces;
using AppleAuth.Native;

public class AppleExampleScript : MonoBehaviour
{
    IAppleAuthManager m_AppleAuthManager;
    public string Token { get; private set; }
    public string Error { get; private set; }

    public void Initialize()
    {
        var deserializer = new PayloadDeserializer();
        m_AppleAuthManager = new AppleAuthManager(deserializer);
    }

   public void Update()
   {
      if (m_AppleAuthManager != null) 
      {
         m_AppleAuthManager.Update();
      }
   }

    public void LoginToApple()
    {
        // Initialize the Apple Auth Manager
        if (m_AppleAuthManager == null)
        {
            Initialize();
        }

        // Set the login arguments
        var loginArgs = new AppleAuthLoginArgs(LoginOptions.IncludeEmail | LoginOptions.IncludeFullName);

        // Perform the login
        m_AppleAuthManager.LoginWithAppleId(
            loginArgs,
            credential =>
            {
                var appleIDCredential = credential as IAppleIDCredential;
                if (appleIDCredential != null)
                {
                    var idToken = Encoding.UTF8.GetString(
                        appleIDCredential.IdentityToken,
                        0,
                        appleIDCredential.IdentityToken.Length);
                    Debug.Log("Sign-in with Apple successfully done. IDToken: " + idToken);
                    Token = idToken;
                }
                else
                {
                    Debug.Log("Sign-in with Apple error. Message: appleIDCredential is null");
                    Error = "Retrieving Apple Id Token failed.";
                }
            },
            error =>
            {
                Debug.Log("Sign-in with Apple error. Message: " + error);
                Error = "Retrieving Apple Id Token failed.";
            }
        );
    }
}
```

## 戻ってきたプレイヤーのサインインまたは新しいプレイヤーの作成##sign-in-a-returning-player-or-create-new-player

`SignInWithAppleAsync` メソッドを使用して、以下のいずれかを行うことができます。

* Apple の認証情報を使用して新しい Unity Authentication プレイヤーを作成する。
* Apple の認証情報を使用して既存のプレイヤーをサインインする。

プロジェクト内の Unity Authentication プレイヤーが認証情報と関連付けられていない場合、`SignInWithAppleAsync` は新しいプレイヤーを作成します。プロジェクト内の Unity Authentication プレイヤーが認証情報と関連付けられている場合、`SignInWithAppleAsync` はそのプレイヤーのアカウントにサインインします。この関数ではキャッシュされたプレイヤーは考慮されません。`SignInWithAppleAsync` はキャッシュされたプレイヤーを置き換えます。

```cs
async Task SignInWithAppleAsync(string idToken)
{
    try
    {
        await AuthenticationService.Instance.SignInWithAppleAsync(idToken);
        Debug.Log("SignIn is successful.");
    }
    catch (AuthenticationException ex)
    {
        // Compare error code to AuthenticationErrorCodes
        // Notify the player with the proper error message
        Debug.LogException(ex);
    }
    catch (RequestFailedException ex)
    {
        // Compare error code to CommonErrorCodes
        // Notify the player with the proper error message
        Debug.LogException(ex);
    }
}
```

## プレイヤーを匿名から Apple アカウントへと更新する##update-a-player-from-anonymous-to-an-apple-account

匿名認証を設定した後、匿名のプレイヤーがアップグレードして Apple アカウントを作成することを希望する場合は、ゲームのプレイヤーにプロンプトを表示し、Apple サインインをトリガーして Apple から ID トークンを取得するように求める必要があります。その後、`LinkWithAppleAsync` API を呼び出して、プレイヤーを Apple ID トークンにリンクします。

キャッシュされたプレイヤーが SDK に存在する場合は、キャッシュされたプレイヤーを Apple アカウントにリンクできます。

1. `SignInAnonymouslyAsync` を使用して、キャッシュされたプレイヤーのアカウントにサインインします。
2. `LinkWithAppleAsync` を使用して、キャッシュされたプレイヤーのアカウントを Apple アカウントにリンクします。

```cs
async Task LinkWithAppleAsync(string idToken)
{
    try
    {
        await AuthenticationService.Instance.LinkWithAppleAsync(idToken);
        Debug.Log("Link is successful.");
    }
    catch (AuthenticationException ex) when (ex.ErrorCode == AuthenticationErrorCodes.AccountAlreadyLinked)
    {
        // Prompt the player with an error message.
        Debug.LogError("This user is already linked with another account. Log in instead.");
    }
    catch (AuthenticationException ex)
    {
        // Compare error code to AuthenticationErrorCodes
        // Notify the player with the proper error message
        Debug.LogException(ex);
    }
    catch (RequestFailedException ex)
    {
        // Compare error code to CommonErrorCodes
        // Notify the player with the proper error message
        Debug.LogException(ex);
    }
}
```

プレイヤーが、サインインまたは新しいプレイヤープロファイルの作成によって Apple サインインをトリガーする場合、Apple ID トークンを受け取ったら、以下の API を呼び出してプレイヤーの認証を行います。

```cs
async Task SignInWithAppleAsync(string idToken)
{
    try
    {
        await AuthenticationService.Instance.SignInWithAppleAsync(idToken);
        Debug.Log("SignIn is successful.");
    }
    catch (AuthenticationException ex)
    {
        // Compare error code to AuthenticationErrorCodes
        // Notify the player with the proper error message
        Debug.LogException(ex);
    }
    catch (RequestFailedException ex)
    {
        // Compare error code to CommonErrorCodes
        // Notify the player with the proper error message
        Debug.LogException(ex);
    }
}
```

## Apple サインイン認証を実装する##unlink-apple-account

プレイヤーが、サインインまたは新しいプレイヤープロファイルの作成によって Apple サインインをトリガーする場合、Apple ID トークンを受け取ったら、以下の API を呼び出してプレイヤーの認証を行います: `SignInWithAppleAsync(string idToken).`

## Apple アカウントのリンク解除

`UnlinkAppleAsync` API を使用して、プレイヤーが自身の Apple アカウントをリンク解除できるようにします。リンク解除後、そのアカウントが他のどの ID にもリンクされていない場合、そのアカウントは匿名アカウントに遷移します。

```cs
async Task UnlinkAppleAsync(string idToken)
{
   try
   {
       await AuthenticationService.Instance.UnlinkAppleAsync(idToken);
       Debug.Log("Unlink is successful.");
   }
   catch (AuthenticationException ex)
   {
       // Compare error code to AuthenticationErrorCodes
       // Notify the player with the proper error message
       Debug.LogException(ex);
   }
   catch (RequestFailedException ex)
   {
       // Compare error code to CommonErrorCodes
       // Notify the player with the proper error message
       Debug.LogException(ex);
   }
}
```
