유니티 플레이팹 애플 로그인 Playfab Sign ln with Apple Login 간단 구현

반응형

유니티용 애플 SDK 설치

 

Release Sign in with Apple Unity Plugin v1.4.2 · lupidan/apple-signin-unity

Changed Handles empty NSPersonNameComponents sent by Apple when not requesting a name, to be nil natively. Updated MacOSAppleAuthManager.bundle with the updated native code Removed Removes FixSe...

github.com

 

코드 작성

using System;
using System.Collections;
using System.Text;
using PlayFab;
using PlayFab.ClientModels;
using UnityEngine;
#if UNITY_IOS
using AppleAuth;
using AppleAuth.Native;
using AppleAuth.Enums;
using AppleAuth.Interfaces;
using AppleAuth.Extensions;
#endif

public class PlayfabManager : MonoBehaviour
{
#if UNITY_IOS
    // 상수 및 필드
    private const string AppleUserIdKey = "AppleUserId";
    private IAppleAuthManager _appleAuthManager;
    private bool _isAppleAuthInitialized = false;
    
    // 이벤트 시스템 추가
    public event Action<LoginResult> OnAppleLoginSuccess;
    public event Action<string> OnAppleLoginFailed;
    public event Action<bool> OnAppleLinkCompleted;
#endif

    // 오류 처리 함수
    private void DisplayPlayfabError(PlayFabError error)
    {
        string errorMessage = "PlayFab 오류: " + error.GenerateErrorReport();
        Debug.LogError(errorMessage);
#if UNITY_IOS
        OnAppleLoginFailed?.Invoke(errorMessage);
#endif
    }

    private void Awake()
    {
#if UNITY_IOS
        // 시작 시 Apple 인증 초기화
        InitializeAppleAuth();
#endif
    }

#if UNITY_IOS
    // Apple 인증 초기화
    private bool InitializeAppleAuth()
    {
        // 이미 초기화되었으면 중복 초기화 방지
        if (_isAppleAuthInitialized)
            return true;
            
        // 플랫폼 지원 확인
        if (!AppleAuthManager.IsCurrentPlatformSupported)
        {
            Debug.LogWarning("현재 플랫폼은 Apple 인증을 지원하지 않습니다.");
            return false;
        }
        
        try
        {
            // 인증 관리자 초기화
            var deserializer = new PayloadDeserializer();
            _appleAuthManager = new AppleAuthManager(deserializer);
            
            // 업데이트 코루틴 시작
            StartCoroutine(AppleAuthUpdateCoroutine());
            
            _isAppleAuthInitialized = true;
            Debug.Log("Apple 인증 초기화 완료");
            return true;
        }
        catch (Exception ex)
        {
            Debug.LogError($"Apple 인증 초기화 실패: {ex.Message}");
            return false;
        }
    }
    
    // Apple 인증 업데이트 코루틴
    private IEnumerator AppleAuthUpdateCoroutine()
    {
        while (true)
        {
            // null 체크 추가
            if (_appleAuthManager != null)
            {
                _appleAuthManager.Update();
            }
            yield return null;
        }
    }
    
    // Apple 로그인 버튼 클릭 시 호출
    public void OnClickAppleLogin()
    {
        Debug.Log("Apple 로그인 시도 중...");
        
        // 초기화 확인
        if (!_isAppleAuthInitialized && !InitializeAppleAuth())
        {
            string errorMessage = "Apple 인증을 초기화할 수 없습니다.";
            Debug.LogError(errorMessage);
            OnAppleLoginFailed?.Invoke(errorMessage);
            return;
        }
        
        // 저장된 Apple ID 확인
        string storedAppleUserId = PlayerPrefs.GetString(AppleUserIdKey, "");
        bool hasExistingCredentials = !string.IsNullOrEmpty(storedAppleUserId);
        
        StartCoroutine(AppleLoginCoroutine(hasExistingCredentials));
    }
    
    // Apple 로그인 코루틴
    private IEnumerator AppleLoginCoroutine(bool useQuickLogin)
    {
        // 초기화 대기
        while (_appleAuthManager == null)
        {
            yield return null;
        }
        
        try
        {
            if (useQuickLogin)
            {
                // 빠른 로그인 시도 (이전에 로그인한 적이 있는 경우)
                Debug.Log("Apple 빠른 로그인 시도 중...");
                var quickLoginArgs = new AppleAuthQuickLoginArgs();
                
                _appleAuthManager.QuickLogin(
                    quickLoginArgs,
                    credential => {
                        var appleIdCredential = credential as IAppleIDCredential;
                        if (appleIdCredential != null)
                        {
                            // 사용자 ID 저장
                            PlayerPrefs.SetString(AppleUserIdKey, appleIdCredential.User);
                            PlayerPrefs.Save();
                            
                            // PlayFab 로그인 처리
                            ProcessAppleLoginWithPlayFab(appleIdCredential.IdentityToken);
                        }
                        else
                        {
                            Debug.LogError("Apple 인증 정보가 올바르지 않습니다.");
                            OnAppleLoginFailed?.Invoke("인증 정보가 올바르지 않습니다.");
                        }
                    },
                    error => {
                        Debug.LogWarning($"Apple 빠른 로그인 실패: {error}, 전체 로그인 시도...");
                        StartCoroutine(PerformFullAppleSignIn());
                    });
            }
            else
            {
                // 전체 로그인 시도
                yield return StartCoroutine(PerformFullAppleSignIn());
            }
        }
        catch (Exception ex)
        {
            Debug.LogError($"Apple 로그인 중 오류 발생: {ex.Message}");
            OnAppleLoginFailed?.Invoke(ex.Message);
        }
    }
    
