Skip to content

Manual event tracking

Aside from Install, Open, Update, and Purchase (in-app purchase) which are tracked automatically by Hive SDK, you can manually track the necessary events you want. To do this, you need to register the event to the dashboard of each attribution. For example, you can track specific events like the completion of your game tutorial (TutorialComplete) or the completion of a mission objective (MissionClear). You should implement the manual event tracking after finishing setting up the automatic event tracking.

Manual Event Tracking with Adjust

  1. To track custom events manually, register the events on Adjust dashboard, and get the app token and the event tokens. The app token can be obtained on the dashboard main page, and the event tokens on Dashboard > All Settings > Events. Refer to the Adjust dashboard guide to learn how to get the tokens.
  2. Add the app token and the event token of each event on hive_config.xml. For more details, see the example codes below.
  3. The Adjust dashboard provides SDK Signature V3 for app spoofing prevention. To use the SDK Signature, you must review the contractual terms with Adjust.

    <providers>
    <!-- (skipped) -->
    <!-- Do not set the id field of the Adjust node. -->
    <!-- The name field of the Adjust node is fixed to "Adjust." -->
    <!-- The name field of the event node is defined by the game studio. But once it is set, it should be the same for the name field of all other marketing attributions for the sendEvent() request.-->
    <!-- From Hive SDK v4 25.0.0, id, secretId, info1~4 are no longer used as of the application of Adjust v5 -->
    <Adjust name="Adjust" key="APP_TOKEN">
            <events>
                    <event name="TutorialComplete" value="TutorialComplete_EVENT_TOKEN"/>
                    <event name="MissionClear" value="MissionClear_EVENT_TOKEN"/>
            </events>
    <!-- (skipped) -->
    </Adjust>
    </providers>
    
  4. Send events by calling the Analytics API sendEvent(). When sending events, use the <event> tag added to hive_config.xml. Among the <event> tag values, name is used as a parameter when calling the API, and value can be checked in the dashboard of the corresponding attribution.

    • Analytics.sendEvent("TutorialComplete");
    • Analytics.sendEvent("MissionClear");

Tracking Events Manually with Airbridge

  1. Get the required token. For information on how to get a token, refer to the Airbridge Dashboard Guide.
    • Get the App SDK Token and App Name from Dashboard > Settings > Token Management.
  2. Add the token, app name, and event settings to hive_config.xml. Refer to the hive_config.xml example code below. On Windows, the token and app name settings are not required, but the Hive console settings are required.
  3. Airbridge provides SDK Signature to prevent app spoofing. To use the related function, you must first check the contract terms with Airbridge. Get the key and add it as secretId, secret value in hive_config.xml. For more information about SDK signature security information, refer to the Airbridge Guide. It is supported only on Android and iOS, not on Windows.
  4. If you are applying Windows, Android, and iOS together, contact Airbridge for presets.
  5. Send events by calling the Analytics API sendEvent(). When sending events, use the <event> tag added to hive_config.xml. Among the <event> tag values, name is used as a parameter when calling the API, and value can be checked in the dashboard of the corresponding attribution.
    • Analytics.sendEvent("TutorialComplete");
    • Analytics.sendEvent("MissionClear");

hive_config.xml example code

<providers>
    <Airbridge name="Airbridge" key="APP_SDK_TOKEN" appName="APP_NAME" secretId="SECRET_ID" secret="SECRET">
                <events>
                        <event name="TutorialComplete" value="Tutorial Complete" />
                        <event name="MissionClear" value="Mission Clear" />
                </events>
        </Airbridge>
</providers>

Track events manually with Singular, Appsflyer, and Firebase Analytics

