로그인·로그아웃하기
로그인
인증에서 로그인은 다음의 순서로 구성합니다.
Authv4Helper는 로그인과 관련된 일련의 과정을 수행하며, 응답 값에 따라 적절한 화면으로 이동하도록 구성하는 클래스입니다.
로그인 구성 시 다음 사항을 참고하세요.
자동 로그인 및 묵시적 로그인
자동 로그인
유저가 로그인 수단을 선택하지 않고 iOS에서는 Apple Game Center 계정을, Android에서는 Google Play 게임 계정을 자동 연동하여 로그인하는 방식을 의미합니다. 자동 로그인을 구현하고, 자동 로그인에 실패했을 경우 묵시적 로그인을 수행합니다.
오프라인 모드
Hive SDK v4 23.1.0 이상에서는 유저 기기가 네트워크에 연결되지 않은 상태에서 앱을 실행했더라도 자동 로그인(ProviderType.AUTO
를 사용하는 AuthV4.signIn
, 또는 AuthV4.Helper.signIn
) 기능을 제공할 수 있습니다. 오프라인 모드를 사용하려면 다음 안내를 따르세요.
- 온라인 상태에서 앱을 실행하여 명시적, 묵시적, 게스트, 또는 커스텀 로그인에 성공하고,
playerId
와playerToken
을 발급받은 적이 있어야 합니다.앱 개발사 입장에서는 온라인 상태에서 최소 한 번 이상
AuthV4.Helper.signIn
,AuthV4.showSignIn
, 또는AuthV4.signInWithAuthKey
실행에 성공하여 콜백으로playerId
와playerToken
을 받은 적이 있어야 하며, 유저 입장에서는 유저 기기가 네트워크에 연결된 상태에서 최소 한 번 이상 앱에서 로그인에 성공했어야 합니다. 단, 유저가 온라인 상태에서 마지막으로 로그인을 시도했을 때 유저 계정이 이용 정지 또는 이용 제한 상태였다면, 유저는 오프라인 모드에서도 로그인할 수 없습니다. - Hive 콘솔 앱센터 > 프로젝트 관리 > 게임 상세 > Hive 제품설정에서 오프라인 모드를 활성화합니다.
Windows 환경에서 자동 로그인
Windows 환경도 자동 로그인을 지원하며, Hive 콘솔 앱센터에서 활성화/비활성화할 수 있습니다. 단, Windows 자동 로그인은 모바일과 다르게 동작합니다. Windows에서 자동 로그인은 다음과 같은 차이가 있습니다.
- 모바일에서는 로그인 이후에 무조건 자동 로그인으로 로그인 상태를 유지하지만, Windows에서는 유저가 로그인 유지 체크박스(로그인 UI상에서 IdP 목록 하단에 표시)를 활성화한 경우에만 로그인을 유지합니다. 그 외 상황에서는 로그인을 유지하지 않습니다.
- AuthV4Helper.Connect 실행 시 모바일에서는 새로운 계정으로 계정을 전환할 경우 새 계정도 자동 로그인 상태를 유지하지만, Windows에서는 새로운 계정으로 계정을 전환할 경우 새 계정은 자동 로그인 상태를 유지하지 않습니다.
묵시적 로그인
AuthV4.Helper.signIn
은 PlayerID의 인증 토큰 키를 이용해 자동 로그인을 시도합니다. 기존에 로그인 했던 인증 토큰 키가 없다면 iOS인 경우 Apple Game Center에, Android인 경우 Google Play 게임에 자동으로 로그인합니다. 로그인을 실패하면 응답 값에 따라 적절한 로그인 화면을 구성합니다.
다음은 자동 로그인을 수행하는 예제 코드입니다.
API Reference: hive.AuthV4.Helper.signIn
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// Hive SDK 로그인(signIn) 시도 AuthV4.Helper.signIn (delegate (ResultAPI result, AuthV4.PlayerInfo playerInfo) { if (result.isSuccess()) { // 로그인 성공 } else if (result.needExit()) { // TODO: 앱 종료 기능을 구현하세요 // 예) Application.Quit(); } else { switch (result.code) { case ResultAPI.Code.AuthV4ConflictPlayer: // 계정 충돌 break; case ResultAPI.Code.AuthV4HelperImplifiedLoginFail: // 묵시적 로그인에 실패 // ex) AuthV4.showSignIn(...); break; default: // 기타 예외 상황 break; } } }); |
API Reference: Auth4::signIn
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
// Hive SDK 로그인(signIn) 시도 AuthV4::Helper::signIn([=](ResultAPI const & result, std::shared_ptr playerInfo) { if (result.isSuccess()) { // 로그인 성공 } else if (result.needExit()) { // TODO: 앱 종료 기능을 구현하세요 // Cocos2d-x 엔진 사용자 // 예) exit(0); // Unreal 엔진 사용자 // 예) UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, false); } else { switch (result.code) { case ResultAPI::AuthV4ConflictPlayer: // 계정 충돌 break; case ResultAPI::AuthV4HelperImplifiedLoginFail: // 묵시적 로그인에 실패 // ex) AuthV4.showSignIn(...); break; default: break; } } }); |
API Reference: com.hive.Auth4.Helper.signIn
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
// Hive SDK 로그인(signIn) 시도 AuthV4.Helper.signIn(object : AuthV4.Helper.AuthV4HelperListener { override fun onAuthV4Helper(result: ResultAPI, playerInfo: AuthV4.PlayerInfo?) { if (result.isSuccess) { // 로그인 성공 } else if (result.needExit()) { // TODO: 앱 종료 기능을 구현하세요 // 예) exitProcess(0) } else { when (result.code) { ResultAPI.Code.AuthV4ConflictPlayer -> { // 계정 충돌 } ResultAPI.Code.AuthV4HelperImplifiedLoginFail -> { // 묵시적 로그인에 실패 // ex) AuthV4.showSignIn(...); } else -> { // 기타 예외 상황 } } } } }) |
API Reference: com.hive.Auth4.Helper.signIn
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
// Hive SDK 로그인(signIn) 시도 AuthV4.Helper.signIn(new AuthV4.Helper.AuthV4HelperListener() { @Override public void onAuthV4Helper(ResultAPI result, AuthV4.PlayerInfo playerInfo) { if (result.isSuccess()) { // 로그인 성공 } else if (result.needExit()) { // TODO: 앱 종료 기능을 구현하세요 // 예) System.exit(0); } else { switch (result.code) { case AuthV4ConflictPlayer: // 계정 충돌 break; case AuthV4HelperImplifiedLoginFail: // 묵시적 로그인에 실패 // ex) AuthV4.showSignIn(...); break; default: // 기타 예외 상황 break; } } } }); |
API Reference: HIVEAuth4:signIn
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
// Hive SDK 로그인(signIn) 시도 AuthV4Interface.helper().signIn() { (result, playerInfo) in if result.isSuccess() { // 로그인 성공 } else if result.needExit() { // TODO: 앱 종료 기능을 구현하세요 // 예) exit(0) } else { switch result.getCode() { case .authV4ConflictPlayer: // 계정 충돌 case .authV4HelperImplifiedLoginFail: // 묵시적 로그인에 실패 // ex) AuthV4Interface.showSignIn() { (result, playerInfo) // // do something... // } default: // 기타 예외 상황 break } } } |
API Reference: HIVEAuth4:signIn
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
// Hive SDK 로그인(signIn) 시도 [[HIVEAuthV4 helper] signIn:^(HIVEResultAPI *result, HIVEPlayerInfo *playerInfo) { if (result.isSuccess) { // 로그인 성공 } else if (result.needExit) { // TODO: 앱 종료 기능을 구현하세요 // 예) exit(0); } else { switch (result.code) { case kAuthV4ConflictPlayer: // 계정 충돌 break; case kAuthV4HelperImplifiedLoginFail: // 묵시적 로그인에 실패 // ex) [HIVEAuthV4 showSignIn:^(HIVEResultAPI *result, HIVEPlayerInfo *playerInfo) { // // do something... // }]; break; default: // 기타 예외 상황 break; } } }]; |
묵시적 로그인 동작: 모바일
모바일(Hive SDK Unity Android 등 Android/iOS 플랫폼) 묵시적 로그인(AuthV4.Helper.signIn
)은 최초 로그인 후에 다른 계정으로 로그인할 경우, 계정 충돌 상황이 발생하고 마지막으로 로그인한 계정으로 로그인할 지 사용자에게 묻는 창을 띄웁니다.
묵시적 로그인 동작: PC
PC(Hive SDK Unity Windows 등 Windows 플랫폼) 묵시적 로그인(AuthV4.Helper.signIn
)은 최초 로그인 후에 다른 계정으로 로그인할 경우, 마지막으로 로그인한 계정으로 자동으로 로그인합니다. 계정 충돌 상황은 발생하지 않습니다.
명시적 로그인
명시적 로그인이란 유저가 인증을 진행할 IdP를 선택하여 진행하는 것을 의미합니다. 자동 로그인과 묵시적 로그인 모두 실패했다면, 게임 타이틀 화면으로 이동한 후 타이틀에서 클릭했을 때 명시적 로그인을 수행하도록 구현하세요.
명시적 로그인 UI는 Hive SDK에서 제공하는 UI를 사용할 수도 있고 Hive SDK 초기화가 완료 후 결과로 반환되는 인증에 사용할 IdP 리스트를 이용하여 게임 자체 구현으로 커스터마이징 할 수 있습니다. UI를 커스터마이징 하는 경우 명시적 로그인 커스터마이징 항목을 참고하세요.
IdP 리스트는 각 국가의 정책에 따라 Hive 플랫폼에서 제어하여 제공됩니다. 예를 들어, 중국에서는 Google Play 게임 및 Facebook, 게스트가 제공되지 않습니다.
명시적 로그인 스크린샷
SDK에서 제공하는 UI를 사용하여 구현하는 경우
SDK에서 제공하는 UI를 사용하여 명시적 로그인을 구현하기 위해서는 showSignIn()
메서드를 호출하여 IdP 리스트 UI를 간단히 호출할 수 있습니다.
API Reference: hive.AuthV4.showSignIn
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
// Hive SDK AuthV4 인증 UI 요청 AuthV4.showSignIn((ResultAPI result, AuthV4.PlayerInfo playerInfo)=>{ if (result.isSuccess()) { // 인증 성공 // playerInfo : 인증된 사용자 정보 // 이메일 정보 조회 예시 foreach (KeyValuePair<AuthV4.ProviderType, AuthV4.ProviderInfo> entry in playerInfo.providerInfoData) { AuthV4.ProviderInfo providerInfo = entry.Value; if(providerInfo.providerEmail != null && providerInfo.providerEmail != "") { string email = providerInfo.providerEmail; break; } } } else if (result.needExit()) { // TODO: 앱 종료 기능을 구현하세요 // 예) Application.Quit(); } }); |
API Reference: AuthV4::showSignIn
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// Hive SDK AuthV4 인증 UI 요청 AuthV4::showSignIn([=](ResultAPI const & result, PlayerInfo const & playerInfo) { if (result.isSuccess()) { // 인증 성공 // playerInfo: 인증된 사용자 정보 // 이메일 정보 조회 예시 for(auto it = playerInfo.providerInfoData.begin(); it != playerInfo.providerInfoData.end(); ++it) { hive::ProviderInfo providerInfo = it->second; if(!providerInfo.providerEmail.empty()) { std::string email = providerInfo.providerEmail; break; } } } else if (result.needExit()) { // TODO: 앱 종료 기능을 구현하세요 // Cocos2d-x 엔진 사용자 // 예) exit(0); // Unreal 엔진 사용자 // 예) UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, false); } }); |
API Reference: com.hive.AuthV4.showSignIn
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// Hive SDK AuthV4 인증 UI 요청 AuthV4.showSignIn(object : AuthV4.AuthV4SignInListener { override fun onAuthV4SignIn(result: ResultAPI, playerInfo: AuthV4.PlayerInfo?) { if (result.isSuccess) { // 인증 성공 // playerInfo: 인증된 사용자 정보 // 이메일 정보 조회 예시 playerInfo?.let { for ((key, value) in it.providerInfoData) { var providerInfo: AuthV4.ProviderInfo = value if(providerInfo.providerEmail.isNotEmpty()) { val email = providerInfo.providerEmail break } } } } else if (result.needExit()) { // TODO: 앱 종료 기능을 구현하세요 // 예) exitProcess(0) } } }) |
API Reference: com.hive.AuthV4.showSignIn
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
// Hive SDK AuthV4 인증 UI 요청 AuthV4.showSignIn(new AuthV4.AuthV4SignInListener() { @Override public void onAuthV4SignIn(ResultAPI result, AuthV4.PlayerInfo playerInfo) { if (result.isSuccess()) { // 인증 성공 // playerInfo: 인증된 사용자 정보 // 이메일 정보 조회 예시 if(playerInfo != null) { for (Map.Entry<AuthV4.ProviderType, AuthV4.ProviderInfo> entry : playerInfo.getProviderInfoData().entrySet()) { AuthV4.ProviderInfo providerInfo = entry.getValue(); if (providerInfo.getProviderEmail() != "") { String email = providerInfo.getProviderEmail(); break; } } } } else if (result.needExit()) { // TODO: 앱 종료 기능을 구현하세요 // 예) System.exit(0); } } }); |
API Reference: HIVEAuthV4:showSignIn
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
var email = String() // Hive SDK AuthV4 인증 UI 요청 AuthV4Interface.showSignIn { (result, playerInfo) in if result.isSuccess() { // 인증 성공 // playerInfo: 인증된 사용자 정보 // 이메일 정보 조회 예시 if let playerInfo = playerInfo { // providerEmail이 존재하는 providerInfo 탐색 (현재 로그인 진행된 provider) for key in playerInfo.providerInfoData.keys { if let providerInfo = playerInfo.providerInfoData[key], providerInfo.providerEmail.count > 0 { // providerEmail != "" email = providerInfo.providerEmail break } } } } else if result.needExit() { // TODO: 앱 종료 기능을 구현하세요 // 예) exit(0) } } |
API Reference: HIVEAuthV4:showSignIn
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
__block NSString* email = @""; // Hive SDK AuthV4 인증 UI 요청 [HIVEAuthV4 showSignIn:^(HIVEResultAPI *result, HIVEPlayerInfo *playerInfo) { if([result isSuccess]){ // 인증 성공 // playerInfo: 인증된 사용자 정보 // 이메일 정보 조회 예시 if(playerInfo != nil) { // providerEmail이 존재하는 providerInfo 탐색 (현재 로그인 진행된 provider) for (NSString* key in playerInfo.providerInfoData.allKeys) { HIVEProviderInfo* providerInfo = playerInfo.providerInfoData[key]; if (providerInfo != nil && providerInfo.providerEmail.length > 0) { // providerEmail != "" email = providerInfo.providerEmail; break; } } } } else if ([result needExit]) { // TODO: 앱 종료 기능을 구현하세요 // 예) exit(0); } }]; |
명시적 로그인 커스터마이징
명시적 로그인의 커스터마이징 UI는 providerTypeList
를 이용해 구현할 수 있습니다. providerTypeList
는 Hive SDK를 초기화할 목적으로 AuthV4.setup()
메서드를 호출하거나, 초기화 이후 AuthV4.Helper.getIDPList()
메서드를 호출했을 때 반환되는 응답 콜백 핸들러입니다. 게임 UI에 맞추어서 로그인 화면을 노출하거나 특정 IdP와의 연동만을 주로 노출하고 싶을 때 이 기능을 사용합니다. 커스터마이징 UI를 구현한 후에는 유저의 액션에 따라 원하는 ProviderType으로 signIn()
메서드를 호출해 로그인을 구현하세요.
- 로그인 화면에 Facebook 연동 버튼만 노출하는 UI 예시 스크린샷
다음은 커스터마이징한 명시적 로그인 UI에서 유저가 Google 로그인을 선택한 상황을 가정한 예제 소스입니다.
API Reference: hive.AuthV4.signIn
1 2 3 4 5 6 7 8 9 10 11 12 13 |
using hive; AuthV4.signIn(AuthV4.ProviderType.GOOGLE, (ResultAPI result, AuthV4.PlayerInfo playerInfo) => { if (result.isSuccess()) { // 호출 성공 // playerInfo : 인증된 사용자 정보. // ProviderType.GOOGLE의 이메일 정보 조회 예시 Dictionary<AuthV4.ProviderType, AuthV4.ProviderInfo> providerInfoData = playerInfo.providerInfoData; AuthV4.ProviderInfo providerInfo = providerInfoData[AuthV4.ProviderType.GOOGLE]; string email = providerInfo.providerEmail; } }); |
API Reference: Auth4::signIn
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#include <HIVE_SDK_Plugin/HIVE_CPP.h> AuthV4::signIn(ProviderType::GOOGLE, [=](ResultAPI const & result, PlayerInfo const & playerInfo) { if (result.isSuccess()) { // 호출 성공 // playerInfo : 인증된 사용자 정보. // ProviderType::GOOGLE의 이메일 정보 조회 예시 map<ProviderType, ProviderInfo> providerInfoData = playerInfo.providerInfoData; ProviderInfo providerInfo = providerInfoData[ProviderType::GOOGLE]; string email = providerInfo.providerEmail; } }); |
API Reference: AuthV4.signIn
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
import com.hive.AuthV4 import com.hive.ResultAPI AuthV4.signIn(AuthV4.ProviderType.GOOGLE, object : AuthV4.AuthV4SignInListener { override fun onAuthV4SignIn(result: ResultAPI, playerInfo: AuthV4.PlayerInfo?) { if (result.isSuccess) { // 호출 성공 // playerInfo: 인증된 사용자 정보 // ProviderType.GOOGLE 의 이메일 정보 조회 예시 if (playerInfo != null) { val providerInfoData = playerInfo.providerInfoData val providerInfo = providerInfoData[AuthV4.ProviderType.GOOGLE] if (providerInfo != null) { val email = providerInfo.providerEmail } } } } }) |
API Reference: com.hive.Auth4.signIn
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import com.hive.AuthV4; import com.hive.ResultAPI; AuthV4.INSTANCE.signIn(AuthV4.ProviderType.GOOGLE, (result, playerInfo) -> { if (result.isSuccess()) { // 호출 성공 // playerInfo: 인증된 사용자 정보 // ProviderType.GOOGLE 의 이메일 정보 조회 예시 if (playerInfo != null) { HashMap<AuthV4.ProviderType, AuthV4.ProviderInfo> providerInfoData = playerInfo.getProviderInfoData(); AuthV4.ProviderInfo providerInfo = providerInfoData.get(AuthV4.ProviderType.GOOGLE); if (providerInfo != null) { String email = providerInfo.getProviderEmail(); } } } }); |
API Reference: AuthV4Interface.signIn
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
import HIVEService AuthV4Interface.signIn(.Google) { result, playerInfo in if result.isSuccess() { // 호출 성공 // playerInfo: 인증된 사용자 정보. // .Google의 이메일 정보 조회 예시 if let playerInfo = playerInfo, let providerInfo = playerInfo.providerInfoData["GOOGLE"] { let email = providerInfo.providerEmail } } } |
API Reference: HIVEAuth4:signIn
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#import <HIVEService/HIVEService-Swift.h> [HIVEAuthV4 signIn:HIVEProviderTypeGoogle handler:^(HIVEResultAPI *result, HIVEPlayerInfo *playerInfo) { if ([result isSuccess]){ // 호출 성공 // playerInfo: 인증된 사용자 정보. // HIVEProviderTypeGoogle의 이메일 정보 조회 예시 if(playerInfo != nil) { HIVEProviderInfo *providerInfo = playerInfo.providerInfoData[@"GOOGLE"]; if(providerInfo != nil){ NSString *email = providerInfo.providerEmail; } } } }]; |
기기에 로그인한 IdP 계정 확인
자동 로그인은 저장된 PlayerID의 인증 토큰 키만으로 로그인하고, 명시적 로그인은 여러 IdP에 연동된 계정에 로그인합니다. 이 두 가지 경우 로그인 PlayerID의 IdP계정과 실제 단말에 로그인한 IdP 계정(DevicePlayer)이 다를 수 있습니다. 추후 업적이나 리더보드 사용에 대비해 두 계정을 통일할 수 있도록 안내 문구를 제공합니다.
다음은 IdP 정보를 확인하는 예제 코드입니다.
API Reference: AuthV4.Helper.syncAccount
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
using hive; AuthV4.ProviderType providerType = AuthV4.ProviderType.GOOGLE; AuthV4.Helper.syncAccount (providerType, delegate (ResultAPI result, AuthV4.PlayerInfo playerInfo) { switch (result.code) { case ResultAPI.Code.Success: // 정상 break; case ResultAPI.Code.AuthV4ConflictPlayer: // 계정 충돌 // ex) Hive UI 사용시 // AuthV4.Helper.showConflict(...); // or // ex) GameUI 구현시 // AuthV4.Helper.resolverConflict(...);// 현재 사용자 선택시 // AuthV4.Helper.switchAccount(...);// 사용자 전환 선택시 break; default: // 기타 예외 상황 break; } }); |
API Reference: AuthV4::Helper::syncAccount
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
#include <HIVE_SDK_Plugin/HIVE_CPP.h> using namespace std; using namespace hive; ProviderType providerType = ProviderType::GOOGLE; AuthV4::Helper::syncAccount(providerType, [=](ResultAPI const & result, shared_ptr<PlayerInfo> playerInfo) { switch (result.code) { case ResultAPI::Success: // 정상 break; case ResultAPI::AuthV4ConflictPlayer: // 계정 충돌 // ex) Hive UI 사용시 // AuthV4::Helper::showConflict(...); // or // ex) GameUI 구현시 // AuthV4::Helper::resolverConflict(...);// 현재 사용자 선택시 // AuthV4::Helper::switchAccount(...);// 사용자 전환 선택시 break; default: // 기타 예외 상황 break; } }); |
API Reference: AuthV4.Helper.syncAccount
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
import com.hive.AuthV4 import com.hive.ResultAPI val providerType = AuthV4.ProviderType.GOOGLE AuthV4.Helper.syncAccount(providerType, object : AuthV4.Helper.AuthV4HelperListener { override fun onAuthV4Helper(result: ResultAPI, playerInfo: AuthV4.PlayerInfo?) { when (result.code) { ResultAPI.Code.Success -> { // 정상 } ResultAPI.Code.AuthV4ConflictPlayer -> { // 계정 충돌 // ex) Hive UI 사용시 // AuthV4.Helper.showConflict(...); // or // ex) GameUI 구현시 // AuthV4.Helper.resolverConflict(...);// 현재 사용자 선택시 // AuthV4.Helper.switchAccount(...);// 사용자 전환 선택시 } else -> { // 기타 예외 상황 } } } }) |
API Reference: AuthV4.Helper.INSTANCE.syncAccount
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
import com.hive.AuthV4; import com.hive.ResultAPI; AuthV4.ProviderType providerType = AuthV4.ProviderType.GOOGLE; AuthV4.Helper.INSTANCE.syncAccount(providerType, (result, playerInfo) -> { switch (result.getCode()) { case Success: // 정상 break; case AuthV4ConflictPlayer: // 계정 충돌 // ex) Hive UI 사용시 // AuthV4.Helper.INSTANCE.showConflict(...); // or // ex) GameUI 구현시 // AuthV4.Helper.INSTANCE.resolverConflict(...);// 현재 사용자 선택시 // AuthV4.Helper.INSTANCE.switchAccount(...);// 사용자 전환 선택시 break; default: // 기타 예외 상황 break; } }); |
API Reference: AuthV4Interface.helper().syncAccount
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import HIVEService let providerType: ProviderType = .Google AuthV4Interface.helper().syncAccount(providerType) { result, playerInfo in switch result.getCode() { case .success: // 정상 case .authV4ConflictPlayer: // 계정 충돌 // ex) Hive UI 사용시 // AuthV4Interface.helper().showConflict(...); // or // ex) GameUI 구현시 // AuthV4Interface.helper().resolverConflict(...);// 현재 사용자 선택시 // AuthV4Interface.helper().switchAccount(...);// 사용자 전환 선택시 default: // 기타 예외 상황 break } } |
API Reference: [HIVEAuthV4 helper] syncAccount
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#import <HIVEService/HIVEService-Swift.h> HIVEProviderType providerType = HIVEProviderTypeGoogle [[HIVEAuthV4 helper] syncAccount: providerType handler: ^(HIVEResultAPI *result, HIVEPlayerInfo *playerInfo) { switch ([result getCode]) { case HIVEResultAPICodeSuccess: // 정상 break; case HIVEResultAPICodeAuthV4ConflictPlayer: // 계정 충돌 // ex) Hive UI 사용시 // [[HIVEAuthV4 helper] showConflict: ...]; // or // ex) GameUI 구현시 // [[HIVEAuthV4 helper] resolverConflict:...];// 현재 사용자 선택시 // [[HIVEAuthV4 helper] switchAccount:...];// 사용자 전환 선택시 break; default: // 기타 예외 상황 break; } }]; |
게스트 로그인
유저가 IdP를 선택하지 않고 게스트 상태로 게임을 이용할 수 있도록 게스트 로그인 기능을 지원합니다. Hive SDK가 제공하는 명시적 로그인 UI에서 게스트를 선택할 수도 있고, 게임에서 커스터마이징하여 직접 구현하는 경우에도 게스트 로그인을 구현할 수 있습니다. Windows 환경은 게스트 로그인을 지원하지 않습니다.
게스트 로그인 시에는 다음의 정책을 반드시 준수해야 합니다.
게스트 로그인 정책
-
- IdP 인증 유저와 게스트 유저 모두 게임을 동일하게 이용할 수 있게 구현하세요.
게스트 로그인 시에도 Hive 플랫폼의 기능 대부분을 이용할 수 있습니다. 때문에 여러분의 게임에서도 게스트로 로그인한 유저가 IdP 연동 유저와 동일하게 게임을 이용할 수 있도록 구현해 주세요. 예를 들면 게스트 유저도 게임 내에서 아이템을 구매하고 결제할 수 있어야 합니다. - 게스트 유저에게 로그아웃 기능을 제공하지 마세요.
유저가 게스트로 로그인 한 후 로그아웃하면 더 이상 동일한 PlayerID로 로그인이 불가합니다. 따라서 유저가 게스트로 로그인 했을 때는 로그아웃을 못하도록 로그아웃 버튼을 제공하지 마세요. - 중국 게스트 로그인 금지 정책
중국 IP를 사용할 경우에는 실명 인증된 유저만 재화를 충전·소비하는 서비스가 가능(17. 5. 1시행)하므로 중국 IP로 로그인할 수 있는 IdP 목록에 게스트 로그인이 포함되지 않습니다.
- IdP 인증 유저와 게스트 유저 모두 게임을 동일하게 이용할 수 있게 구현하세요.
게스트 로그인을 수행하기 위해서는 ProviderType.GUEST
를 파라미터로 signIn()
메서드를 호출하세요.
다음은 게스트 로그인을 수행하는 예제 코드입니다.
API Reference: hive.AuthV4.signIn
1 2 3 4 5 6 7 8 |
using hive; AuthV4.signIn(AuthV4.ProviderType.GUEST, (ResultAPI result, AuthV4.PlayerInfo playerInfo) => { if (result.isSuccess()) { // 인증 성공 // playerInfo: 인증된 사용자 정보 } }); |
API Reference: Auth4::signIn
1 2 3 4 5 6 7 8 9 10 |
#include <HIVE_SDK_Plugin/HIVE_CPP.h> using namespace std; using namespace hive; AuthV4::signIn(ProviderType::GUEST, [=](ResultAPI const & result, PlayerInfo const & playerInfo) { if (result.isSuccess()) { // 인증 성공 // playerInfo: 인증된 사용자 정보 } }); |
API Reference: AuthV4.signIn
1 2 3 4 5 6 7 8 9 10 11 |
import com.hive.AuthV4 import com.hive.ResultAPI AuthV4.signIn(AuthV4.ProviderType.GUEST, object : AuthV4.AuthV4SignInListener { override fun onAuthV4SignIn(result: ResultAPI, playerInfo: AuthV4.PlayerInfo?) { if (result.isSuccess) { // 인증 성공 // playerInfo: 인증된 사용자 정보 } } }) |
API Reference: com.hive.Auth4.signIn
1 2 3 4 5 6 7 8 9 |
import com.hive.AuthV4; import com.hive.ResultAPI; AuthV4.INSTANCE.signIn(AuthV4.ProviderType.GUEST, (result, playerInfo) -> { if (result.isSuccess()) { // 인증 성공 // playerInfo: 인증된 사용자 정보 } }); |
API Reference: AuthV4Interface.signIn
1 2 3 4 5 6 7 8 |
import HIVEService AuthV4Interface.signIn(.Guest) { result, playerInfo in if result.isSuccess() { // 인증 성공 // playerInfo: 인증된 사용자 정보 } } |
API Reference: HIVEAuth4:signIn
1 2 3 4 5 6 7 8 |
#import <HIVEService/HIVEService-Swift.h> [HIVEAuthV4 signIn: HIVEProviderTypeGuest handler: ^(ResultAPI *result, HIVEPlayerInfo *playerInfo) { if ([result isSuccess]) { // 인증 성공 // playerInfo: 인증된 사용자 정보 } }]; |
커스텀 로그인
커스텀 로그인은 맞춤형 로그인 기능으로, Hive에서 제공하는 IdP 외에 게임 자체에서 연동하는 IdP로 로그인을 구현할 수 있습니다. 인증 v4 커스텀 인증하기에 따라 커스텀 로그인 API 호출 시 사용할 인증 키(authKey)를 생성해 보세요.
커스텀 로그인 API 호출 후 콜백으로 전달 받는 PlayerInfo 클래스 인스턴스로 customProviderInfoData
데이터에 접근하여 커스텀 로그인된 유저 정보를 확인할 수 있습니다. customProviderInfoData
의 ProviderType(enum) 은 모두 CUSTOM
으로 동일하게 설정되며, ProviderName(String)으로 상세히 구분할 수 있습니다.
- 게임에서 커스텀 로그인을 구현한 IdP의 정보는 AuthV4 클래스의
setup()
및showSignIn()
메서드 호출 결과에 포함되지 않습니다.- 커스텀 로그인 최초 실행 후 playerId와 playerToken을 발급받았다면, 커스텀 로그인 API 재호출 시
authV4SessionExist(code)
의 Result API가 콜백으로 전달됩니다. 이 경우에는ProviderType.Auto
를 파라미터로signIn()
를 호출하여 기존에 로그인된 계정으로 자동 로그인을 진행해야 합니다. 아래의 예제 코드를 참조하세요.- AuthV4 클래스의
connect()
와disconnect()
메서드는 커스텀 로그인 IdP의 추가 연동 및 해제를 지원하지 않습니다.connectWithAuthKey()
와disconnectWithName()
메서드로 커스텀 로그인 IdP의 추가 연동 및 해제를 지원합니다.
다음은 커스텀 로그인을 구현하는 예제코드입니다.
API Reference: hive.AuthV4.signIn
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
// 게임에서 직접 구현한 트위터 로그인 Game.Login("CUSTOM_TWITTER", (string authKey) => { AuthV4.signInWithAuthKey(authKey, (ResultAPI result, PlayerInfo playerInfo) => { if (result.isSuccess()) { Dictionary<string, ProviderInfo> customProviderInfoData = playerInfo.customProviderInfoData; ProviderInfo providerInfo = customProviderInfoData["CUSTOM_TWITTER"]; // 다음의 유저 연동 정보 확인 providerInfo.providerType; // ProviderType.CUSTOM, 커스텀들은 Type 이 고정이니 providerName 으로 구분 필요 providerInfo.providerName; // "CUSTOM_TWITTER" providerInfo.providerUserId; // 직접 구현한 트위터 로그인에 사용된 사용자 id return; } else if (result.code == ResultAPI.Code.AuthV4SessionExist) { // 이미 playerId 및 playerToken을 발급 받아 자동로그인이 필요한 경우 // TODO: AuthV4.signIn(ProviderType.AUTO, (ResultAPI _result, PlayerInfo playerInfo) => {}); } else if (result.code == ResultAPI.Code.AuthV4NotInitialized) { // TODO: SDK 초기화 필요 } else if (result.code == ResultAPI.Code.AuthV4InvalidParam) { // TODO: 전달한 authKey의 값이 NULL 이거나 비어있는 값인지 확인 필요 } else if (result.needExit()) { // TODO: 앱 종료 기능을 구현하세요 // 예) Application.Quit(); } }); }); |
API Reference: Auth4::signIn
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
using namespace std; using namespace hive; // 게임에서 직접 구현한 트위터 로그인 Game::Login("CUSTOM_TWITTER", [=](string authKey) { AuthV4::signInWithAuthKey(authKey, [=](ResultAPI const & result, PlayerInfo const & playerInfo) { if (result.isSuccess()) { map<string, ProviderInfo> customProviderInfoData = playerInfo.customProviderInfoData; ProviderInfo providerInfo = customProviderInfoData["CUSTOM_TWITTER"]; // 다음의 유저 연동 정보 확인 providerInfo.providerType; // ProviderType::CUSTOM, 커스텀들은 Type 이 고정이니 providerName 으로 구분 필요 providerInfo.providerName; // "CUSTOM_TWITTER" providerInfo.providerUserId; // 직접 구현한 트위터 로그인에 사용된 사용자 id return; } else if (result.code == ResultAPI::Code::AuthV4SessionExist) { // 이미 playerId 및 playerToken을 발급 받아 자동로그인이 필요한 경우 // TODO: AuthV4.signIn(ProviderType::AUTO, [=](ResultAPI const & _result, PlayerInfo const & playerInfo) {}); } else if (result.code == ResultAPI::Code::AuthV4NotInitialized) { // TODO: SDK 초기화 필요 } else if (result.code == ResultAPI::Code::AuthV4InvalidParam) { // TODO: 전달한 authKey의 값이 NULL 이거나 비어있는 값인지 확인 필요 } else if (result.needExit()) { // TODO: 앱 종료 기능을 구현하세요 // Cocos2d-x 엔진 사용자 // 예) exit(0); // Unreal 엔진 사용자 // 예) UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, false); } }); }); |
API Reference: com.hive.Auth4.signIn
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
// 게임에서 직접 구현한 트위터 로그인 Game.Login("CUSTOM_TWITTER") { authKey: String -> AuthV4.signInWithAuthKey(authKey, object : AuthV4.AuthV4SignInListener { override fun onAuthV4SignIn(result: ResultAPI, playerInfo: AuthV4.PlayerInfo?) { if (result.isSuccess && playerInfo != null) { playerInfo.customProviderInfoData["CUSTOM_TWITTER"]?.let { providerInfo -> providerInfo.providerType // ProviderType.CUSTOM, 커스텀들은 Type 이 고정이니 providerName 으로 구분 필요 providerInfo.providerName // "CUSTOM_TWITTER" providerInfo.providerUserId // 직접 구현한 트위터 로그인에 사용된 사용자 id } } else if (result.needExit()) { // TODO: 앱 종료 기능을 구현하세요 // 예) exitProcess(0) } else if (result.code == ResultAPI.Code.AuthV4SessionExist) { // 이미 playerId 및 playerToken을 발급 받아 자동로그인이 필요한 경우 // TODO: AuthV4.signIn(AuthV4.ProviderType.AUTO, authV4SignInListener) } else if (result.code == ResultAPI.Code.AuthV4NotInitialized) { // TODO: SDK 초기화 필요 } else if (result.code == ResultAPI.Code.AuthV4InvalidParam) { // TODO: 전달한 authKey의 값이 NULL 이거나 비어있는 값인지 확인 필요 } } }) } |
API Reference: com.hive.Auth4.signIn
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
// 게임에서 직접 구현한 트위터 로그인 Game.Login("CUSTOM_TWITTER") { authKey: String -> AuthV4.INSTANCE.signInWithAuthKey(authKey, new AuthV4.AuthV4SignInListener() { @Override public void onAuthV4SignIn(@NonNull ResultAPI result, @Nullable AuthV4.PlayerInfo playerInfo) { if(result.isSuccess() && playerInfo != null) { HashMap<String, AuthV4.ProviderInfo> customProviderInfoData = playerInfo.getCustomProviderInfoData(); AuthV4.ProviderInfo providerInfo = customProviderInfoData.get("CUSTOM_TWITTER"); // 다음의 유저 연동 정보 확인 if (providerInfo != null){ providerInfo.getProviderType(); // AuthV4.ProviderType.CUSTOM, 커스텀들은 Type 고정이니 providerName 으로 구분 필요 providerInfo.getProviderName(); // "CUSTOM_TWITTER" providerInfo.getProviderUserId(); // 직접 구현한 트위터 로그인에 사용된 사용자 id } } else if (result.needExit()) { // TODO: 앱 종료 기능을 구현하세요 // 예) System.exit(0); } else if (result.getCode() == ResultAPI.Code.AuthV4SessionExist) { // 이미 playerId 및 playerToken을 발급 받아 자동로그인이 필요한 경우 // TODO: AuthV4.signIn(AuthV4.ProviderType.AUTO, authV4SignInListener) } else if (result.getCode() == ResultAPI.Code.AuthV4NotInitialized) { // TODO: SDK 초기화 필요 } else if (result.getCode() == ResultAPI.Code.AuthV4InvalidParam) { // TODO: 전달한 authKey의 값이 NULL 이거나 비어있는 값인지 확인 필요 } } }); } |
API Reference: HIVEAuth4:signIn
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
// 게임에서 직접 구현한 트위터 로그인 Game.login("CUSTOM_TWITTER") { (authKey) in AuthV4Interface.signInWithAuthKey(authKey) { (result, playerInfo) in if result.isSuccess() { let customProviderInfoData = playerInfo?.customProviderInfoData; let providerInfo = customProviderInfoData?["CUSTOM_TWITTER"] // 다음의 유저 연동 정보 확인 providerInfo?.providerType; // AuthProviderType, 커스텀들은 Type 이 고정이니 providerName 으로 구분 필요 providerInfo?.providerName; // "CUSTOM_TWITTER" providerInfo?.providerUserId; // 직접 구현한 트위터 로그인에 사용된 사용자 id return } else if result.getCode() == .authV4SessionExist { // 이미 playerId 및 playerToken을 발급 받아 자동로그인이 필요한 경우 // TODO: AuthV4Interface.signIn(.auto) { (result, playerInfo) in } } else if result.getCode() == .authV4NotInitialized { // TODO: SDK 초기화 필요 } else if result.getCode() == .authV4invalidParam { // TODO: 전달한 authKey의 값이 nil 이거나 비어있는 값인지 확인 필요 } else if result.needExit() { // TODO: 앱 종료 기능을 구현하세요. // 예) exit(0) } } } |
API Reference: HIVEAuth4:signIn
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
// 게임에서 직접 구현한 트위터 로그인 [Game login:@"CUSTOM_TWITTER" handler:^(NSString* authKey) { [HIVEAuthV4 signInWithAuthKey:authKey handler:^(HIVEResultAPI* result, HIVEPlayerInfo* playerInfo) { if (result.isSuccess) { NSDictionary<NSString*, HIVEProviderInfo*>* customProviderInfoData = playerInfo.customProviderInfoData; ProviderInfo* providerInfo = [customProviderInfoData objectForKey:@"CUSTOM_TWITTER"]; // 다음의 유저 연동 정보 확인 providerInfo.providerType; // HIVEProviderTypeCustom, 커스텀들은 Type 이 고정이니 providerName 으로 구분 필요 providerInfo.providerName; // "CUSTOM_TWITTER" providerInfo.providerUserId; // 직접 구현한 트위터 로그인에 사용된 사용자 id return; } else if (result.getCode == HIVEResultAPICodeAuthV4SessionExist) { // 이미 playerId 및 playerToken을 발급 받아 자동로그인이 필요한 경우 // TODO: [HIVEAuthV4 signIn:HIVEProviderTypeAuto, handler:^(HIVEResultAPI* _result, HIVEPlayerInfo* playerInfo) {}]; } else if (result.getCode == HIVEResultAPICodeAuthV4NotInitialized) { // TODO: SDK 초기화 필요 } else if (result.getCode == HIVEResultAPICodeAuthV4InvalidParam) { // TODO: 전달한 authKey의 값이 NULL 이거나 비어있는 값인지 확인 필요 } else if (result.needExit) { // TODO: 앱 종료 기능을 구현하세요. // 예) exit(0); } }]; }]; |
유저네임
미국 COPPA 등의 이슈로 인해 미국과 미국령에서 접속하여 IdP로 로그인하는 경우에는 추가적인 유저 식별을 위한 인증 처리를 할 수 있도록 유저네임을 입력해야 합니다.
참고로, 미국령에 포함되는 나라는 아메리칸 사모아(AS), 괌(GU), 북마리아나 군도(MP), 푸에르토리코(PR), 미국령 소군도(UM), 미국령 버진아일랜드(VI)입니다.
유저 식별을 위한 유저네임 입력 화면은 아래와 같습니다.
- 유저네임 입력화면은 유저 식별 용도로만 사용되므로, 최초 IdP 연동 시 1회만 노출되며 그 외에는 노출되지 않습니다.
- 게스트 로그인 시에는 유저네임 입력화면이 노출되지 않습니다.
인증 토큰 키 유효성 검증
게임 서버에서는 로그인 성공 후 반환 된 Token, playerId, DID 정보를 이용하여 인증 토큰키의 유효성을 검증할 수 있습니다. Hive 인증에서는 멀티 디바이스 로그인과 중복 접속을 허용합니다.
동일한 계정으로 중복 접속을 허용하지 않을 경우, 게임 서버는 먼저 접속한 기기에 안내 메시지를 노출시킨 후 게임을 종료하고 나중에 접속한 기기에서 게임이 유지되도록 처리합니다. 이때 게임을 종료하지 않은 채 중복 접속할 경우 게임 플레이 기록이 정상적으로 반영되지 않을 수 있습니다. 해당 기능을 구현하려면 검증을 완료한 토큰 키를 관리하거나 이를 이용한 게임 자체의 세션 키를 관리하여 처리해야 합니다.
해당 기능은 인증 토큰키 유효성 검증 Server API를 참고하여 구현하세요.
Hive 톡플러스 로그인 토큰 획득
인증 v4 인터페이스를 통해 signIn()
완료 후 AuthV4.getHiveTalkPlusLoginToken API를 호출하여 획득한 로그인 토큰을 Hive 톡플러스 로그인 시 사용합니다. (관련 가이드: Hive 톡플러스 로그인 가이드)
1 2 3 4 5 6 |
AuthV4.getHiveTalkPlusLoginToken((ResultAPI result, String loginToken) => { if (result.isSuccess()) { // SUCCESS // TODO: 전달받은 loginToken 값 확인 후 HiveTalkPlus 로그인 진행 } }); |
1 2 3 4 5 6 7 8 |
// Kotlin AuthV4.getHiveTalkPlusLoginToken(object : AuthV4.AuthV4GetHiveTalkPlusLoginTokenListener { override fun onAuthV4GetHiveTalkPlusLoginToken(resultApi: ResultAPI, loginToken: String?) { if (resultApi.isSuccess) { // SUCCESS } } } |
1 2 3 4 5 6 7 8 9 |
// Java com.hive.AuthV4.INSTANCE.getHiveTalkPlusLoginToken(new com.hive.AuthV4.AuthV4GetHiveTalkPlusLoginTokenListener() { @Override public void onAuthV4GetHiveTalkPlusLoginToken(@NotNull ResultAPI result, @Nullable String loginToken) { if (result.isSuccess()) { // SUCCESS } } }); |
1 2 3 4 5 6 |
// Swift AuthV4Interface.getHiveTalkPlusLoginToken { result, loginToken in if (result.isSuccess()) { // SUCCESS } } |
1 2 3 4 5 6 |
// Objective-c [HIVEAuthV4 getHiveTalkplusLoginToken:^(HIVEResultAPI* result, NSString* loginToken) { if ([result isSuccess]) { // SUCCESS } }]; |
백그라운드에서 IdP 계정 변경 감지
유저가 게임 실행 중에 기기 설정으로 이동하여 Apple Game Center 또는 Google Play 게임 계정을 변경할 수 있습니다. 게임 실행 중에 IdP 계정이 현재 PlayerID에 IdP 계정과 다른지 여부를 확인해야 하는 경우 setProviderChangedListener()
를 SDK 초기화 이후 호출하세요. 해당 API를 호출하면 게임 Resume시 기기에 설정된 IdP계정이 변경되었다는 이벤트를 받을 수 있습니다.
iOS는 Apple Game Center, Android는 Google Play 게임의 계정이 변경 시에 동작하며 현재 로그인 된 PlayerID가 해당 IdP에 연동되어 있을 경우에만 응답이 전달됩니다. IdP 계정 변경 이벤트를 받을 경우, 유저에게 기기에 로그인된 IdP 계정을 사용할지 여부를 유저에게 선택할 수 있도록 UI를 구성합니다. 유저가 기기에 로그인된 IdP 계정을 선택하면, signOut
을 호출하여 로그아웃 시킨 후, 묵시적 로그인을 진행합니다.
다음은 유저가 게임을 다시 시작했을 때, 기기에 설정된 IdP 계정이 변경되었다는 이벤트를 받도록 설정하는 예제 코드입니다.
API Reference: hive.AuthV4.setProviderChangedListener
1 2 3 4 5 6 7 8 9 10 11 |
using hive; AuthV4.setProviderChangedListener((ResultAPI result, AuthV4.ProviderInfo providerInfo) => { if (!result.isSuccess()) { return; } if (providerInfo != null && providerInfo.providerType == AuthV4.ProviderType.APPLE) { // GameCenter 사용자 정보 변경 } }); |
API Reference: AuthV4::setProviderChangedListener
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#include <HIVE_SDK_Plugin/HIVE_CPP.h> using namespace std; using namespace hive; AuthV4::setProviderChangedListener([=](ResultAPI const & result, ProviderInfo const & providerInfo) { if (!result.isSuccess()) { return; } if (providerInfo != null && providerInfo.providerType == ProviderType::GOOGLE) { // Google Play Game Service 계정 변경 } }); |
API Reference: AuthV4.setProviderChangedListener
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import com.hive.AuthV4 import com.hive.ResultAPI AuthV4.setProviderChangedListener(object : AuthV4.AuthV4CheckProviderListener { override fun onDeviceProviderInfo(result: ResultAPI, providerInfo: AuthV4.ProviderInfo?) { if (!result.isSuccess) { return } if (providerInfo != null && providerInfo.providerType == AuthV4.ProviderType.GOOGLE) { // Google Play Game Service 계정 변경 } } }) |
API Reference: com.hive.AuthV4.setProviderChangedListener
1 2 3 4 5 6 7 8 9 10 11 12 |
import com.hive.AuthV4; import com.hive.ResultAPI; AuthV4.INSTANCE.setProviderChangedListener((result, providerInfo) -> { if (!result.isSuccess()) { return; } if (providerInfo != null && providerInfo.getProviderType() == AuthV4.ProviderType.GOOGLE) { // Google Play Game Service 계정 변경 } }); |
API Reference: AuthV4Interface.setProviderChangedListener
1 2 3 4 5 6 7 8 9 10 11 |
import HIVEService AuthV4Interface.setProviderChangedListener() { result, providerInfo in if !result.isSuccess() { return } if let providerInfo = providerInfo, providerInfo.providerType == .Apple { // GameCenter 사용자 정보 변경 } } |
API Reference: HIVEAuthV4:setProviderChangedListener
1 2 3 4 5 6 7 8 9 10 11 |
#import <HIVEService/HIVEService-Swift.h> [HIVEAuthV4 setProviderChangedListener: ^(HIVEResultAPI *result, ProviderInfo *providerInfo) { if (![result isSuccess]) { return; } if (providerInfo != nil && providerInfo.providerType == HIVEProviderTypeApple) { // GameCenter 사용자 정보 변경 } }]; |
게임 데이터 초기화
게임 데이터를 초기화할 때 로그아웃을 호출하지 마세요. PlayerID가 삭제되지 않기 때문에 계정간 충돌이 발생할 수 있습니다. 현재 로그인한 계정으로 계속 플레이할 수 있어야 하므로 유저가 명시적으로 요청하기 전에는 로그아웃을 호출하지 않도록 구현하세요.
로그아웃
Hive 로그인을 수행하였다면 PlayerID 와 인증 토큰 키가 발급된 상태입니다. 로그아웃이란 PlayerID와 인증 토큰 키를 초기화 하는 기능을 수행합니다. signOut()
메서드를 호출해 로그아웃을 완료하면 게임 타이틀로 이동하고 타이틀 클릭 시 명시적 로그인을 수행합니다.
다음은 로그아웃을 수행하는 예제 코드입니다.
API Reference: hive.AuthV4.signOut
1 2 3 4 5 6 7 8 9 10 11 12 |
using hive; AuthV4.Helper.signOut (delegate (ResultAPI result, AuthV4.PlayerInfo playerInfo) { switch(result.code) { case ResultAPI.Code.Success: // 로그아웃 성공 break; default: // 기타 예외 상황 break; } }); |
API Reference: AuthV4::signOut
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#include <HIVE_SDK_Plugin/HIVE_CPP.h> using namespace std; using namespace hive; AuthV4::Helper::signOut([=](ResultAPI const & result, shared_ptr playerInfo) { switch (result.code) { case ResultAPI::Success: // 로그아웃 성공 break; default: // 기타 예외 상황 break; } }); |
API Reference: AuthV4.Helper.signOut
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
import com.hive.AuthV4 import com.hive.ResultAPI AuthV4.Helper.signOut(object : AuthV4.Helper.AuthV4HelperListener { override fun onAuthV4Helper(result: ResultAPI, playerInfo: AuthV4.PlayerInfo?) { when (result.code) { ResultAPI.Code.Success -> { // 로그아웃 성공 } else -> { // 기타 예외 상황 } } } }) |
API Reference: AuthV4.Helper.INSTANCE.signOut
1 2 3 4 5 6 7 8 9 10 11 12 13 |
import com.hive.AuthV4; import com.hive.ResultAPI; AuthV4.Helper.INSTANCE.signOut((result, playerInfo) -> { switch (result.getCode()) { case Success: // 로그아웃 성공 break; default: // 기타 예외 상황 break; } }); |
API Reference: AuthV4Interface.helper().signOut()
1 2 3 4 5 6 7 8 9 10 |
import HIVEService AuthV4Interface.helper().signOut() { result, playerInfo in switch result.getCode() { case .success: // 로그아웃 성공 default: // 기타 예외 상황 break }} |
API Reference: [HIVEAuthV4 helper] signOut
1 2 3 4 5 6 7 8 9 10 11 12 |
#import <HIVEService/HIVEService-Swift.h> [[HIVEAuthV4 helper] signOut: ^(HIVEResultAPI *result, HIVEPlayerInfo *playerInfo) { switch ([result getCode]) { case HIVEResultAPICodeSuccess: // 로그인 성공 break; default: // 기타 예외 상황 break; } }]; |
Game Center 취소 안내 문구
언어 | 문구 |
---|---|
한국어 | Apple Game Center 로그인이 취소되었습니다. Game Center 계정과 연동하려면 [설정 > Game Center]에서 로그인한 후 다시 시도해주세요. |
영어 | Your login to the Game Center has been canceled. Log in at [Settings> Game Center] to sync to the Game Center Account and try again. |
일본어 | Apple Game Center ログインがキャンセルされました。 Game Center アカウントと連動するには [設定 > Game Center] にログインした後、再度お試しください。 |
중국어 간체 | Apple Game Center已退出登录。 若想与Game Center账号同步,请在设备[设置>Game Center]中重新登录后再试。 |
중국어 번체 | 登入Apple Game Center已取消。 若想連動Game Center帳號,請至[設定 > Game Center]登入後,再試一次。 |
프랑스어 | Ta connexion au Game Center a été annulée. Connecte-toi dans [Réglages > Game Center] pour synchroniser ton compte Game Center et essaie de nouveau. |
독일어 | Das Einloggen ins Apple Game Center wurde abgebrochen. Die Synchronisation mit dem Game Center-Konto läuft über [Einstellungen > Game Center]. Logge dich ein und versuche es erneut. |
러시아어 | Ваш авторизация в Game Center была отменена. Авторизуйтесь в Game Center через [Настройки > Game Center] и повторите попытку. |
스페인어 | Tu Inicio de Sesión en Game Center ha sido cancelado. Inicia Sesión en [Configuración>Game Center] para sincronizar a la Cuenta de Game Center, e inténtalo de nuevo. |
포르투갈어 | O seu login no Game Center foi cancelado. Faça o login em [Configurações>Game Center] para sincronizar com a Conta do Game Center e tente novamente. |
인도네시아어 | Login ke Apple Game Center telah dibatalkan. Hubungkan akun Game Center dengan login di [Pengaturan > Game Center] dan coba lagi. |
말레이시아어 | Log masuk ke Game Center anda telah dibatalkan. Log masuk di [Tetapan>Game Center] untuk disegerakkan ke Akaun Game Center dan cuba lagi. |
베트남어 | Đã hủy bỏ đăng nhập vào Apple Game Center. Đăng nhập tại [Cài đặt > Game Center] để đồng bộ với tài khoản Game Center và thử lại. |
태국어 | การล็อกอินเข้า Game Center ของคุณถูกยกเลิก ล็อกอินที่ [การตั้งค่า>Game Center] เพื่อเชื่อมต่อบัญชี Game Center และโปรดลองอีกครั้ง |
이탈리아어 | L’accesso all’Apple Game Center è stato annullato. Fai log-in su [Impostazioni > Game Center] per sincronizzare il tuo account con il Game Center e riprova. |
터키어 | Apple Oyun Merkezine girişiniz iptal edilmiştir. Oyun Merkezi Hesabına ulaşmak için [Ayarlar>Oyun Merkezi]’nden giriş yapın ve tekrar deneyin. |
아랍어 | تم إلغاء تسجيل الدخول إلى مركز الألعاب. سجل الدخول إلى [الإعدادات> مركز الألعاب] للمزامنة مع حساب مركز الألعاب وحاول مرة أخرى. |