Apple

Minimum SDK version: 2.0.0

This article guides you through the following scenarios in setting up authentication for players in your game with an Apple account:

  • Set up an Apple sign-in.
  • Sign in a returning user or create new user.
  • Update a user from an anonymous sign-in to a platform sign-in via an Apple account.

Important: The sign-in with Apple support in the Unity Authentication SDK only works with a single Bundle ID with the ID token from the iOS platform. It doesn't support Apple sign-in for players using Service ID and auth code from the Android platform.

To provide an Apple sign-in option for the players in your game, set up your app to enable sign-in with Apple.

Note: The code example below assumes you already have the player's Apple ID Token.

Set up an Apple sign-in

  1. Set up your app to enable sign-in with Apple. Note: Unity Authentication only supports Bundle ID based sign-in. Service ID is not supported.
  2. Configure your ID provider to be Apple for Unity Authentication:
    1. In the Unity Editor menu, go to Edit > Project Settings…, then select Services > Authentication from the navigation menu.
    2. Set ID Providers to Sign-in with Apple, then select Add.
    3. Enter the Bundle ID from the Apple developer console, in the App ID text field, then select Save. The Bundle ID should look like this: com.something.somethingelse.
  3. To integrate sign-in with Apple within your Unity project, we recommend leveraging an SDK library package from the Unity Asset Store. One example is Sign in with the Apple Unity Plugin.
    1. To install, follow the steps in the documentation of the package.
    2. Note: The referenced package is not developed, owned, or operated by Unity. Refer to our best practices for working with non-Unity packages.
    3. The below code snippet shows how you can leverage this example package within your Unity project to enable Apple sign-in.
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

You can use the SignInWithAppleAsync method to either:

  • Create a new Unity Authentication player with the Apple credentials.
  • Sign in an existing player using the Apple credentials.

If no Unity Authentication player in your project is associated with the credentials, SignInWithAppleAsync creates a new player. If a Unity Authentication player in your project is associated with the credentials, SignInWithAppleAsync signs into that player's account. This function doesn't consider the cached player, and SignInWithAppleAsync replaces the cached player.

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);
    }
}

Update a player from anonymous to an Apple account

After you’ve set up anonymous authentication, if an anonymous player wants to upgrade to creating an Apple account, then sign in using Apple, your game should prompt the player to trigger the Apple sign-in and get the ID token from Apple. Then, call the LinkWithAppleAsync API to link the player to the Apple ID token.

If a cached player exists on the SDK, you can link the cached player to the Apple Account.

  1. Sign into the cached player's account using SignInAnonymouslyAsync.
  2. Link the cached player's account to the Apple account with LinkWithAppleAsync.

For more information about cached players, refer to Sign In a Cached User.

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);
    }
}

When the player triggers the Apple sign in by signing in or by creating a new player profile, and you have received the Apple ID token, call the following API to authenticate the player.

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);
    }
}

Implement an Apple sign-in authentication

When the player triggers the Apple sign in by signing in or by creating a new player profile, and you have received the Apple ID token, call the following API to authenticate the player: SignInWithAppleAsync(string idToken).

Use the UnlinkAppleAsync API so your players can unlink their Apple account. Once unlinked, if their account isn’t linked to any additional identity, it transitions to an anonymous account.

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);
   }
}