This section explains how to manually track events with Singular, Appsflyer, and Firebase Analytics attribution.

  1. 아래와 같이 각 어트리뷰션의 대시보드에서 필요한 키를 발급받습니다. 키 발급 방법에 대해서는 각 어트리뷰션에서 제공하는 대시보드 가이드를 참고하세요.
    • Singular: 대시보드에서 SDK Key와 SDK SecretKey를 받습니다.
    • Appsflyer: 대시보드 > 앱 설정에서 Dev 키를 받습니다.
    • Firebase Analytics: 키 발급이 필요하지 않습니다.
  2. hive_config.xml 파일을 아래의 예제와 같이 수정합니다. 특히, Hive SDK Native iOS 혹은 Unity Android & iOS 및 Unreal Engine Android & iOS에서 Appsflyer 어트리뷰션을 사용하는 경우, Apple AppID 설정을 위해 itunseConnectAppId 값을 설정합니다.
      <providers>
      <!-- Singular 설정하기 -->
      <!-- Singular 노드 name 필드는 "Singular" 고정값입니다. -->
      <!-- event 노드 name 필드는 게임사에서 임의로 설정합니다. 단, sendEvent() 호출을 위해 다른 어트리뷰션에서도 동일한 값을 사용해야 합니다.-->
      <!-- event 노드 value 필드는 게임사에서 임의로 설정합니다. -->
      <Singular name="Singular" id="SDK_KEY" key="SDK_SECRET_KEY">
          <events>
              <event name="TutorialComplete" value="Tutorial Complete" />
              <event name="MissionClear" value="Mission Clear" />
          </events>
      </Singular>
    
      <!-- AppsFlyer 설정하기 -->
      <!-- AppsFlyer 노드 name 필드는 "AppsFlyer" 고정값입니다. -->
      <!-- AppsFlyer 노드 id 필드는 설정하지 않습니다. -->
      <!-- event 노드 name 필드는 게임사에서 임의로 설정합니다. 단, sendEvent() 호출을 위해 다른 어트리뷰션에서도 동일한 값을 사용해야 합니다.-->
      <!-- event 노드 value 필드는 게임사에서 임의로 설정합니다. -->
      <AppsFlyer name="AppsFlyer" id="unused" key="DEV_KEY" itunseConnectAppId="909923112">
          <events>
              <event name="TutorialComplete" value="Tutorial Complete" />
              <event name="MissionClear" value="Mission Clear" />
          </events>
      </AppsFlyer>
    
      <!-- Firebase Analytics 설정하기 -->
      <!-- event 노드 name 필드는 게임사에서 임의로 설정합니다. 단, sendEvent() 호출을 위해 다른 어트리뷰션에서도 동일한 값을 사용해야 합니다.-->
      <!-- event 노드 value 필드는 게임사에서 임의로 설정합니다. -->
      <firebase>
          <events>
            <event name="TutorialComplete" value="TutorialComplete" />
            <event name="MissionClear" value="MissionClear" />
          </events>
      </firebase>
      </providers>
    
  3. Analytics API sendEvent()를 호출하여 이벤트를 전송합니다. 이벤트 전송 시, hive_config.xml에 추가한 <event> 태그 값을 전달 인자로 사용하여 이벤트를 전송합니다. <event> 태그 값 중 name은 API 호출 시 파라미터로 사용되며, value는 해당 어트리뷰션의 대시보드에서 확인할 수 있습니다.
    • Analytics.sendEvent("TutorialComplete");
    • Analytics.sendEvent("MissionClear");

sendEvent()로 이벤트 전송하기

어트리뷰션에 유저의 행동을 추적하는 이벤트를 전송하는 방법을 설명합니다.

어트리뷰션에 추적 이벤트 전송 시, 유저의 모든 행동을 추적하기 보다는 '튜토리얼 완료'와 같이 유저의 행동이 특정 조건을 만족시켰을 때 전송하는 것을 권장합니다.

유저 행동 추적 이벤트를 전송하려면 Analytics APIsendEvent() 함수를 호출하세요. sendEvent() 함수의 첫 번째 파라미터 값은 hive_config.xml 설정 파일에 정의한 <event> 요소의 name 속성 값으로 입력합니다.

유저가 튜토리얼을 완료 시, TutorialComplete 이벤트를 마케팅 어트리뷰션에 전송하는 예제 코드는 아래와 같습니다.

API Reference: hive.Analytics.sendEvent

using hive;    
    String eventName = "TutorialComplete";    
Analytics.sendEvent(eventName);
#include "HiveAnalytics.h"

FString EventName = TEXT("TutorialComplete");
FHiveAnalytics::SendEvent(EventName);

API Reference: Analytics::sendEvent

#include <HIVE_SDK_Plugin/HIVE_CPP.h>    
    using namespace std;    
    using namespace hive;    
    string eventName = "TutorialComplete";    