    // 전체 Apple 로그인 프로세스
    private IEnumerator PerformFullAppleSignIn()
    {
        Debug.Log("Apple 전체 로그인 시도 중...");
        
        bool signInCompleted = false;
        Exception signInException = null;
        
        // 이메일과 이름 정보 요청
        var loginArgs = new AppleAuthLoginArgs(LoginOptions.IncludeEmail | LoginOptions.IncludeFullName);
        
        _appleAuthManager.LoginWithAppleId(
            loginArgs,
            credential => {
                var appleIdCredential = credential as IAppleIDCredential;
                if (appleIdCredential != null)
                {
                    // 사용자 ID 저장
                    PlayerPrefs.SetString(AppleUserIdKey, appleIdCredential.User);
                    PlayerPrefs.Save();
                    
                    // 추가 정보 로깅 (디버그용)
                    if (!string.IsNullOrEmpty(appleIdCredential.Email))
                        Debug.Log($"Apple 이메일: {appleIdCredential.Email}");
                        
                    if (appleIdCredential.FullName != null)
                    {
                        string fullName = "";
                        if (!string.IsNullOrEmpty(appleIdCredential.FullName.GivenName))
                            fullName += appleIdCredential.FullName.GivenName;
                            
                        if (!string.IsNullOrEmpty(appleIdCredential.FullName.FamilyName))
                        {
                            if (!string.IsNullOrEmpty(fullName))
                                fullName += " ";
                            fullName += appleIdCredential.FullName.FamilyName;
                        }
                        
                        if (!string.IsNullOrEmpty(fullName))
                            Debug.Log($"Apple 사용자 이름: {fullName}");
                    }
                    
                    // PlayFab 로그인 처리
                    ProcessAppleLoginWithPlayFab(appleIdCredential.IdentityToken);
                }
                else
                {
                    signInException = new Exception("Apple 인증 정보가 올바르지 않습니다.");
                }
                
                signInCompleted = true;
            },
            error => {
                var authorizationErrorCode = error.GetAuthorizationErrorCode();
                signInException = new Exception($"Apple 로그인 실패: {error} (코드: {authorizationErrorCode})");
                signInCompleted = true;
            });
        
        // 로그인 완료 대기
        while (!signInCompleted)
            yield return null;
            
        // 오류 발생 시 처리
        if (signInException != null)
        {
            Debug.LogError(signInException.Message);
            OnAppleLoginFailed?.Invoke(signInException.Message);
        }
    }
    
    // PlayFab으로 Apple 로그인 처리
    private void ProcessAppleLoginWithPlayFab(byte[] identityToken)
    {
        if (identityToken == null || identityToken.Length == 0)
        {
            Debug.LogError("Apple 인증 토큰이 비어있습니다.");
            OnAppleLoginFailed?.Invoke("인증 토큰이 비어있습니다.");
            return;
        }
        
        try
        {
            string tokenString = Encoding.UTF8.GetString(identityToken);
            Debug.Log("PlayFab으로 Apple 로그인 시도 중...");
            
            PlayFabClientAPI.LoginWithApple(
                new LoginWithAppleRequest
                {
                    CreateAccount = true,
                    IdentityToken = tokenString,
                    TitleId = PlayFabSettings.TitleId,
                    InfoRequestParameters = new GetPlayerCombinedInfoRequestParams
                    {
                        GetPlayerProfile = true,
                        GetUserAccountInfo = true
                    }
                },
                result => {
                    Debug.Log("PlayFab Apple 로그인 성공!");
                    OnLoginSuccess(result);
                },
                error => {
                    Debug.LogError($"PlayFab Apple 로그인 실패: {error.ErrorMessage}");
                    OnAppleLoginFailed?.Invoke(error.ErrorMessage);
                });
        }
        catch (Exception ex)
        {
            Debug.LogError($"PlayFab 로그인 처리 중 오류 발생: {ex.Message}");
            OnAppleLoginFailed?.Invoke(ex.Message);
        }
    }
    
