Appearance
Appearance
Sign in with Apple allows users to login with their Apple ID accounts. Sign in with Apple is a cross platform identity provider, and is required for iOS platforms if any other third-party login system is used in the game.
To use Sign in with Apple, you need to:
Configure Sign in with Apple in the Apple developer portal.
Follow the instructions at https://help.apple.com/developer-account/?lang=en#/devde676e696.
Configure the Game Server to accept and validate Sign in with Apple requests.
In the relevant Options.<env>.yaml
, set:
AppleStore:
EnableAppleAuthentication: true
IosBundleId: <bundle id of the app>
Implement the client side logic.
In game UI, allow players to login and logout. After a successful login, send a SocialAuthenticationClaimSignInWithApple
request.
On app launch, check if we are still logged in on this device.
// savedUserID, savedUserToken from persistent storage, like KeyChain
BOOL isLoggedInToApple = FALSE;
if (savedUserID != nil)
{
ASAuthorizationAppleIDProvider* provider = [[ASAuthorizationAppleIDProvider alloc] init];
[provider getCredentialStateForUserID:savedUserID completion:
^(ASAuthorizationAppleIDProviderCredentialState credentialState, NSError *error)
{
isLoggedInToApple = (credentialState == ASAuthorizationAppleIDProviderCredentialAuthorized);
}];
}
On session start, check if the logged in Sign-in With Apple account is the same as what we are already using.
if (isLoggedInToApple == false)
{
// Show Sign in with Apple in the UI
}
else
{
var expectedKey = new AuthenticationKey(AuthenticationPlatform.SignInWithApple, savedUserID)
if (!playerModel.AttachedAuthMethods.ContainsKey(expectedKey))
{
// Device is logged in but not attached to game yet. Attach immediately.
SignInWithAppleLoggedIn(savedUserID, savedUserToken)
}
}
On user UI action, login.
ASAuthorizationAppleIDProvider* provider = [[ASAuthorizationAppleIDProvider alloc] init];
ASAuthorizationAppleIDRequest* request = [provider createRequest];
// No need for any scopes, not setting requestedScopes
// No need for state. Only one request in flight at a time
// No need for nonce. Replay protection is handled on transport layer
ASAuthorizationController* controller = [[ASAuthorizationController alloc] initWithAuthorizationRequests: @[request]]
controller.delegate = authDelegate
[controller performRequests]
// In our auth delegate
- (void)authorizationController:(ASAuthorizationController *)controller
didCompleteWithAuthorization:(ASAuthorization *)authorization
{
ASAuthorizationAppleIDCredential* appleIdCreds = (ASAuthorizationAppleIDCredential*)authorization.credential;
savedUserID = appleIdCreds.user;
savedUserToken = appleIdCreds.identityToken;
// Save savedUserID, savedUserToken to persistent storage, like KeyChain
SignInWithAppleLoggedIn(appleIdCreds.user, appleIdCreds.identityToken)
}
- (void)authorizationController:(ASAuthorizationController *)controller
didCompleteWithError:(NSError *)error
{
// handle error
}
Race Condition Warning
Native completion handlers are not executed on the Unity thread. Proper synchronization is required when delivering the result to Unity Thread.
Handle passing the pending login state to the Game Server:
void OnSignInWithAppleLoggedIn(user, identityToken)
{
var claim = new SocialAuthenticationClaimSignInWithApple(user, identityToken);
MetaplaySDK.MessageDispatcher.SendMessage(new SocialAuthenticateRequest(claim))
}
As with Game Center WWDC2020, the player IDs in Sign in with Apple are Scoped to the the app's Apple Development Team ID. This means their value depends on the team ID of the app. If the app is transferred from one team to another, the player ID's no longer match and existing Sign in with Apple authentication records are lost.
After this even, when a player logs in to the game with their Sign in with Apple account, either of the following happens (assuming state management is implemented as defined earlier in this document):
If the player has played the game with their current device, the authentication record is refreshed and there are no visible changes to the player.
If the player has not played the game with their current device, or has uninstalled the game, their new Sign in with Apple authentication key cannot be used to find their existing account. The Player will see that their existing account was not restored, and a new account is created instead. The new account uses a refreshed authentication token.
If the player now opens the game on a device that has used to play the game, an account conflict will occur. Upon resolution, the old or the new account will be orphaned.
💡 Pro tip
Lost authentication records could be restored by using unauthenticated, unsafe GamePlayerId
but this mode of operation is not yet implemented in Metaplay SDK. Contact us for more information.