Analytics::sendEvent(eventName);

API Reference: Analytics.sendEvent

import com.hive.Analytics    
    val eventName = "TutorialComplete"    
Analytics.sendEvent(eventName)

API Reference: AnalyticsInterface .sendEvent

import HIVEService    
    let eventName = "TutorialComplete"    
AnalyticsInterface.sendEvent(eventName)

API Reference: HIVEAnalytics:sendEvent

#import <HIVEService/HIVEService-Swift.h>    
    NSString eventName = @"TutorialComplete";    
[HIVEAnalytics sendEvent: eventName];

API Reference: AnalyticsInterface.sendEvent

#import HIVEService   
    let eventName = "TutorialComplete"
AnalyticsInterface.sendEvent(eventName)

sendEventWithAttributes()로 추가 어트리뷰트 전송하기

sendEvent() 대신 sendEventWithAttributes() 함수를 호출하는 경우, 사용자가 정의한 어트리뷰트를 추가하여 전송할 수 있습니다.

sendEventWithAttributes() 함수의 첫 번째 파라미터 값은 hive_config.xml 설정 파일에 정의한 <event> 요소의 name 속성 값으로 입력합니다.

커스텀 어트리뷰트 추가하기

addCustomAttribute()를 호출하여 Hive SDK에서 지원하는 모든 마케팅 어트리뷰션(Airbridge, Adjust, Appsflyer, Singular, Firebase Analytics)에 커스텀 어트리뷰트를 추가하여 전송할 수 있습니다.

Note

커스텀 어트리뷰트(Custom Attribute)란 사용자가 정의한 속성으로 String, Int, Float, Double, Boolean 데이터 형식을 지원합니다. 단, Adjust로 전송하는 경우 데이터 형식과 관계 없이 모든 데이터 형식을 String으로 변환하여 전송합니다.

커스텀 어트리뷰트 추가하여 전송하는 예제 코드는 아래와 같습니다.

API Reference: hive.Analytics.sendEventWithAttributes

using hive;    

// Create AnalyticsAttributes
var analyticsAttributes = new AnalyticsAttributes();

// Add Custom Attribute
analyticsAttributes.AddCustomAttribute("key1", "value1");
analyticsAttributes.AddCustomAttribute("key2", "value2");

Analytics.sendEventWithAttributes("Quest Complete", analyticsAttributes);
#include "HiveAnalytics.h"

// Create AnalyticsAttributes
FHiveAnalyticsAttributes AnalyticsAttributes;

// Add Custom Attribute
TSharedPtr<FJsonValue> CustomJsonValue1 = MakeShareable(new FJsonValueString("value1"));
AnalyticsAttributes.AddCustomAttribute(TEXT("key1"), CustomJsonValue1);
TSharedPtr<FJsonValue> CustomJsonValue2 = MakeShareable(new FJsonValueString("value2"));
AnalyticsAttributes.AddCustomAttribute(TEXT("key2"), CustomJsonValue2);

FHiveAnalytics::SendEventWithAttributes(strEventName, AnalyticsAttributes);

API Reference: Analytics::sendEventWithAttributes

#include <HIVE_SDK_Plugin/HIVE_CPP.h>    
using namespace std;   
using namespace hive;

// Create AnalyticsAttributes
AnalyticsAttributes analyticsAttributes;

// Add Custom Attribute
analyticsAttributes.addCustomAttribute("key1", picojson::value("value1"));
analyticsAttributes.addCustomAttribute("key2", picojson::value("value2"));

std::string eventName = "Quest Complete";

Analytics::sendEventWithAttributes(eventName, analyticsAttributes);

API Reference: Analytics.sendEventWithAttributes

import com.hive.Analytics    
import com.hive.analytics.provider.attributes.AirbridgeSpecific
import com.hive.analytics.provider.attributes.AnalyticsAttributes

// Create AnalyticsAttributes
val analyticsAttributes = AnalyticsAttributes()

// Add Custom Attribute
analyticsAttributes.addCustomAttribute("key1", "value1")
analyticsAttributes.addCustomAttribute("key2", "value2")

Analytics.sendEventWithAttributes("Quest Complete", analyticsAttributes)

API Reference: Analytics.sendEventWithAttributes