    // 계정 연결 기능
    public void OnClickAppleLink(bool forceLink = false)
    {
        Debug.Log($"Apple 계정 연결 시도 중... (강제 연결: {forceLink})");
        
        // 초기화 확인
        if (!_isAppleAuthInitialized && !InitializeAppleAuth())
        {
            Debug.LogError("Apple 인증을 초기화할 수 없습니다.");
            OnAppleLinkCompleted?.Invoke(false);
            return;
        }
        
        try
        {
            var quickLoginArgs = new AppleAuthQuickLoginArgs();
            
            _appleAuthManager.QuickLogin(
                quickLoginArgs,
                credential => {
                    var appleIdCredential = credential as IAppleIDCredential;
                    if (appleIdCredential != null)
                    {
                        LinkAppleAccountWithPlayFab(appleIdCredential.IdentityToken, forceLink);
                    }
                    else
                    {
                        Debug.LogError("Apple 인증 정보가 올바르지 않습니다.");
                        OnAppleLinkCompleted?.Invoke(false);
                    }
                },
                error => {
                    // 빠른 로그인 실패 시 전체 로그인 시도
                    var loginArgs = new AppleAuthLoginArgs(LoginOptions.IncludeEmail | LoginOptions.IncludeFullName);
                    
                    _appleAuthManager.LoginWithAppleId(
                        loginArgs,
                        fullLoginCredential => {
                            var appleIdCredential = fullLoginCredential as IAppleIDCredential;
                            if (appleIdCredential != null)
                            {
                                LinkAppleAccountWithPlayFab(appleIdCredential.IdentityToken, forceLink);
                            }
                            else
                            {
                                Debug.LogError("Apple 인증 정보가 올바르지 않습니다.");
                                OnAppleLinkCompleted?.Invoke(false);
                            }
                        },
                        fullLoginError => {
                            Debug.LogError($"Apple 로그인 실패: {fullLoginError}");
                            OnAppleLinkCompleted?.Invoke(false);
                        });
                });
        }
        catch (Exception ex)
        {
            Debug.LogError($"Apple 계정 연결 중 오류 발생: {ex.Message}");
            OnAppleLinkCompleted?.Invoke(false);
        }
    }
    
    // PlayFab으로 Apple 계정 연결
    private void LinkAppleAccountWithPlayFab(byte[] identityToken, bool forceLink)
    {
        if (identityToken == null || identityToken.Length == 0)
        {
            Debug.LogError("Apple 인증 토큰이 비어있습니다.");
            OnAppleLinkCompleted?.Invoke(false);
            return;
        }
        
        try
        {
            string tokenString = Encoding.UTF8.GetString(identityToken);
            
            PlayFabClientAPI.LinkApple(
                new LinkAppleRequest
                {
                    ForceLink = forceLink,
                    IdentityToken = tokenString
                },
                result => {
                    Debug.Log("Apple 계정 연결 성공!");
                    OnAppleLinkCompleted?.Invoke(true);
                },
                error => {
                    // 계정이 이미 다른 계정에 연결되어 있는 경우
                    if (error.Error == PlayFabErrorCode.AccountAlreadyLinked)
                    {
                        Debug.LogError("이 Apple 계정은 이미 다른 PlayFab 계정에 연결되어 있습니다.");
                    }
                    // 현재 계정이 이미 다른 Apple 계정에 연결되어 있는 경우
                    else if (error.Error == PlayFabErrorCode.LinkedAccountAlreadyClaimed)
                    {
                        Debug.LogError("현재 PlayFab 계정은 이미 다른 Apple 계정에 연결되어 있습니다.");
                    }
                    else
                    {
                        Debug.LogError($"Apple 계정 연결 실패: {error.ErrorMessage}");
                    }
                    
                    OnAppleLinkCompleted?.Invoke(false);
                });
        }
        catch (Exception ex)
        {
            Debug.LogError($"PlayFab 계정 연결 중 오류 발생: {ex.Message}");
            OnAppleLinkCompleted?.Invoke(false);
        }
    }
#endif

    // 로그인 성공 처리
    public void OnLoginSuccess(LoginResult result)
    {
        Debug.Log("PlayFab 로그인 성공! PlayFabId: " + result.PlayFabId);
        
#if UNITY_IOS
        // 이벤트 호출
        OnAppleLoginSuccess?.Invoke(result);
#endif

        // 로그인 성공 후 추가 처리
    }
}

 


참고할만한 글

 

플레이팹 Playfab 게스트 로그인 Guest Login 간단 사용법

using PlayFab; using PlayFab.ClientModels; using PlayFab.Json; using PlayFab.ProfilesModels; using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using Entity..

parksh3641.tistory.com

 

유니티 플레이팹 구글 로그인 Playfab Sign In with Google Login 간단 구현

구글 로그인 SDK 설치 https://github.com/playgameservices/play-games-plugin-for-unity/tree/master/current-build GitHub - playgameservices/play-games-plugin-for-unity: Google Play Games plugin for Unity Google Play Games plugin for Unity. Contribute t

parksh3641.tistory.com

 

반응형