### Install via Git URL for Unity Package Manager Source: https://github.com/lupidan/apple-signin-unity/blob/master/Source/README.md Add this line to the 'Packages/manifest.json' file of your Unity Project to install the plugin via Git URL. This method is available starting from Unity 2020.3. ```json { "dependencies": { "com.lupidan.apple-signin-unity": "https://github.com/lupidan/apple-signin-unity.git?path=Source#1.5.0" } } ``` -------------------------------- ### Initialize Apple Authentication Manager (C#) Source: https://github.com/lupidan/apple-signin-unity/blob/master/Source/README.md Demonstrates how to initialize the IAppleAuthManager in a Unity project. It checks for platform support and creates a default JSON deserializer to handle native responses. This code should be called during the application's start. ```csharp private IAppleAuthManager appleAuthManager; void Start() { ... // If the current platform is supported if (AppleAuthManager.IsCurrentPlatformSupported) { // Creates a default JSON deserializer, to transform JSON Native responses to C# instances var deserializer = new PayloadDeserializer(); // Creates an Apple Authentication manager with the deserializer this.appleAuthManager = new AppleAuthManager(deserializer); } ... } void Update() { ... // Updates the AppleAuthManager instance to execute // pending callbacks inside Unity's execution loop if (this.appleAuthManager != null) { this.appleAuthManager.Update(); } ... } ``` -------------------------------- ### Configure Xcode for Apple Sign In (iOS/tvOS) - C# Source: https://context7.com/lupidan/apple-signin-unity/llms.txt Automatically adds the Sign in with Apple capability to the Xcode project during the post-build process for iOS and tvOS. This involves reading the project file, obtaining the target GUID, and using ProjectCapabilityManager to add the capability. Requires UnityEditor, UnityEditor.Callbacks, UnityEditor.iOS.Xcode, AppleAuth.Editor, and System.IO namespaces. ```csharp using UnityEditor; using UnityEditor.Callbacks; using UnityEditor.iOS.Xcode; using AppleAuth.Editor; using System.IO; public static class SignInWithApplePostprocessor { [PostProcessBuild(1)] public static void OnPostProcessBuild(BuildTarget target, string path) { if (target != BuildTarget.iOS && target != BuildTarget.tvOS) return; // Get Xcode project path string projectPath = PBXProject.GetPBXProjectPath(path); // Read project PBXProject project = new PBXProject(); project.ReadFromString(File.ReadAllText(projectPath)); // Add Sign in with Apple capability string targetGuid = project.GetUnityMainTargetGuid(); ProjectCapabilityManager manager = new ProjectCapabilityManager( projectPath, "Entitlements.entitlements", null, targetGuid); // Extension method adds capability with AuthenticationServices.framework manager.AddSignInWithAppleWithCompatibility(); manager.WriteToFile(); Debug.Log("Added Sign in with Apple capability to Xcode project"); } } ``` -------------------------------- ### Update PBXProject for iOS Compatibility (Unity 2019.3+) Source: https://github.com/lupidan/apple-signin-unity/wiki/Migration-guides This code snippet demonstrates how to update the PBXProject to ensure compatibility with iOS for Unity versions 2019.3 and later. It modifies the AddSignInWithApple method to include compatibility for the Unity framework target GUID. ```csharp var project = new PBXProject(); project.ReadFromString(System.IO.File.ReadAllText(projectPath)); var manager = new ProjectCapabilityManager(projectPath, "Entitlements.entitlements", null, project.GetUnityMainTargetGuid()); manager.AddSignInWithAppleWithCompatibility(project.GetUnityFrameworkTargetGuid()); manager.WriteToFile(); ``` -------------------------------- ### C# Complete Apple Sign-In Flow for Unity Source: https://context7.com/lupidan/apple-signin-unity/llms.txt This C# script demonstrates a complete Apple Sign-In authentication flow within a Unity application. It handles initialization of the AppleAuthManager, checks for existing credentials, attempts a quick login, and provides a button click handler for initiating the full Apple ID sign-in process. It also includes callbacks for credential revocation and user account creation. ```csharp using AppleAuth; using AppleAuth.Native; using AppleAuth.Enums; using AppleAuth.Interfaces; using AppleAuth.Extensions; using UnityEngine; using System.Text; public class CompleteAuthFlow : MonoBehaviour { private const string AppleUserIdKey = "AppleUserId"; private IAppleAuthManager appleAuthManager; void Start() { // Initialize if (AppleAuthManager.IsCurrentPlatformSupported) { var deserializer = new PayloadDeserializer(); appleAuthManager = new AppleAuthManager(deserializer); // Setup revocation callback appleAuthManager.SetCredentialsRevokedCallback(HandleCredentialsRevoked); // Check for existing credentials if (PlayerPrefs.HasKey(AppleUserIdKey)) { ValidateExistingCredential(); } else { AttemptQuickLogin(); } } } void Update() { appleAuthManager?.Update(); } private void ValidateExistingCredential() { string userId = PlayerPrefs.GetString(AppleUserIdKey); appleAuthManager.GetCredentialState( userId, state => { if (state == CredentialState.Authorized) { LoginUser(userId); } else { PlayerPrefs.DeleteKey(AppleUserIdKey); ShowSignInButton(); } }, error => { Debug.LogError($"Credential validation error: {error.GetAuthorizationErrorCode()}"); ShowSignInButton(); }); } private void AttemptQuickLogin() { var quickLoginArgs = new AppleAuthQuickLoginArgs(); appleAuthManager.QuickLogin( quickLoginArgs, credential => { PlayerPrefs.SetString(AppleUserIdKey, credential.User); LoginUser(credential.User); }, error => { ShowSignInButton(); }); } public void OnSignInButtonClicked() { var loginArgs = new AppleAuthLoginArgs( LoginOptions.IncludeEmail | LoginOptions.IncludeFullName); appleAuthManager.LoginWithAppleId( loginArgs, credential => { var appleIdCredential = credential as IAppleIDCredential; if (appleIdCredential != null) { // Save user ID PlayerPrefs.SetString(AppleUserIdKey, appleIdCredential.User); // Get user information (first login only) string email = appleIdCredential.Email; IPersonName fullName = appleIdCredential.FullName; // Get tokens for backend string identityToken = Encoding.UTF8.GetString( appleIdCredential.IdentityToken); string authCode = Encoding.UTF8.GetString( appleIdCredential.AuthorizationCode); // Send to backend CreateUserAccount( appleIdCredential.User, email, fullName, identityToken, authCode); LoginUser(appleIdCredential.User); } }, error => { var errorCode = error.GetAuthorizationErrorCode(); Debug.LogError($"Sign in failed: {errorCode}"); if (errorCode == AuthorizationErrorCode.Canceled) { Debug.Log("User canceled sign in"); } }); } private void HandleCredentialsRevoked(string userId) { Debug.LogWarning($"Credentials revoked: {userId}"); PlayerPrefs.DeleteKey(AppleUserIdKey); LogoutAndShowLogin(); } private void LoginUser(string userId) { Debug.Log($"User logged in: {userId}"); // Load game scene } private void ShowSignInButton() { Debug.Log("Showing sign in button"); // Display UI } private void LogoutAndShowLogin() { Debug.Log("Logging out user"); // Return to login screen } private void CreateUserAccount(string id, string email, IPersonName name, string token, string code) { Debug.Log($"Creating account for {id} with email {email}"); // Backend API call } } ``` -------------------------------- ### Perform Sign In with Apple Request (C#) Source: https://github.com/lupidan/apple-signin-unity/blob/master/Source/README.md Shows how to initiate the Sign in With Apple flow and request user's email and full name. Note that this information is only available the first time a user logs in. The callback handles the obtained credential or any errors. ```csharp var loginArgs = new AppleAuthLoginArgs(LoginOptions.IncludeEmail | LoginOptions.IncludeFullName); this.appleAuthManager.LoginWithAppleId( loginArgs, credential => { // Obtained credential, cast it to IAppleIDCredential var appleIdCredential = credential as IAppleIDCredential; if (appleIdCredential != null) { // Apple User ID // You should save the user ID somewhere in the device var userId = appleIdCredential.User; PlayerPrefs.SetString(AppleUserIdKey, userId); // Email (Received ONLY in the first login) var email = appleIdCredential.Email; // Full name (Received ONLY in the first login) var fullName = appleIdCredential.FullName; // Identity token var identityToken = Encoding.UTF8.GetString( appleIdCredential.IdentityToken, 0, appleIdCredential.IdentityToken.Length); // Authorization code var authorizationCode = Encoding.UTF8.GetString( appleIdCredential.AuthorizationCode, 0, appleIdCredential.AuthorizationCode.Length); // And now you have all the information to create/login a user in your system } }, error => { // Something went wrong var authorizationErrorCode = error.GetAuthorizationErrorCode(); }); ``` -------------------------------- ### Login with No Options in Unity Source: https://github.com/lupidan/apple-signin-unity/blob/master/Source/README.md This C# code snippet demonstrates how to initiate the Apple Sign In process in Unity without requesting the user's email or full name. By passing `LoginOptions.None`, the user is not prompted for this information, leading to a smoother login experience. The success and error callbacks handle the results of the login attempt. ```csharp appleAuthManager.LoginWithAppleId(LoginOptions.None, credential => { /* Handle successful login */ }, error => { /* Handle login error */ }); ``` -------------------------------- ### Verify Binary Architectures Source: https://github.com/lupidan/apple-signin-unity/blob/master/Source/docs/macOS_NOTES.md These shell commands use `lipo` to verify the architecture compatibility of binaries within a macOS application. They check for x86_64 (Intel) and arm64 (Apple Silicon) architectures, essential for universal binaries. ```bash # If you are only targetting Intel only lipo BINARY_PATH -verify_arch x86_64 || { echo "Intel x86_64 architecture is missing"; exit 1; } ``` ```bash # If you are targetting both Apple Silicon and Intel (Universal Binary) lipo BINARY_PATH -verify_arch x86_64 || { echo "Intel x86_64 architecture is missing"; exit 1; } lipo BINARY_PATH -verify_arch arm64 || { echo "Apple Silicon amr64 architecture is missing"; exit 1; } ``` -------------------------------- ### Perform Quick Login with Apple Sign-In (C#) Source: https://github.com/lupidan/apple-signin-unity/blob/master/Source/docs/Firebase_NOTES.md Initiates a quick login flow with Apple Sign-In using the AppleAuth SDK. It generates a nonce, prepares the login arguments, and handles the callback for successful credential retrieval. This method is a prerequisite for Firebase authentication. ```csharp using System; using AppleAuth; using AppleAuth.Enums; using AppleAuth.Interfaces; using Firebase.Auth; public void PerformQuickLoginWithFirebase(Action firebaseAuthCallback) { var rawNonce = GenerateRandomString(32); var nonce = GenerateSHA256NonceFromRawNonce(rawNonce); var quickLoginArgs = new AppleAuthQuickLoginArgs(nonce); this.appleAuthManager.QuickLogin( quickLoginArgs, credential => { var appleIdCredential = credential as IAppleIDCredential; if (appleIdCredential != null) { this.PerformFirebaseAuthentication(appleIdCredential, rawNonce, firebaseAuthCallback); } }, error => { // Something went wrong }); } ``` -------------------------------- ### Update QuickLogin Method Arguments Source: https://github.com/lupidan/apple-signin-unity/wiki/Migration-guides The QuickLogin method now requires an instance of AppleAuthQuickLoginArgs to be passed as the first argument. This struct contains data related to the login intent, replacing the previous direct call. ```csharp this.QuickLogin(new AppleAuthQuickLoginArgs(), successCallback, errorCallback); ``` -------------------------------- ### Simplify AppleAuthManager Constructor Source: https://github.com/lupidan/apple-signin-unity/wiki/Migration-guides The AppleAuthManager constructor has been simplified, now only requiring the deserializer. The scheduler parameter has been removed as it's no longer needed. ```csharp this.appleAuthManager = new AppleAuthManager(deserializer); ``` -------------------------------- ### Apple Sign In Entitlements XML Configuration Source: https://github.com/lupidan/apple-signin-unity/blob/master/Source/docs/macOS_NOTES.md This XML snippet defines the necessary entitlements for an application to use Apple Sign In. It includes permissions for JIT, disabling page protection, and specifying the team and application identifiers. ```xml com.apple.security.cs.allow-jit com.apple.security.cs.disable-executable-page-protection com.apple.developer.applesignin Default com.apple.developer.team-identifier ABC123DEF4 com.apple.application-identifier ABC123DEF4.com.mycompany.mygame ``` -------------------------------- ### Open macOS Application Source: https://github.com/lupidan/apple-signin-unity/blob/master/Source/docs/macOS_NOTES.md This command opens the signed and provisioned macOS application. It's typically used after all signing and copying steps are completed to launch the application for testing. ```shell open ./AppleAuthSampleProject.app ``` -------------------------------- ### Perform Minimal Apple Sign-In Source: https://context7.com/lupidan/apple-signin-unity/llms.txt Implements a streamlined Apple Sign-In flow that does not request the user's email or full name, providing a smoother user experience. It retrieves only the user ID and identity token. Requires the AppleAuth SDK. ```csharp using AppleAuth; using AppleAuth.Enums; using AppleAuth.Interfaces; using System.Text; public void MinimalSignIn() { // Skip email and name request for smoother UX var loginArgs = new AppleAuthLoginArgs(LoginOptions.None); appleAuthManager.LoginWithAppleId( loginArgs, credential => { var appleIdCredential = credential as IAppleIDCredential; if (appleIdCredential != null) { // Only user ID and tokens available string userId = appleIdCredential.User; string identityToken = Encoding.UTF8.GetString( appleIdCredential.IdentityToken); // Email and FullName will be null Debug.Log($"Minimal sign in successful: {userId}"); AuthenticateWithBackend(userId, identityToken); } }, error => { Debug.LogError($"Minimal sign in failed: {error}"); }); } private void AuthenticateWithBackend(string id, string token) { /* Backend auth */ } ``` -------------------------------- ### Namespace Consolidation for AppleAuth Source: https://github.com/lupidan/apple-signin-unity/wiki/Migration-guides This code snippet illustrates the consolidation of several AppleAuth related namespaces into a single, more streamlined namespace. This change simplifies imports and organizes related functionalities. ```csharp using AppleAuth; using AppleAuth.Enums; using AppleAuth.Extensions; using AppleAuth.Interfaces; ``` -------------------------------- ### Unity App Codesigning and Verification Script (Bash) Source: https://github.com/lupidan/apple-signin-unity/blob/master/Source/docs/macOS_NOTES.md This bash script automates the codesigning process for a Unity-generated macOS application. It cleans up Unity meta files, verifies the presence of x86_64 and arm64 architectures using lipo, clears extended attributes, and prepares for codesigning. ```bash # Delete .meta files left by Unity in all the elements in the Plugins folder find ./AppleAuthSampleProject.app/Contents/Plugins/ -name "*.meta" -print0 | xargs -I {} -0 rm -v "{}" # Verify Intel architecture lipo ./AppleAuthSampleProject.app/Contents/Frameworks/MonoBleedingEdge/MonoEmbedRuntime/osx/libMonoPosixHelper.dylib -verify_arch x86_64 || { echo "Intel x86_64 architecture is missing"; exit 1; } lipo ./AppleAuthSampleProject.app/Contents/Frameworks/MonoBleedingEdge/MonoEmbedRuntime/osx/libmonobdwgc-2.0.dylib -verify_arch x86_64 || { echo "Intel x86_64 architecture is missing"; exit 1; } lipo ./AppleAuthSampleProject.app/Contents/Frameworks/UnityPlayer.dylib -verify_arch x86_64 || { echo "Intel x86_64 architecture is missing"; exit 1; } lipo ./AppleAuthSampleProject.app/Contents/Frameworks/libcrypto.dylib -verify_arch x86_64 || { echo "Intel x86_64 architecture is missing"; exit 1; } lipo ./AppleAuthSampleProject.app/Contents/Frameworks/libssl.dylib -verify_arch x86_64 || { echo "Intel x86_64 architecture is missing"; exit 1; } lipo ./AppleAuthSampleProject.app/Contents/Plugins/MacOSAppleAuthManager.bundle/Contents/MacOS/MacOSAppleAuthManager -verify_arch x86_64 || { echo "Intel x86_64 architecture is missing"; exit 1; } lipo ./AppleAuthSampleProject.app/Contents/MacOS/AppleAuthSampleProject -verify_arch x86_64 || { echo "Intel x86_64 architecture is missing"; exit 1; } # Verify Apple Silicon architecture (THIS IS ONLY REQUIRED IF YOU ARE BUILDING A UNIVERSAL BINARY) lipo ./AppleAuthSampleProject.app/Contents/Frameworks/MonoBleedingEdge/MonoEmbedRuntime/osx/libMonoPosixHelper.dylib -verify_arch arm64 || { echo "Apple Silicon amr64 architecture is missing"; exit 1; } lipo ./AppleAuthSampleProject.app/Contents/Frameworks/MonoBleedingEdge/MonoEmbedRuntime/osx/libmonobdwgc-2.0.dylib -verify_arch arm64 || { echo "Apple Silicon amr64 architecture is missing"; exit 1; } lipo ./AppleAuthSampleProject.app/Contents/Frameworks/UnityPlayer.dylib -verify_arch arm64 || { echo "Apple Silicon amr64 architecture is missing"; exit 1; } lipo ./AppleAuthSampleProject.app/Contents/Frameworks/libcrypto.dylib -verify_arch arm64 || { echo "Apple Silicon amr64 architecture is missing"; exit 1; } lipo ./AppleAuthSampleProject.app/Contents/Frameworks/libssl.dylib -verify_arch arm64 || { echo "Apple Silicon amr64 architecture is missing"; exit 1; } lipo ./AppleAuthSampleProject.app/Contents/Plugins/MacOSAppleAuthManager.bundle/Contents/MacOS/MacOSAppleAuthManager -verify_arch arm64 || { echo "Apple Silicon amr64 architecture is missing"; exit 1; } lipo ./AppleAuthSampleProject.app/Contents/MacOS/AppleAuthSampleProject -verify_arch arm64 || { echo "Apple Silicon amr64 architecture is missing"; exit 1; } # Clears extended attributes recursively xattr -crs ./AppleAuthSampleProject.app # Sign all the elements ``` -------------------------------- ### Copy Provisioning Profile Source: https://github.com/lupidan/apple-signin-unity/blob/master/Source/docs/macOS_NOTES.md This command copies the necessary development provisioning profile into the application bundle. This profile links the app to your Apple Developer account and enables specific capabilities. Ensure the file names match your project's provisioning profile. ```shell cp ./Sign_In_With_Apple_Tests_Development.provisionprofile ./AppleAuthSampleProject.app/Contents/embedded.provisionprofile ``` -------------------------------- ### Check Platform Support Statically Source: https://github.com/lupidan/apple-signin-unity/wiki/Migration-guides The check for platform support has moved from an instance method on AppleAuthManager to a static method. This allows checking support before instantiating the manager, potentially saving resources. ```csharp if (!AppleAuthManager.IsCurrentPlatformSupported) ``` -------------------------------- ### Codesign macOS Application with Entitlements Source: https://github.com/lupidan/apple-signin-unity/blob/master/Source/docs/macOS_NOTES.md This command signs the main application bundle, applying specific entitlements defined in a .entitlements file. This is crucial for enabling features like Sign in with Apple. Replace placeholder certificate and entitlement file paths with your project's specifics. ```shell codesign -vvv --force --timestamp --options runtime -s "Apple Development: My Full Name (ABCDEFGHIJ)" --entitlements ./Sign_In_With_Apple_Tests.entitlements ./AppleAuthSampleProject.app ``` -------------------------------- ### Conditional Manager Instantiation and Update Source: https://github.com/lupidan/apple-signin-unity/wiki/Migration-guides This snippet demonstrates a pattern for conditionally instantiating and updating the AppleAuthManager based on platform support. It first checks if the platform is supported before creating the manager and then ensures the manager is updated if it exists. ```csharp if (AppleAuthManager.IsCurrentPlatformSupported) { this.appleAuthManager = new AppleAuthManager(deserializer); } ... if (this.appleAuthManager != null) { this.appleAuthManager.Update(); } ``` -------------------------------- ### Secure Apple Sign-In with Nonce and State (C#) Source: https://context7.com/lupidan/apple-signin-unity/llms.txt This C# code implements a secure sign-in flow for Apple Authentication in Unity. It generates a random nonce and a state parameter to enhance security during authentication, which can be used for Firebase or server-side validation. The function takes no direct inputs but relies on an `appleAuthManager` instance and generates internal security parameters. It outputs user credentials and identity tokens upon successful authentication or an error message if it fails. ```csharp using AppleAuth; using AppleAuth.Enums; using AppleAuth.Interfaces; using System; using System.Security.Cryptography; using System.Text; public void SecureSignIn() { // Generate random nonce for security string rawNonce = GenerateRandomString(32); string nonce = GenerateSHA256Hash(rawNonce); // Generate state for request verification string state = Guid.NewGuid().ToString(); var loginArgs = new AppleAuthLoginArgs( LoginOptions.IncludeEmail | LoginOptions.IncludeFullName, nonce, state); appleAuthManager.LoginWithAppleId( loginArgs, credential => { var appleIdCredential = credential as IAppleIDCredential; if (appleIdCredential != null) { // Verify state matches if (appleIdCredential.State == state) { string identityToken = Encoding.UTF8.GetString( appleIdCredential.IdentityToken); // Identity token contains embedded nonce // Send to Firebase or backend with rawNonce SendToBackend(appleIdCredential.User, identityToken, rawNonce); } } }, error => { Debug.LogError($"Secure sign in failed: {error}"); }); } private string GenerateRandomString(int length) { const string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; var random = new System.Random(); return new string(Enumerable.Repeat(chars, length) .Select(s => s[random.Next(s.Length)]).ToArray()); } private string GenerateSHA256Hash(string input) { using (var sha256 = SHA256.Create()) { var bytes = Encoding.UTF8.GetBytes(input); var hash = sha256.ComputeHash(bytes); return BitConverter.ToString(hash).Replace("-", "").ToLower(); } } private void SendToBackend(string userId, string token, string nonce) { // Send to your backend or Firebase Debug.Log($"Authenticating user {userId} with token"); } ``` -------------------------------- ### Codesign macOS Application Frameworks and Plugins Source: https://github.com/lupidan/apple-signin-unity/blob/master/Source/docs/macOS_NOTES.md This command signs individual dynamic libraries and bundles within the macOS application using a specified developer certificate and runtime options. It ensures the integrity and authenticity of the application's components. Ensure you replace placeholder certificate names and file paths with your actual project details. ```shell codesign -vvv --force --timestamp --options runtime -s "Apple Development: My Full Name (ABCDEFGHIJ)" ./AppleAuthSampleProject.app/Contents/Frameworks/MonoBleedingEdge/MonoEmbedRuntime/osx/libMonoPosixHelper.dylib codesign -vvv --force --timestamp --options runtime -s "Apple Development: My Full Name (ABCDEFGHIJ)" ./AppleAuthSampleProject.app/Contents/Frameworks/MonoBleedingEdge/MonoEmbedRuntime/osx/libmonobdwgc-2.0.dylib codesign -vvv --force --timestamp --options runtime -s "Apple Development: My Full Name (ABCDEFGHIJ)" ./AppleAuthSampleProject.app/Contents/Frameworks/UnityPlayer.dylib codesign -vvv --force --timestamp --options runtime -s "Apple Development: My Full Name (ABCDEFGHIJ)" ./AppleAuthSampleProject.app/Contents/Frameworks/libcrypto.dylib codesign -vvv --force --timestamp --options runtime -s "Apple Development: My Full Name (ABCDEFGHIJ)" ./AppleAuthSampleProject.app/Contents/Frameworks/libssl.dylib codesign -vvv --force --timestamp --options runtime -s "Apple Development: My Full Name (ABCDEFGHIJ)" ./AppleAuthSampleProject.app/Contents/Plugins/MacOSAppleAuthManager.bundle ``` -------------------------------- ### Quick Apple Re-authentication (C#) Source: https://context7.com/lupidan/apple-signin-unity/llms.txt This C# code snippet demonstrates how to perform a quick re-authentication with Apple Sign-In in Unity. It attempts silent login using existing credentials stored in the iOS Keychain or previously authorized tokens. The function relies on an `appleAuthManager` and initiates the `QuickLogin` process. It handles successful re-authentication by retrieving user identifiers or Keychain credentials, and provides a fallback to display a full sign-in button if quick login fails due to an error. ```csharp using AppleAuth; using AppleAuth.Interfaces; using UnityEngine; public void AttemptQuickLogin() { var quickLoginArgs = new AppleAuthQuickLoginArgs(); appleAuthManager.QuickLogin( quickLoginArgs, credential => { // Check credential type var appleIdCredential = credential as IAppleIDCredential; if (appleIdCredential != null) { // Previous Apple sign in - only user ID available PlayerPrefs.SetString("AppleUserId", credential.User); Debug.Log($"Quick login successful: {credential.User}"); LoadGameScene(); } var passwordCredential = credential as IPasswordCredential; if (passwordCredential != null) { // iOS Keychain credential string username = passwordCredential.User; string password = passwordCredential.Password; Debug.Log($"Keychain login: {username}"); AuthenticateWithKeychain(username, password); } }, error => { // Quick login failed - show full login screen var errorCode = error.GetAuthorizationErrorCode(); Debug.Log($"Quick login unavailable: {errorCode}"); ShowSignInButton(); }); } private void LoadGameScene() { /* Load game */ } private void AuthenticateWithKeychain(string user, string pass) { /* Auth */ } private void ShowSignInButton() { /* Show UI */ } ``` -------------------------------- ### Add Sign In with Apple Capability Programmatically (C#) Source: https://github.com/lupidan/apple-signin-unity/blob/master/Source/README.md This C# code snippet demonstrates how to programmatically add the Sign In with Apple capability to an Xcode project using a Post-processing build script. It utilizes the ProjectCapabilityManager extension method 'AddSignInWithAppleWithCompatibility' to ensure the necessary entitlements are included. ```csharp using AppleAuth.Editor; using UnityEditor.Callbacks; using UnityEditor.iOS.Xcode; public static class SignInWithApplePostprocessor { [PostProcessBuild(1)] public static void OnPostProcessBuild(BuildTarget target, string path) { if (target != BuildTarget.iOS) return; var projectPath = PBXProject.GetPBXProjectPath(path); var project = new PBXProject(); project.ReadFromString(System.IO.File.ReadAllText(projectPath)); var manager = new ProjectCapabilityManager(projectPath, "Entitlements.entitlements", null, project.GetUnityMainTargetGuid()); manager.AddSignInWithAppleWithCompatibility(); manager.WriteToFile(); } } ``` -------------------------------- ### Adapt Xcode Project Path for visionOS Source: https://github.com/lupidan/apple-signin-unity/blob/master/Source/README.md This code snippet demonstrates how to modify the Xcode project path when building for visionOS in Unity. It replaces the default 'Unity-iPhone.xcodeproj' with 'Unity-VisionOS.xcodeproj' to ensure the correct project is targeted. ```csharp if (target == BuildTarget.VisionOS) { projectPath = projectPath.Replace("Unity-iPhone.xcodeproj", "Unity-VisionOS.xcodeproj"); } ``` -------------------------------- ### Update LoginWithAppleId Method Arguments Source: https://github.com/lupidan/apple-signin-unity/wiki/Migration-guides The LoginWithAppleId method now requires an AppleAuthLoginArgs struct, which is instantiated with the provided options, as the first argument. This change standardizes the input for login methods. ```csharp this.LoginWithAppleId(new AppleAuthLoginArgs(options), successCallback, errorCallback); ``` -------------------------------- ### macOS Entitlements for Apple Sign-In Source: https://github.com/lupidan/apple-signin-unity/blob/master/Source/docs/macOS_NOTES.md These XML snippets define the necessary entitlements for the 'Sign in with Apple' capability on macOS. They include the team identifier, application identifier, and the specific entitlement for Apple Sign-In. ```xml com.apple.developer.team-identifier TEAM_IDENTIFIER com.apple.application-identifier TEAM_IDENTIFIER.APP_IDENTIFIER ``` ```xml com.apple.developer.applesignin Default ``` -------------------------------- ### Update Callback Execution on Manager Source: https://github.com/lupidan/apple-signin-unity/wiki/Migration-guides Callback execution updates are now performed directly on the AppleAuthManager instance, rather than through a separate scheduler. This centralizes update logic within the manager itself. ```csharp this.appleAuthManager.Update(); ``` -------------------------------- ### Handle Apple Credential Revocation Notifications Source: https://context7.com/lupidan/apple-signin-unity/llms.txt Sets up a callback to receive real-time notifications when user credentials are revoked by Apple. This allows for immediate user logout and data cleanup. Depends on the AppleAuth SDK and Unity. ```csharp using AppleAuth; using UnityEngine; public class AuthManager : MonoBehaviour { private IAppleAuthManager appleAuthManager; void Start() { if (AppleAuthManager.IsCurrentPlatformSupported) { var deserializer = new PayloadDeserializer(); appleAuthManager = new AppleAuthManager(deserializer); // Register revocation callback appleAuthManager.SetCredentialsRevokedCallback(result => { Debug.LogWarning($"Credentials revoked for user: {result}"); // Clear stored credentials PlayerPrefs.DeleteKey("AppleUserId"); // Log out user and return to login screen LogoutUser(); ShowLoginScreen(); }); } } void OnDestroy() { // Unregister callback if (appleAuthManager != null) { appleAuthManager.SetCredentialsRevokedCallback(null); } } private void LogoutUser() { /* Logout logic */ } private void ShowLoginScreen() { /* Show UI */ } } ``` -------------------------------- ### Perform Quick Login with Apple Source: https://github.com/lupidan/apple-signin-unity/blob/master/Source/README.md Initiates a quick login flow with Apple Sign In. If the user has previously authorized the app, it prompts for re-confirmation to obtain an Apple User ID. If credentials were never provided or revoked, this will fail. It can return an Apple User ID or, if IOS Keychain credentials are detected, login details via IPasswordCredential. ```csharp var quickLoginArgs = new AppleAuthQuickLoginArgs(); this.appleAuthManager.QuickLogin( quickLoginArgs, credential => { // Received a valid credential! // Try casting to IAppleIDCredential or IPasswordCredential // Previous Apple sign in credential var appleIdCredential = credential as IAppleIDCredential; // Saved Keychain credential (read about Keychain Items) var passwordCredential = credential as IPasswordCredential; }, error => { // Quick login failed. The user has never used Sign in With Apple on your app. Go to login screen }); ``` -------------------------------- ### Update ProjectCapabilityManager for Older Unity Versions Source: https://github.com/lupidan/apple-signin-unity/wiki/Migration-guides This code snippet shows the adjustment needed for ProjectCapabilityManager in older Unity versions. It replaces the direct AddSignInWithApple call with AddSignInWithAppleWithCompatibility to maintain functionality. ```csharp var manager = new ProjectCapabilityManager(projectPath, "Entitlements.entitlements", PBXProject.GetUnityTargetName()); manager.AddSignInWithAppleWithCompatibility(); manager.WriteToFile(); ``` -------------------------------- ### Perform Apple Sign In and Firebase Authentication in C# Source: https://github.com/lupidan/apple-signin-unity/blob/master/Source/docs/Firebase_NOTES.md Initiates the Sign in with Apple flow using the AppleAuthManager, generating a raw nonce and its SHA256 hash. It then performs Firebase authentication using the obtained Apple credentials and the raw nonce. The method accepts a callback to process the FirebaseUser upon successful authentication. ```csharp using System; using AppleAuth; using AppleAuth.Enums; using AppleAuth.Interfaces; using Firebase.Auth; public void PerformLoginWithAppleIdAndFirebase(Action firebaseAuthCallback) { var rawNonce = GenerateRandomString(32); var nonce = GenerateSHA256NonceFromRawNonce(rawNonce); var loginArgs = new AppleAuthLoginArgs( LoginOptions.IncludeEmail | LoginOptions.IncludeFullName, nonce); this.appleAuthManager.LoginWithAppleId( loginArgs, credential => { var appleIdCredential = credential as IAppleIDCredential; if (appleIdCredential != null) { this.PerformFirebaseAuthentication(appleIdCredential, rawNonce, firebaseAuthCallback); } }, error => { // Something went wrong }); } ``` -------------------------------- ### Configure Nonce and State for Apple Authorization Requests Source: https://github.com/lupidan/apple-signin-unity/blob/master/Source/README.md Allows setting optional Nonce and State parameters for Apple authorization requests, used in both `LoginWithAppleId` and `QuickLogin` methods. The State can be validated upon receiving the credential to ensure the request originated from the device. The Nonce is embedded in the IdentityToken and should be unique per request for security, particularly useful for integrations with services like Firebase. ```csharp // Your custom Nonce string var yourCustomNonce = "RANDOM_NONCE_FORTHEAUTHORIZATIONREQUEST"; var yourCustomState = "RANDOM_STATE_FORTHEAUTHORIZATIONREQUEST"; // Arguments for a normal Sign In With Apple Request var loginArgs = new AppleAuthLoginArgs( LoginOptions.IncludeEmail | LoginOptions.IncludeFullName, yourCustomNonce, yourCustomState); // Arguments for a Quick Login var quickLoginArgs = new AppleAuthQuickLoginArgs(yourCustomNonce, yourCustomState); ``` -------------------------------- ### Authenticate User with Firebase using Apple Credentials (C#) Source: https://github.com/lupidan/apple-signin-unity/blob/master/Source/docs/Firebase_NOTES.md Handles the authentication of a user with Firebase using credentials obtained from Apple Sign-In. It constructs a Firebase credential using the identity token, authorization code, and nonce, then signs in the user. Error handling for cancellation and faults is included. ```csharp using System; using System.Text; using AppleAuth.Interfaces; using Firebase.Auth; using Firebase.Extensions; using UnityEngine; // Your Firebase authentication client private FirebaseAuth firebaseAuth; private void PerformFirebaseAuthentication( IAppleIDCredential appleIdCredential, string rawNonce, Action firebaseAuthCallback) { var identityToken = Encoding.UTF8.GetString(appleIdCredential.IdentityToken); var authorizationCode = Encoding.UTF8.GetString(appleIdCredential.AuthorizationCode); var firebaseCredential = OAuthProvider.GetCredential( "apple.com", identityToken, rawNonce, authorizationCode); this.firebaseAuth.SignInWithCredentialAsync(firebaseCredential) .ContinueWithOnMainThread(task => HandleSignInWithUser(task, firebaseAuthCallback)); } private static void HandleSignInWithUser(Task task, Action firebaseUserCallback) { if (task.IsCanceled) { Debug.Log("Firebase auth was canceled"); firebaseUserCallback(null); } else if (task.IsFaulted) { Debug.Log("Firebase auth failed"); firebaseUserCallback(null); } else { var firebaseUser = task.Result; Debug.Log("Firebase auth completed | User ID:" + firebaseUser.UserId); firebaseUserCallback(firebaseUser); } } ``` -------------------------------- ### Remove .meta files from Unity Bundles Source: https://github.com/lupidan/apple-signin-unity/blob/master/Source/docs/macOS_NOTES.md This shell command finds and removes `.meta` files within plugin bundles inside a macOS `.app` package. This is necessary due to a Unity bug that can interfere with code signing. ```bash find MYGAME.app/Contents/Plugins/ -name "*.meta" -print0 | xargs -I {} -0 rm -v "{}" ``` -------------------------------- ### macOS Bundle Identifier Fixer (C#) Source: https://github.com/lupidan/apple-signin-unity/blob/master/Source/README.md Automates the modification of the bundle identifier for a precompiled .bundle file on macOS. This is crucial for avoiding issues when uploading to the App Store. It should be called as a Postprocess build script. ```csharp using AppleAuth.Editor; public static class SignInWithApplePostprocessor { [PostProcessBuild(1)] public static void OnPostProcessBuild(BuildTarget target, string path) { if (target != BuildTarget.StandaloneOSX) return; AppleAuthMacosPostprocessorHelper.FixManagerBundleIdentifier(target, path); } } ``` -------------------------------- ### Remove OnDemandMessageHandlerScheduler Source: https://github.com/lupidan/apple-signin-unity/wiki/Migration-guides The OnDemandMessageHandlerScheduler is no longer required and has been removed from the instantiation of AppleAuthManager. This simplifies the constructor and reduces unnecessary dependencies. ```csharp private OnDemandMessageHandlerScheduler scheduler; ``` -------------------------------- ### Update Namespace for Native Messages Source: https://github.com/lupidan/apple-signin-unity/wiki/Migration-guides This change reflects a namespace update required due to the introduction of macOS support. The AppleAuth.IOS.NativeMessages namespace has been consolidated into the more general AppleAuth.Native namespace. ```csharp using AppleAuth.Native; ``` -------------------------------- ### Generate Random Nonce String in C# Source: https://github.com/lupidan/apple-signin-unity/blob/master/Source/docs/Firebase_NOTES.md Generates a cryptographically secure random string of a specified length, commonly used as a nonce for authentication. It utilizes RNGCryptoServiceProvider for randomness and a predefined character set for the output string. The function throws an exception if the requested length is not positive. ```csharp using System; using System.Collections.Generic; using System.Security.Cryptography; private static string GenerateRandomString(int length) { if (length <= 0) { throw new Exception("Expected nonce to have positive length"); } const string charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._"; var cryptographicallySecureRandomNumberGenerator = new RNGCryptoServiceProvider(); var result = string.Empty; var remainingLength = length; var randomNumberHolder = new byte[1]; while (remainingLength > 0) { var randomNumbers = new List(16); for (var randomNumberCount = 0; randomNumberCount < 16; randomNumberCount++) { cryptographicallySecureRandomNumberGenerator.GetBytes(randomNumberHolder); randomNumbers.Add(randomNumberHolder[0]); } for (var randomNumberIndex = 0; randomNumberIndex < randomNumbers.Count; randomNumberIndex++) { if (remainingLength == 0) { break; } var randomNumber = randomNumbers[randomNumberIndex]; if (randomNumber < charset.Length) { result += charset[randomNumber]; remainingLength--; } } } return result; } ``` -------------------------------- ### Generate SHA256 Hash from Nonce in C# Source: https://github.com/lupidan/apple-signin-unity/blob/master/Source/docs/Firebase_NOTES.md Computes the SHA256 hash of a given raw nonce string. The input string is first converted to UTF8 bytes, then the hash is computed using SHA256Managed. The resulting hash is formatted as a hexadecimal string. This is typically used for verifying credentials with Apple. ```csharp using System.Security.Cryptography; using System.Text; private static string GenerateSHA256NonceFromRawNonce(string rawNonce) { var sha = new SHA256Managed(); var utf8RawNonce = Encoding.UTF8.GetBytes(rawNonce); var hash = sha.ComputeHash(utf8RawNonce); var result = string.Empty; for (var i = 0; i < hash.Length; i++) { result += hash[i].ToString("x2"); } return result; } ``` -------------------------------- ### Handle Credentials Revoked Notification Source: https://github.com/lupidan/apple-signin-unity/blob/master/Source/README.md Registers a callback to listen for notifications when a user revokes their Apple Sign In authorization. Upon receiving such a notification, the application should clear the user's credentials and direct them to the login screen. The callback can be cleared by setting it to null. ```csharp this.appleAuthManager.SetCredentialsRevokedCallback(result => { // Sign in with Apple Credentials were revoked. // Discard credentials/user id and go to login screen. }); ``` ```csharp this.appleAuthManager.SetCredentialsRevokedCallback(null); ``` -------------------------------- ### Check Apple User ID Credential Status Source: https://github.com/lupidan/apple-signin-unity/blob/master/Source/README.md Verifies the validity of an Apple User ID obtained from a previous successful sign-in. It returns the current credential state, allowing the application to determine if the user should be logged in, or if they need to go through the login process again due to revocation or the ID not being found. ```csharp this.appleAuthManager.GetCredentialState( userId, state => { switch (state) { case CredentialState.Authorized: // User ID is still valid. Login the user. break; case CredentialState.Revoked: // User ID was revoked. Go to login screen. break; case CredentialState.NotFound: // User ID was not found. Go to login screen. break; } }, error => { // Something went wrong }); ``` -------------------------------- ### Fix macOS Bundle Identifier for App Store - C# Source: https://context7.com/lupidan/apple-signin-unity/llms.txt Resolves bundle identifier collisions for macOS App Store submissions by modifying the bundle identifier of the AppleAuthManager.bundle. This script runs as a post-build process for standalone macOS builds. It relies on the AppleAuth.Editor namespace and a helper method to perform the identifier fix. ```csharp using UnityEditor; using UnityEditor.Callbacks; using AppleAuth.Editor; public static class MacOSPostprocessor { [PostProcessBuild(1)] public static void OnPostProcessBuild(BuildTarget target, string path) { if (target != BuildTarget.StandaloneOSX) return; // Fix MacOSAppleAuthManager.bundle identifier to avoid conflicts // Changes bundle ID from generic to app-specific AppleAuthMacosPostprocessorHelper.FixManagerBundleIdentifier(target, path); Debug.Log("Fixed macOS bundle identifier for App Store submission"); } } ``` -------------------------------- ### Fix macOS Bundle Identifier using Unity Post-Process Build Script Source: https://github.com/lupidan/apple-signin-unity/blob/master/Source/README.md This code snippet demonstrates how to fix the CFBundleIdentifier collision error by calling a helper method within a Unity post-process build script for macOS. This ensures that the plugin's bundle identifier is customized for your application, preventing conflicts on the App Store. ```csharp AppleAuthMacosPostprocessorHelper.FixManagerBundleIdentifier(); ``` -------------------------------- ### Validate User Credential State with Apple Auth Source: https://context7.com/lupidan/apple-signin-unity/llms.txt Checks the authorization status of a stored Apple User ID. It handles cases where credentials are authorized, revoked, not found, or transferred, ensuring appropriate user flows. Requires the AppleAuth SDK. ```csharp using AppleAuth; using AppleAuth.Enums; using UnityEngine; public void ValidateStoredCredential() { string storedUserId = PlayerPrefs.GetString("AppleUserId"); if (string.IsNullOrEmpty(storedUserId)) { ShowLoginScreen(); return; } appleAuthManager.GetCredentialState( storedUserId, state => { switch (state) { case CredentialState.Authorized: Debug.Log("User is authorized - logging in"); LoginUserWithId(storedUserId); break; case CredentialState.Revoked: Debug.LogWarning("Credentials revoked - clearing data"); PlayerPrefs.DeleteKey("AppleUserId"); ShowLoginScreen(); break; case CredentialState.NotFound: Debug.LogWarning("User not found - clearing data"); PlayerPrefs.DeleteKey("AppleUserId"); ShowLoginScreen(); break; case CredentialState.Transferred: Debug.Log("Credentials transferred to new device"); LoginUserWithId(storedUserId); break; } }, error => { Debug.LogError($"Credential check failed: {error}"); ShowLoginScreen(); }); } private void LoginUserWithId(string userId) { /* Login */ } private void ShowLoginScreen() { /* Show UI */ } ``` -------------------------------- ### Remove Extended Attributes from macOS Application Source: https://github.com/lupidan/apple-signin-unity/blob/master/Source/docs/macOS_NOTES.md This command removes extended attributes from the application bundle. This is an optional but recommended step when distributing the app to other machines to prevent potential issues caused by macOS's attribute handling. Execute this on the machine receiving the app. ```console xattr -crs ./AppleAuthSampleProject.app ``` -------------------------------- ### Remove Extended Attributes from App Bundle Source: https://github.com/lupidan/apple-signin-unity/blob/master/Source/docs/macOS_NOTES.md This shell command removes extended attributes from all files within a macOS `.app` bundle. This is crucial to prevent issues when distributing signed applications, as certain applications can add attributes that cause runtime errors. ```bash xattr -crs MYGAME.app ```