import com.hive.Analytics;
import com.hive.analytics.provider.attributes.AirbridgeSpecific;
import com.hive.analytics.provider.attributes.AnalyticsAttributes;

// Create AnalyticsAttributes
AnalyticsAttributes analyticsAttributes = new AnalyticsAttributes();

// Add Custom Attribute
analyticsAttributes.addCustomAttribute("key1", "value1");
analyticsAttributes.addCustomAttribute("key2", "value2");

Analytics.sendEventWithAttributes("Quest Complete", analyticsAttributes);

API Reference: HIVEAnalytics:sendEventWithAttributes

#import <HIVEService/HIVEService-Swift.h>

HiveAnalyticsAttributes* analyticsAttributes = [[HiveAnalyticsAttributes alloc] init];

[analyticsAttributes addModuleSpecificAttribute: airbridgeSpecific];
[analyticsAttributes addCustomAttribute: @"key1" value: @"value1"];
[analyticsAttributes addCustomAttribute: @"key2" value: @"value2"];

[HIVEAnalytics sendEventWithAttributes: @"Quest Complete" attributes: analyticsAttributes];

API Reference: HIVEAnalytics:sendEventWithAttributes

#import HIVEService

// Create AnalyticsAttributes
let analyticsAttributes = AnalyticsAttributes()

// Add Custom Attribute
analyticsAttributes.addCustomAttribute("key1", value: "value1")
analyticsAttributes.addCustomAttribute("key2", value: "value2")

AnalyticsInterface.sendEventWithAttributes("Quest Complete", attributes: analyticsAttributes)

Airbridge에 시맨틱 어트리뷰트 전송하기

Airbridge에 추가 어트리뷰트 전송 시, 커스텀 어트리뷰트 외에도 아래와 같은 시맨틱 어트리뷰트를 추가하여 전송할 수 있습니다.

  • 액션(Action), 라벨(Label): Airbridge 리포트에서 그룹바이로 활용할 수 있는 정보를 수집합니다.
  • Value: Collects information used for revenue analysis.
  • 시맨틱 어트리뷰트(Semantic Attribute): Airbridge에서 미리 정의한 어트리뷰트입니다.
    • If you enter an attribute string other than the predefined attributes, it may not be collected.
    • Events with data that do not match the data format of the semantic attribute will not be collected. Since the data format varies for each semantic attribute, caution is required.
    • Semantic attributes with a data format of string are allowed up to 1024 characters. Semantic attributes with a data format of int or float are allowed up to 64 bits.

API Reference: hive.Analytics.sendEventWithAttributes

using hive;    

// Create AnalyticsAttributes
var analyticsAttributes = new AnalyticsAttributes();

// Specific Attribute for Airbridge
var airbridgeSpecific = new AirbridgeSpecific();
// Action
airbridgeSpecific.SetSemanticAction("Tool");
// Label
airbridgeSpecific.SetSemanticLabel("Hammer");
// Value
airbridgeSpecific.SetSemanticValue(10);

// Semantic Attribute
airbridgeSpecific.AddSemanticAttribute("type", "Warrior");
airbridgeSpecific.AddSemanticAttribute("score", 20);

// Add Airbridge Specific Attribute
analyticsAttributes.AddModuleSpecificAttributes(airbridgeSpecific);

// Add Custom Attribute
analyticsAttributes.AddCustomAttribute("key1", "value1");
analyticsAttributes.AddCustomAttribute("key2", "value2");

Analytics.sendEventWithAttributes("Quest Complete", analyticsAttributes);
#include "HiveAnalytics.h"

// Create AnalyticsAttributes
FHiveAnalyticsAttributes AnalyticsAttributes;

// Specific Attribute for Airbridge
FHiveAirbridgeSpecific AirbridgeSpecific;
// Action
AirbridgeSpecific.SetSemanticAction(TEXT("Tool"));
// Label
AirbridgeSpecific.SetSemanticLabel(TEXT("Hammer"));
// Value
AirbridgeSpecific.SetSemanticValue(10.0);

