마케팅 어트리뷰션(Hive 사용자 추적 툴)은 Adjust, Singular, AppsFlyer를 동시에 적용하기 쉽도록 묶어 놓은 패키지이다. 프로젝트 별로 적용 여부를 따진 후, 각 모듈 별로 키를 발급해 적용한다.
- Adjust: https://www.adjust.com
- Singular: https://app.singular.net
- AppsFlyer: https://hq1.appsflyer.com/
Key 설정을 위해 마케팅 어트리뷰션 툴 가이드를 참고하세요.
기본으로 지원하는 기능은 아래와 같다.
- 게임 내 이벤트 추적
- 과금 추적
Tracking Module Initialize
- 모듈의 키 값과 이벤트 키 값을 설정
- 최초 모듈 초기화 시 발급받은 키 값을 입력하거나 Unity의 경우 키 값을 입력할 인스펙터를 제공함
필수 발급 키 값
- Adjust는 기본 Update와 Purchase, TutorialComplete용 키 값 발급 필요
- Singular는 별도의 키 값을 발급할 필요 없이 코드에 추가해서 사용
TutorialComplete를 제외한 다른 값(Purchase, Install, Open, Update)은 모듈에서 호출하기 때문에 게임 내에서는 호출하지 않아야 한다. 단, Adjust의 경우 Update에 대한 키 값을 발급받아 클라이언트에서 따로 키 값을 추가해주어야 한다.
트래킹 모듈의 키 값 설정 시 Adjust는 발급받은 이벤트 토큰(Token) 값을 입력해야 한다. Singular는 Singular 콘솔 페이지에서 별도 발급 및 추가 없이 코드에서 원하는 키 값을 추가하여 사용하면 해당 키 값이 집계된다.
C2SModuleTracker_SendEvent
이벤트를 전송한다.
argument type | type | desc | platform | 비고 |
---|---|---|---|---|
event | string | 이벤트 이름은 Initialize에서 Matching에 설정한 키로 사용 |
all | 1.5.0 |
revenue | Dictionary (unity) | 설정할 경우 수익 측정 이벤트를 발생 | all | 1.5.0 |
key-value for revenue
argument type | type | desc | platform | 비고 |
---|---|---|---|---|
title | string | (필수) 상품 이름 | all | 1.5.0 |
description | string | (필수) 상품 설명 | all | 1.5.0 |
currency | string | (필수) 통화 코드 (https://en.wikipedia.org/wiki/ISO_4217) 규격에 맞게 입력 (대문자로 사용) |
all | 1.5.0 |
price | string | (필수) 상품 가격 (float 형태) | all | 1.5.0 |
itemCount | int | (필수) 상품 개수 | all | 1.5.0 |
transactionId | string | 중복구매방지 refId 안드로이드 : order Id iOS : (영수증 검증 이후의) transactionId |
all | 1.11.3+ |
Returns
YES일 경우 성공, NO일 경우 실패
C2SModuleTracker_SetEnable
Tracker의 이벤트 전송에 대한 활성화 여부를 설정한다.
argument type | type | desc | platform | 비고 |
---|---|---|---|---|
Adjust | bool | Adjust모듈의 이벤트 전송 활성화 여부 | all | 1.5.0 |
Singular | bool | Singular모듈의 이벤트 전송 활성화 여부 | all | 1.5.0 |
AppsFlyer | bool | AppsFlyer모듈의 이벤트 전송 활성화 여부 | all | 1.19.8+ |
Returns
YES일 경우 성공, NO일 경우 실패
샘플 코드
public static bool C2SModule.Tracker.SendEvent(C2SModule.Parameter arg, out C2SModule.Error error,
C2SModule.CompletionHandler completionHandler);
– 사용자 추적툴 이벤트 발생
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
[일반 이벤트 사용시] C2SModule.Error error; C2SModule.Parameter arg; arg["event"] = "TutorialComplete"; if( !C2SModule.Tracker.SendEvent( arg, out error ) ) { // Error 시 처리 } [수익 측정 이벤트 사용시] C2SModule.Error error; Dictionary<string,object> revenueArg = new Dictionary<string,object>(); revenueArg["title"] = "item1"; revenueArg["description"] = "item1 desc"; revenueArg["currency"] = "USD"; revenueArg["price"] = "0.99"; revenueArg["itemCount"] = 1; C2SModule.Parameter arg; arg["event"] = "Purchase"; //< 사전 정의된 이벤트 이름. arg["revenue"] = revenueArg; if( !C2SModule.Tracker.SendEvent( arg, out error ) ) { // Error 시 처리 } |
public static bool C2SModule.Tracker.SetEnable(C2SModule.Parameter arg, out C2SModule.Error error,
C2SModule.CompletionHandler completionHandler);
– 사용자 추적툴 사용여부 설정
1 2 3 4 5 6 7 8 |
C2SModule.Error error; C2SModule.Parameter arg; arg["Adjust"] = true; arg["Singular"] = true; arg["AppsFlyer"] = true; if( !C2SModule.Tracker.SetEnable( arg, out error ) ) { // Error 시 처리 } |
– 사용자 추적툴 이벤트 발생
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 |
[일반 이벤트 보내는 예시] TSharedPtr< FJsonObject> arg = MakeShareable(new FJsonObject); arg->SetStringField(TEXT("event"), TEXT("TutorialComplete")); FString OutputString; TSharedRef< TJsonWriter<> > Writer = TJsonWriterFactory<>::Create(&OutputString); FJsonSerializer::Serialize(arg.ToSharedRef(), Writer); FHiveSDKModule::Get().HiveSDKUETracker_SendEvent(OutputString); [수익 측정 이벤트 예시] TSharedPtr< FJsonObject> arg = MakeShareable(new FJsonObject); arg->SetStringField(TEXT("event"), TEXT("Purchase")); TSharedPtr< FJsonObject> argRevenueInfo = MakeShareable(new FJsonObject); argRevenueInfo->SetStringField(TEXT("title"), TEXT("potion")); argRevenueInfo->SetStringField(TEXT("description"), TEXT("potion")); argRevenueInfo->SetNumberField(TEXT("itemCount"), 1); argRevenueInfo->SetStringField(TEXT("currency"), TEXT("KRW")); argRevenueInfo->SetStringField(TEXT("price"), TEXT("1000")); arg->SetObjectField(TEXT("revenue"),argRevenueInfo); FString OutputString; TSharedRef< TJsonWriter<> > Writer = TJsonWriterFactory<>::Create(&OutputString); FJsonSerializer::Serialize(arg.ToSharedRef(), Writer); FHiveSDKModule::Get().HiveSDKUETracker_SendEvent(OutputString); |
– 사용자 추적툴 사용여부 설정
1 2 3 4 5 6 7 8 9 |
TSharedPtr< FJsonObject> arg = MakeShareable(new FJsonObject); arg->SetBoolField(TEXT("Adjust"), true); // true : 사용, false : 사용 안 함 arg->SetBoolField(TEXT("Singular"), true); FString OutputString; TSharedRef< TJsonWriter<> > Writer = TJsonWriterFactory<>::Create(&OutputString); FJsonSerializer::Serialize(arg.ToSharedRef(), Writer); FHiveSDKModule::Get().HiveSDKUETracker_SetEnable(OutputString); |
+(BOOL)SetEnable:(id)arg error:(NSError**)error completionHandler:(void(^)(NSDictionary *, NSError*))
completionHandler;
– 사용자 추적툴 이벤트 발생
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 |
[일반 이벤트 보내는 예시] -(void)tutorialComplete { NSError* error = nil; NSDictionary* arg = @{@"event":@"TutorialComplete"}; [C2STracker SendEvent:arg error:&error completionHandler:^(NSDictionary *, NSError *) { //이벤트 완료. }]; } [수익 측정 이벤트 예시] -(void)revenueEvent { NSError* error = nil; NSDictionary* arg = @{@"event":@"Purchase", @"revenue":@{ @"title"", //아이템이름 @"description":@"item1", //아이템설명 @"currency":@"USD", //커런시코드 @"price":@"0.99", //아이템가격 @"itemCount":@1, //아이템 수량 } }; [C2STracker SendEvent:arg error:&error completionHandler:^(NSDictionary *, NSError *) { //이벤트 완료. }]; } |
+(BOOL)SetEnable:(id)arg error:(NSError**)error completionHandler:(void(^)(NSDictionary *, NSError*))
completionHandler;
– 사용자 추적툴 사용여부 설정
1 2 3 4 5 6 7 8 |
NSError* error = nil; NSDictionary* arg = @{@"Singular":@true, @"Adjust":@true, @"AppsFlyer":@true}; //true false로 사용여부 설정. [C2SModuleTracker SetEnable:arg error:&error completionHandler:^(NSDictionary *, NSError *) { //이벤트 완료. }]; } |
C2SModule_Cocos2dx::C2SModuleCompletionHandler* completionHandler = NULL);
– 사용자 추적툴 이벤트 발생
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 |
[일반 이벤트 보내는 예시] Json::Value arg; arg["event"] = "TutorialComplete"; // initialize때 등록한 이벤트 문자열 Json::StyledWriter writer; std::string strJSON = writer.write(arg); C2SModule_Cocos2dx::C2SModuleError error; if( ::C2SModuleTracker_SendEvent( strJSON.c_str(), &error ) == false ) { CCLog( "====>>>> Tracking SendEvent error (%s)", error.get()->GetMessage() ); } [수익 측정 이벤트 예시] Json::Value arg; arg["event"] = "Purchase"; Json::Value argRevenueInfo; argRevenueInfo["title"] = "healing potion"; argRevenueInfo["description"] = "healing potion desc"; argRevenueInfo["itemCount"] = 1; argRevenueInfo["currency"] = "KRW"; argRevenueInfo["price"] = "1000"; arg["revenue"] = argRevenueInfo; Json::StyledWriter writer; std::string strJSON = writer.write(arg); C2SModule_Cocos2dx::C2SModuleError error; if( ::C2SModuleTracker_SendEvent( strJSON.c_str(), &error ) == false ) { CCLog( "====>>>> Tracking SendEvent error (%s)", error.get()->GetMessage() ); } |
pkError, C2SModule_Cocos2dx::C2SModuleCompletionHandler* completionHandler = NULL);
– 사용자 추적툴 사용여부 설정
1 2 3 4 5 6 7 8 9 10 |
Json::Value arg; arg["Adjust"] = false; // true : 사용, false : 사용 안 함 arg["Singular"] = true; arg["AppsFlyer"] = true; Json::StyledWriter writer; std::string strJSON = writer.write(arg); C2SModule_Cocos2dx::C2SModuleError error; if( ::C2SModuleTracker_SetEnable( strJSON.c_str(), &error ) == false ) { CCLog( "====>>>> Tracking SetEnable error (%s)", error.get()->GetMessage() ); } |
C2SModuleTracker_ShowConsentMode
EU 및 EEA 지역에서 2024년 3월 6일부터 맞춤 광고 제공을 위한 개인 정보를 수집할 경우 유저로부터 명시적 동의를 받도록 하는 DMA 규정이 의무화 됨에 따라, 개인정보 수집 동의 여부를 체크할 수 있는 동의 배너를 노출합니다.
API 사용을 위한 사전 설정
Android
App 수준의 build.gradle에서 “Analytics Consent-Mode” 라이브러리를 선언합니다.
1 2 3 |
implementation "com.com2us.android.hive:hive-analytics-consent-mode:${HIVE_SDK_VERSION}" // BoM을 사용하지 않을 경우 HiveSDK 버전 입력 |
iOS
Podfile에서 “Analytics Consent-Mode” 프레임워크를 선언합니다.
1 2 3 |
pod 'HiveAnalyticsConsentMode', '${HIVE_SDK_VERSION}' # HiveSDK 버전 입력 |
Request
ARGUMENT NAME | TYPE | DESC | PLATFORM | 비고 |
---|---|---|---|---|
checkCmp | bool | (optional) TCF 규격에 맞게 저장된 파일이 있다면 해당 파일을 읽어 동의 정보 설정 여부이며 기본값은 true (서드 파티 동의 관리 플랫폼(CMP)과 연동 참고) |
all | 24.1.1+ |
type | string |
|
all | 24.1.1+ |
Response
ARGUMENT NAME | TYPE | DESC | PLATFORM | 비고 |
---|---|---|---|---|
type | string | 호출 타입 (require / always ) |
all | 24.1.1+ |
consentStatus | Array | 동의 배너에 포함되는 Provider 상태 정보 | all | 24.1.1+ |
consentStatus 배열 타입
ARGUMENT NAME | TYPE | DESC | PLATFORM | 비고 |
---|---|---|---|---|
providerName | string | Provider 이름
|
all | 24.1.1+ |
consentForDataUsage | string |
|
all | 24.1.1+ |
consentForPersonalization | string |
|
all | 24.1.1+ |
consentDate | long | 동의를 진행한 시각. 단위는 millisecond. | all | 24.1.1+ |
expiredDate | long | 동의가 만료되는 시각. 단위는 millisecond. | all | 24.1.1+ |
샘플 코드
public static bool C2SModule.Tracker.ShowConsentMode(C2SModule.Parameter arg, out C2SModule.Error error, C2SModule.CompletionHandler completionHandler);
– 동의 배너를 노출
1 2 3 4 5 6 7 8 9 10 11 |
C2SModule.Error error; C2SModule.Parameter arg; arg["type"] = "require"; arg["checkCmp"] = true; if( !C2SModule.Tracker.ShowConsentMode( arg, out error ) ) { // Error 시 처리 } |
+(BOOL)ShowConsentMode:(id)arg error:(NSError**)error completionHandler:(void(^)(NSDictionary *, NSError*))
completionHandler;
– 동의 배너를 노출
1 2 3 4 5 6 7 |
NSError* error = nil; NSDictionary* arg = @{@"type":@"require", @"checkCmp":@true}; [C2STracker ShowConsentMode:arg error:&error completionHandler:^(NSDictionary *, NSError *) { //이벤트 완료. }]; |
C2SModule_Cocos2dx::C2SModuleCompletionHandler* completionHandler = NULL);
– 동의 배너를 노출
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Json::Value arg; arg["type"] = "require"; arg["checkCmp"] = true; Json::StyledWriter writer; std::string strJSON = writer.write(arg); C2SModule_Cocos2dx::C2SModuleError error; if( ::C2SModuleTracker_ShowConsentMode( strJSON.c_str(), &error ) == false ) { CCLog( "====>>>> Tracking ShowConsentMode error (%s)", error.get()->GetMessage() ); } |
서드 파티 동의 관리 플랫폼(CMP)과 연동
동의 배너 팝업을 노출할 때 생성하는 TCF 규격에 맞는 파일을 활용하면 서드 파티 동의 관리 플랫폼(CMP)과 중복으로 동의 배너 UI를 노출하지 않도록 설정할 수 있습니다. C2SModuleTracker_ShowConsentMode checkCmp 파라미터가 true
인 경우, TCF 규격에 맞게 저장된 파일이 있다면 해당 파일을 읽어 파일에 있는 업체는 동의 설정한 것으로 간주합니다. 예를 들어, Hive Adiz를 사용할 경우 Google AdMob 콘솔에 접속하여 GDPR 메시지를 작성한 후, Hive Adiz를 초기화해볼 수 있습니다. CMP에서 동의 배너를 중복하여 노출하지 않으려면 아래와 같은 순서로 파트너 설정을 진행합니다. 설정에 앞서 동의를 받아야 하는 업체를 파트너로 설정합니다. 설정에 대한 자세한 사항은 HIVE ADIZ > GDPR 메시지 작성를 참고하세요.
- 좌측 메뉴에서 개인 정보 보호 및 메시지를 클릭
- 동의 관리 솔루션 > 유럽 규정 메뉴에서 ‘GDPR’ 설정을 클릭. 이후 메시지를 입력하고, 파트너사를 설정할 수 있는 페이지로 이동
- 광고 파트너 검토 > 맞춤 광고 파트너 항목에서 수정 버튼을 클릭(이후, 광고 파트너 목록을 확인하고 필요한 파트너를 선택하도록 수정할 수 있음)
- 동의를 받아야 하는 업체명을 확인하여 체크. (파트너 목록에서는 검색 기능을 제공하지 않으므로 Ctrl+F로 검색하시면 편리함.)
– AppsFlyer 동의 필요 → Appsflyer 체크
– Adjust 동의 필요 → Adjust GmbH 체크
– Singular 동의 필요 → Singular Labs Inc. 체크
※Google은 자동으로 선택되어 있음
- 저장 후, 선택한 파트너사가 목록에 노출되는 것을 확인할 수 있음
마케팅 어트리뷰션별 참고 사항
마케킹 어트리뷰션별 참고 사항에 대한 안내입니다.
Adjust Signature 연동
SDK Signature V1(구 버전)을 사용했다면 서명 라이브러리를 연동하기 전에 SDK Signature V3 마이그레이션이 필요합니다. 처음 SDK Signature를 사용하는 경우 Adjust와의 계약 사항을 확인해야 합니다. 다음 안내에 따라 SDK Signature V3 설정을 진행합니다.
Android 환경에서 SDK Signature를 사용하려면 다음 안내를 따릅니다.
- Android/external 폴더에 포함된 adjust-android-signature-xxxxxx.aar 라이브러리를 복사하여 프로젝트 libs 폴더에 추가합니다.
- Adjust 대시보드로 이동한 후 디지털 인증서 핑거프린트를 Adjust의 허용 리스트에 추가 안내 페이지에 따라 핑거 프린트를 설정합니다.
- 핑거 프린트 확인은 Adjust suite에서 인증서 설정 페이지를 참고하여 앱에서 사용하는 인증서 방식을 따라 확인할 수 있습니다.
iOS 환경에서 SDK Signature를 사용하려면 Podfile에 ProviderAdjust Subspec을 추가합니다.
1 2 3 |
pod 'HiveAnalyticsProviderAdjust', $HIVE_SDK_VERSION pod 'HiveAnalyticsProviderAdjust/SignatureV3', $HIVE_SDK_VERSION ... |
SDK Signature 연동 상태 확인
SDK Signature 서명 라이브러리가 잘 연동되었는지 확인하려면, Hive SDK 초기화 시 Hive 샌드박스 서버 환경으로 설정해야 합니다. 그 다음, 아래 내용을 따릅니다(자세한 내용은 Adjust 문서를 참고 바랍니다.)
- 설치 정보가 전송되도록 테스트 기기에서 앱을 완전히 삭제합니다.
- Adjust 대시보드 테스팅 콘솔로 이동하여 테스트 기기 정보를 입력 후 기기 삭제를 눌러 모두 삭제합니다.
- 테스트 기기에 앱을 설치한 다음, Adjust로 설치 정보가 전송될 수 있도록 앱을 실행합니다.
- 테스팅 콘솔에 테스트 기기의 광고 ID 또는 IDFA 를 입력하여 설치 이벤트 정보를 불러옵니다.
- SignatureVerificationResult(서명 인증 결과) 필드에 Valid Signature(유효한 서명) 값이 표시되어야 함
- SignatureVersion(서명 버전) 필드 값이 3인지 확인
SDK Signature 마이그레이션
SDK Signature V3를 사용하려면 이전 SDK Signature 버전 설정을 제거해야 합니다.