// Semantic Attribute
TSharedPtr<FJsonValue> SemanticJsonValue1 = MakeShared<FJsonValueString>(TEXT("Warrior"));
AirbridgeSpecific.AddSemanticAttribute(TEXT("type"), SemanticJsonValue1);
TSharedPtr<FJsonValue> SemanticJsonValue2 = MakeShared<FJsonValueNumber>(20);
AirbridgeSpecific.AddSemanticAttribute(TEXT("score"), SemanticJsonValue2);

// Add Airbridge Specific Attribute
AnalyticsAttributes.AddModuleSpecificAttribute(AirbridgeSpecific);

// Add Custom Attribute
TSharedPtr<FJsonValue> CustomJsonValue1 = MakeShareable(new FJsonValueString("value1"));
AnalyticsAttributes.AddCustomAttribute(TEXT("key1"), CustomJsonValue1);
TSharedPtr<FJsonValue> CustomJsonValue2 = MakeShareable(new FJsonValueString("value2"));
AnalyticsAttributes.AddCustomAttribute(TEXT("key2"), CustomJsonValue2);

FHiveAnalytics::SendEventWithAttributes(strEventName, AnalyticsAttributes);

API Reference: Analytics::sendEventWithAttributes

#include <HIVE_SDK_Plugin/HIVE_CPP.h>    
using namespace std;   
using namespace hive;

// Create AnalyticsAttributes
AnalyticsAttributes analyticsAttributes;

// Specific Attribute for Airbridge
AirbridgeSpecific airbridgeSpecific;

std::string semanticAction = "Tool";
std::string semanticLabel = "Hammer";
double semanticValue = 10.0;

// Action
airbridgeSpecific.setSemanticAction(semanticAction);
// Label
airbridgeSpecific.setSemanticLabel(semanticLabel);
// Value
airbridgeSpecific.setSemanticValue(semanticValue);

// Semantic Attribute
airbridgeSpecific.addSemanticAttribute("type", picojson::value("Warrior"));
airbridgeSpecific.addSemanticAttribute("score", picojson::value(20.0f));

// Add Airbridge Specific Attribute
analyticsAttributes.addModuleSpecificAttribute(airbridgeSpecific);

// Add Custom Attribute
analyticsAttributes.addCustomAttribute("key1", picojson::value("value1"));
analyticsAttributes.addCustomAttribute("key2", picojson::value("value2"));

std::string eventName = "Quest Complete";

Analytics::sendEventWithAttributes(eventName, analyticsAttributes);

API Reference: Analytics.sendEventWithAttributes

import com.hive.Analytics    
import com.hive.analytics.provider.attributes.AirbridgeSpecific
import com.hive.analytics.provider.attributes.AnalyticsAttributes

// Create AnalyticsAttributes
val analyticsAttributes = AnalyticsAttributes()

// Specific Attribute for Airbridge
val airbridgeSpecific = AirbridgeSpecific().apply {
    setSemanticAction("Tool")                // Action
    setSemanticLabel("Hammer")               // Label
    setSemanticValue(10.0)                  // Value
    addSemanticAttribute("type", "Warrior")  // Semantic Attribute
    addSemanticAttribute("score", 20.0f)     // Semantic Attribute
}

// Add Airbridge Specific Attribute
analyticsAttributes.addModuleSpecificAttribute(airbridgeSpecific)

// Add Custom Attribute
analyticsAttributes.addCustomAttribute("key1", "value1")
analyticsAttributes.addCustomAttribute("key2", "value2")

Analytics.sendEventWithAttributes("Quest Complete", analyticsAttributes)

API Reference: Analytics.sendEventWithAttributes

import com.hive.Analytics;
import com.hive.analytics.provider.attributes.AirbridgeSpecific;
import com.hive.analytics.provider.attributes.AnalyticsAttributes;

// Create AnalyticsAttributes
AnalyticsAttributes analyticsAttributes = new AnalyticsAttributes();

// Specific Attribute for Airbridge
AirbridgeSpecific airbridgeSpecific = new AirbridgeSpecific();
airbridgeSpecific.setSemanticAction("Tool");                // Action
airbridgeSpecific.setSemanticLabel("Hammer");               // Label
airbridgeSpecific.setSemanticValue(10.0);                  // Value
airbridgeSpecific.addSemanticAttribute("type", "Warrior");  // Semantic Attribute
airbridgeSpecific.addSemanticAttribute("score", 20.0f);     // Semantic Attribute

// Add Airbridge Specific Attribute
analyticsAttributes.addModuleSpecificAttribute(airbridgeSpecific);

// Add Custom Attribute
analyticsAttributes.addCustomAttribute("key1", "value1");
analyticsAttributes.addCustomAttribute("key2", "value2");

Analytics.sendEventWithAttributes("Quest Complete", analyticsAttributes);

API Reference: HIVEAnalytics:sendEventWithAttributes

#import <HIVEService/HIVEService-Swift.h>

HiveAnalyticsAttributes* analyticsAttributes = [[HiveAnalyticsAttributes alloc] init];

HiveAirbridgeSpecific* airbridgeSpecific = [[HiveAirbridgeSpecific alloc] init];
[airbridgeSpecific setSemanticAction: @"Tool"];
[airbridgeSpecific setSemanticAction: @"Hammer"];
[airbridgeSpecific setSemanticValue: 10.0];
[airbridgeSpecific addSemanticAttribute: @"type" value: @"Warrior"];
[airbridgeSpecific addSemanticAttribute: @"score" value: @20.0f];

[analyticsAttributes addModuleSpecificAttribute: airbridgeSpecific];
[analyticsAttributes addCustomAttribute: @"key1" value: @"value1"];
[analyticsAttributes addCustomAttribute: @"key2" value: @"value2"];

[HIVEAnalytics sendEventWithAttributes: @"Quest Complete" attributes: analyticsAttributes];

API Reference: HIVEAnalytics:sendEventWithAttributes

#import HIVEService

// Create AnalyticsAttributes
let analyticsAttributes = AnalyticsAttributes()

// Specific Attribute for Airbridge
let airbridgeSpecific = AirbridgeSpecific()
airbridgeSpecific.setSemanticAction("Tool")
airbridgeSpecific.setSemanticLabel("Hammer")
airbridgeSpecific.setSemanticValue(10.0)
airbridgeSpecific.addSemanticAttribute("type", value: "Warrior")
airbridgeSpecific.addSemanticAttribute("score", value: 20.0)

// Add Airbridge Specific Attribute
analyticsAttributes.addModuleSpecificAttribute(airbridgeSpecific)

// Add Custom Attribute
analyticsAttributes.addCustomAttribute("key1", value: "value1")
analyticsAttributes.addCustomAttribute("key2", value: "value2")

AnalyticsInterface.sendEventWithAttributes("Quest Complete", attributes: analyticsAttributes)

Applying Google Ads on-device measurement in Firebase environment

To measure on-device conversions provided by Google Ads in a Firebase environment, you need to implement the Firebase Google ODM Solution. This solution requires the email address or phone number that the user has consented to provide. During the implementation of this solution, if Firebase Authentication or a separate authentication environment introduced by the developer is implemented, the Hive SDK does not collect email addresses and only passes any email address obtained in the response after authentication directly to the Firebase API.

Note

This guide is intended for iOS apps only. Android apps do not require a separate process for measuring on-device conversions in the Firebase environment.

Implementation method

Throughout the entire process below, you must make sure that personal information for identification must not leak from the user's device to the outside.

  1. Download the Google Firebase ODM Unity Plugin and add it to your Unity project.
  2. Implement authentication to obtain the IdP email address or phone number after logging in.
  3. Normalize the email address or phone number according to the method defined by Firebase.
  4. Implement the passing of the normalized email address/phone number to Firebase. Alternatively, implement the passing of the hashed value of the normalized email address/phone number to Firebase. Refer to the example code below.
Note

The plugin API can be called sequentially, but subsequent calls are essentially ignored after being called once per user.

Example code

Below is example code when using the Unity plugin.

Example code using hashed values

using hive;
// Sending the hashed & normalized email address
GoogleODM.setHashedEmailAddress(ComputeSha256Hash("abc@abc.com"));
using hive;
// Sending the hashed & normalized phone number information
GoogleODM.setHashedPhoneNumber(ComputeSha256Hash("+821012345678"));

Example code using plain values

using hive;
// Sending the normalized email address
GoogleODM.setEmailAddress("abc@abc.com");
using hive;
// Sending the normalized phone number information
GoogleODM.setPhoneNumber("+821012345678");