SDK ์ฐ๋
Hackle Android SDK ๋ Android API 16 ์ด์ (4.1 Jelly Bean)์ ์ง์ํฉ๋๋ค.
1. ์์กด์ฑ ์ถ๊ฐ
repositories {
mavenCentral()
}build.gradle ํ์ผ์ ์์กด์ฑ์ ์ถ๊ฐํฉ๋๋ค.
dependencies {
implementation 'io.hackle:hackle-android-sdk:2.63.0'
}ProGuard
ProGuard๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ, aar ์ํฐํฉํธ์ ๋๋ ํ ๊ท์น์ด ์๋์ผ๋ก ํฌํจ๋ฉ๋๋ค. ์ด ๊ฒฝ์ฐ๊ฐ ์๋๋ผ๋ฉด ์๋ ๊ท์น์ ํฌํจ์์ผ์ผ ํฉ๋๋ค.
-keep class io.hackle.android.** { *; }
-keep class io.hackle.sdk.** { *; }2. SDK ์ด๊ธฐํ
SDK๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์ ๋ฐ๋์ HackleApp์ ์ด๊ธฐํ ํด์ผ ํฉ๋๋ค. HackleApp์ ์ด๊ธฐํ ํ๊ธฐ ์ํด SDK ํค๊ฐ ํ์ํฉ๋๋ค.
HackleApp์ SDK์ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๊ธฐ ์ํ ๋ฉ์๋๋ค์ ์ ๊ณตํ๋ ํด๋์ค์ ๋๋ค.- SDK ํค๋ ํตํด ์๋น์ค์ ๋์๋ณด๋ ์์ ์์นํ SDK ์ฐ๋ ์ ๋ณด์์ ํ์ธํ์ค ์ ์์ต๋๋ค.
import io.hackle.android.Hackle
import io.hackle.android.initialize
Hackle.initialize(applicationContext, YOUR_APP_SDK_KEY)import io.hackle.android.HackleApp;
HackleApp.initializeApp(getApplicationContext(), YOUR_APP_SDK_KEY);์ด๊ธฐํ ์๋ฃ
์ด๊ธฐํ๊ฐ ์์๋๋ฉด ํตํด ์๋ฒ๋ก๋ถํฐ ํ์ํ ์ ๋ณด๋ค์ ๊ฐ์ ธ์์ SDK์ ์ ์ฅํฉ๋๋ค. ์ด ์์ ์ ๋น๋๊ธฐ๋ก ์คํ๋๋ฉฐ, ์ด๊ธฐํ์ ๋ง์ง๋ง ํ๋ผ๋ฏธํฐ๋ก ์ฝ๋ฐฑ์ ์ ๋ฌํ๋ฉด SDK ์ฌ์ฉ ์ค๋น๊ฐ ์๋ฃ๋ ๊ฒ์ ์ ์ ์์ต๋๋ค. ์ด๊ธฐํ๊ฐ ์๋ฃ ๋๊ธฐ ์ ์ A/B ํ ์คํธ, ๊ธฐ๋ฅ ํ๋๊ทธ๋ฅผ ํธ์ถํ๋ฉด ๊ธฐ๋ณธ ๊ทธ๋ฃน(A), ๊บผ์ง(false)์ ๋ฆฌํดํฉ๋๋ค.
import io.hackle.android.Hackle
import io.hackle.android.initialize
Hackle.initialize(applicationContext, YOUR_APP_SDK_KEY) {
// SDK ready to use.
}import io.hackle.android.HackleApp;
HackleApp.initializeApp(getApplicationContext(), YOUR_APP_SDK_KEY, () -> {
// SDK ready to use.
});๊ถ์ฅ ์ด๊ธฐํ ์ ๋ต: ๋ก๋ฉ ํ๋ฉด์ ํตํ ์ด๊ธฐํ
์ฑ์ ์ฆ์ ์์ํ์ง ์๊ณ ๋ก๋ฉ ํ๋ฉด์ ํ์ํ๊ณ SDK๋ฅผ ์ด๊ธฐํํฉ๋๋ค. ์ดํ ์ฝ๋ฐฑ์ ํตํด ๋ก๋ฉ ํ๋ฉด์ ๋ซ๊ณ ์ฌ์ฉ์๊ฐ ์ฑ๊ณผ ์ํธ์์ฉ์ ์์ํ ์ ์๋๋ก ํฉ๋๋ค.
์ด ์ ๋ต์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ๋ก๋ฉ ํ๋ฉด์ ์ ํ ์๊ฐ์ ๋๋ ๊ฒ์ด ์ข์ต๋๋ค.
์ธ์คํด์ค ๊ฐ์ ธ์ค๊ธฐ
์ด๊ธฐํ ์ดํ ์๋ ์ฝ๋๋ฅผ ํตํด HackleApp ์ธ์คํด์ค๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.
import io.hackle.android.Hackle
import io.hackle.android.app
val hackleApp = Hackle.appimport io.hackle.android.HackleApp;
HackleApp hackleApp = HackleApp.getInstance();์ด๊ธฐํ ์ค์ ์ ๋ณด
์ค์ ์ ๋ณด๋ฅผ ํฌํจํ์ฌ SDK๋ฅผ ์ด๊ธฐํ ํ ์ ์์ต๋๋ค.
import io.hackle.android.Hackle
import io.hackle.android.HackleConfig
import io.hackle.android.initialize
val config = HackleConfig.builder()
.build()
Hackle.initialize(applicationContext, YOUR_APP_SDK_KEY, config) {
// SDK ready to use.
}import io.hackle.android.HackleApp;
import io.hackle.android.HackleConfig;
HackleConfig config = HackleConfig.builder()
.exposureEventDedupIntervalMillis(1000)
.build();
HackleApp.initializeApp(getApplicationContext(), YOUR_APP_SDK_KEY, config, () -> {
// SDK ready to use.
});๋ชจ๋ ์ค์ ์ต์
์ค์ | ๊ธฐ๋ฅ | ๊ธฐ๋ณธ๊ฐ | ์ง์ ๋ฒ์ |
|---|---|---|---|
exposureEventDedupIntervalMillis | ๋์ผํ ์ฌ์ฉ์๊ฐ ์ฐ์์ผ๋ก ๋ฐ์์ํจ ๋์ผํ A/B ํ ์คํธ, ๊ธฐ๋ฅํ๋๊ทธ ๋ถ๋ฐฐ๊ฒฐ๊ณผ์ ๋ํ ๋ ธ์ถ ์ด๋ฒคํธ๋ฅผ ์ ๊ฑฐํฉ๋๋ค. ์ต์๊ฐ: 1000 (1์ด) ์ต๋๊ฐ:
| 60000 (1๋ถ) | 2.7.0+ (2.47.0 ์ดํ๋ถํฐ ์ฑ ์ข ๋ฃ ํ ์ฌ์์ ์์๋ ์ง์ํฉ๋๋ค.) |
eventFlushIntervalMillis | ์์ง๋ ์ด๋ฒคํธ๋ฅผ ์๋ฒ๋ก ์ ์กํ๋ ์ฃผ๊ธฐ์ ๋๋ค. ์ต์๊ฐ: 1000 (1์ด) ์ต๋๊ฐ: 60000 (1๋ถ) | 10000 (10์ด) | 2.10.0+ |
sessionTimeoutMillis | ์ธ์ ๋ง๋ฃ ์๊ฐ์ ์ค์ ํฉ๋๋ค. | 1800000 (30๋ถ) | 2.13.0+ |
pollingIntervalMillis | ๋์๋ณด๋์์ ์ค์ ํ ์ ๋ณด๋ฅผ ์ฃผ๊ธฐ์ ์ผ๋ก ์ ๋ฐ์ดํธ ํ ์ ์์ต๋๋ค. ์ต์๊ฐ : 60000 (60์ด) | -1 (์ฃผ๊ธฐ์ ์ผ๋ก ์ ๋ฐ์ดํธํ์ง ์์) | 2.19.0+ |
๋์๋ณด๋ ์ค์ ์ ๋ณด ๊ฐฑ์
๋์๋ณด๋ ์ค์ ์ ๋ณด๋ฅผ ๋ช ์์ ์ผ๋ก ๊ฐฑ์ ํ ์ ์์ต๋๋ค.
hackleApp.fetch {
// done
}hackleApp.fetch(new Runnable() {
@Override
public void run() {
// done
}
});ํด๋น ํจ์๋ 60์ด์ ํ๋ฒ ์ ํ์ ์ผ๋ก ํธ์ถํ ์ ์์ต๋๋ค.
Third-party ์์กด์ฑ
ํตํด Android SDK๋ ์๋์ ๊ฐ์ third-party ์์กด์ฑ์ ๊ฐ์ง๊ณ ์์ต๋๋ค
- com.squareup.okhttp3:okhttp:3.12.2
- com.google.code.gson:gson:2.8.6
- com.google.android.gms:play-services-base:17.3.0
3. ์ฌ์ฉ์ ์ค์
์ฌ์ฉ์ ์ ๋ณด๋ฅผ SDK์ ์ค์ ํ ์ ์์ต๋๋ค.
์ฌ์ฉ์ ID ์ค์
์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธํ ๊ฒฝ์ฐ, setUserId๋ฅผ ํธ์ถํด์ ๋ก๊ทธ์ธํ ์ฌ์ฉ์์ ID๋ฅผ ์ค์ ํ ์ ์์ต๋๋ค.
- ๋ก๊ทธ์ธ ์ ํ๋ฒ๋ง ์ค์ ํ๋ฉด ๋ฉ๋๋ค.
- ์ด๋ฏธ ๋ก๊ทธ์ธ์ด ๋์ด์๋ ์ฌ์ฉ์์ ๊ฒฝ์ฐ์๋ ๋ก๊ทธ์ธํ ์ ๋ณด๋ฅผ ํ์ธํ๋ ์์ ์ ํธ์ถํ๋ฉด ๋ฉ๋๋ค.
val userId: String = ... // ๋ก๊ทธ์ธํ ์ฌ์ฉ์์ ID (ํ์๋ฒํธ, ๋ฉค๋ฒ ID ๋ฑ)
hackleApp.setUserId(userId)String userId = ... // ๋ก๊ทธ์ธํ ์ฌ์ฉ์์ ID (ํ์๋ฒํธ, ๋ฉค๋ฒ ID ๋ฑ)
hackleApp.setUserId(userId);์ฌ์ฉ์ ์์ฑ ์ค์
์ด๋ฉ์ผ์ฃผ์, ์์น, ๋์ด, ํ์๋ฑ๊ธ๊ณผ ๊ฐ์ ์ ๋ณด๋ฅผ ์ฌ์ฉ์ ์์ฑ์ผ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
import io.hackle.sdk.common.PropertyOperations
val operations = PropertyOperations.builder()
.set("age", 42)
.set("grade", "GOLD")
.build()
hackleApp.updateUserProperties(operations)import io.hackle.sdk.common.PropertyOperations;
PropertyOperations operations = PropertyOperations.builder()
.set("age", 42)
.set("grade", "GOLD")
.build();
hackleApp.updateUserProperties(operations);์ฌ์ฉ์ ๋ก๊ทธ์์ ์ ์ฌ์ค์
์ฌ์ฉ์๊ฐ ๋ก๊ทธ์์ ํ ๊ฒฝ์ฐ resetUser๋ฅผ ํธ์ถํ์ฌ ๊ธฐ์กด์ ์ค์ ํ ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ๋ฆฌ์
ํ ์ ์์ต๋๋ค. ์๋ ์ ๋ณด๊ฐ ๋ฆฌ์
๋ฉ๋๋ค.
- ์ฌ์ฉ์ ID
- ์ฌ์ฉ์ ์์ฑ
hackleApp.resetUser()hackleApp.resetUser();4. ์ด๋ฒคํธ ์ ์ก
์ฌ์ฉ์๊ฐ ์ํํ๋ ํ๋์ ์ด๋ฒคํธ๋ก ์ ์กํ ์ ์์ต๋๋ค. ์ ์ก๋ ์ด๋ฒคํธ๋ A/B ํ ์คํธ ๋ถ์, ๋ฐ์ดํฐ ๋ถ์ ๋ฑ์ ์ฌ์ฉ๋ฉ๋๋ค. ์๋ฅผ๋ค์ด, ์ฌ์ฉ์๊ฐ ๊ตฌ๋งค๋ผ๋ ํ๋์ ํ๋ค๋ฉด ์๋์ ๊ฐ์ด ์ด๋ฒคํธ๋ฅผ ์ ์กํ ์ ์์ต๋๋ค.
import io.hackle.sdk.common.Event
// ์ด๋ฒคํธ ์ ์ก
hackleApp.track("purchase")
// ์ด๋ฒคํธ๋ฅผ ์์ฑ๊ณผ ํจ๊ป ์ ์ก
val event = Event.builder("purchase")
.property("amount", 4200)
.property("pay_method", "CARD")
.property("is_discount", false)
.property("product_ids", listOf(42, 43))
.build()
hackleApp.track(event)import io.hackle.sdk.common.Event;
// ์ด๋ฒคํธ ์ ์ก
hackleApp.track("purchase");
// ์ด๋ฒคํธ๋ฅผ ์์ฑ๊ณผ ํจ๊ป ์ ์ก
Event event = Event.builder("purchase")
.property("amount", 4200)
.property("pay_method", "CARD")
.property("is_discount", false)
.property("product_ids", Arrays.asList(42, 43))
.build();
hackleApp.track(event);์ ์กํ ์ด๋ฒคํธ ํ์ธํ๊ธฐ
๋์๋ณด๋ ์ด๋ฒคํธ๊ด๋ฆฌ ๋ฉ๋ด์์ ์ ์กํ ์ด๋ฒคํธ๋ฅผ ํ์ธํ ์ ์์ต๋๋ค. ์ด๋ฒคํธ ์ ์ก ํ ๋์๋ณด๋์ ํ์๋๊ธฐ๊น์ง ์ผ๋ฐ์ ์ผ๋ก ~60์ด๊ฐ ๊ฑธ๋ฆฝ๋๋ค.
5. A/B ํ
์คํธ
์ฌ์ฉ์๋ฅผ ํ
์คํธ ๊ทธ๋ฃน์ผ๋ก ๋ถ๋ฐฐํ๊ณ ๋ถ๋ฐฐ๋ ๊ฒฐ๊ณผ์ ํด๋นํ๋ ๋ก์ง์ ์์ฑํ์ฌ A/B ํ
์คํธ๋ฅผ ๊ตฌํํฉ๋๋ค. variation์ ์คํํค๋ฅผ ์ ๋ฌํ์ฌ ํธ์ถํ๋ฉด ๋ถ๋ฐฐ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌํด๋ฐ์ ์ ์์ต๋๋ค.
์คํํค: ๊ฐ A/B ํ ์คํธ๋ณ๋ก ๊ฐ๊ฒ ๋๋ ๊ณ ์ ๋ฒํธ์ ๋๋ค. A/B ํ ์คํธ๋ฅผ ์์ฑํ๋ฉด ์๋์ผ๋ก ๋ฐ๊ธ๋ฉ๋๋ค.
import io.hackle.sdk.common.Variation
// ์คํ ํค๊ฐ 42์ธ A/B ํ
์คํธ์์ ์ฌ์ฉ์์๊ฒ ๋
ธ์ถํ ํ
์คํธ ๊ทธ๋ฃน์ ๊ฒฐ์ ํฉ๋๋ค.
val variation: Variation = hackleApp.variation(42)
// ํ ๋น๋ฐ์ ๊ทธ๋ฃน์ ๋ํ ๋ก์ง
if (variation == Variation.A) {
// ๊ทธ๋ฃน A ๋ก์ง
} else if (variation == Variation.B) {
// ๊ทธ๋ฃน B ๋ก์ง
}import io.hackle.sdk.common.Variation;
// ์คํ ํค๊ฐ 42์ธ A/B ํ
์คํธ์์ ์ฌ์ฉ์์๊ฒ ๋
ธ์ถํ ํ
์คํธ ๊ทธ๋ฃน์ ๊ฒฐ์ ํฉ๋๋ค.
Variation variation = hackleApp.variation(42);
// ํ ๋น๋ฐ์ ๊ทธ๋ฃน์ ๋ํ ๋ก์ง
if (variation == Variation.A) {
// ๊ทธ๋ฃน A ๋ก์ง
} else if (variation == Variation.B) {
// ๊ทธ๋ฃน B ๋ก์ง
}๋ถ๋ฐฐ ๊ฒฐ๊ณผ ํ์ธํ๊ธฐ
๋์๋ณด๋ A/B ํ ์คํธ์ ์์ธํ์ด์ง์ ์ค์๊ฐ ๋ ธ์ถ ํํฉ ํญ์์ ๋ถ๋ฐฐ๋ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํ ์ ์์ต๋๋ค. ๋ถ๋ฐฐ ํ ๋์๋ณด๋์ ํ์๋๊ธฐ๊น์ง ์ผ๋ฐ์ ์ผ๋ก ~60์ด๊ฐ ๊ฑธ๋ฆฝ๋๋ค.
6. ๊ธฐ๋ฅ ํ๋๊ทธ
๊ธฐ๋ฅ ํ๋๊ทธ๋ ์ผ์ง(on) ์ํ์ ๊บผ์ง(off) ์ํ๊ฐ ์์ต๋๋ค. ์ํ์ ๋ฐ๋ผ ๋ค๋ฅธ ๋ก์ง์ ์์ฑํ์ฌ ๊ธฐ๋ฅ ํ๋๊ทธ๋ฅผ ๊ตฌํํฉ๋๋ค. isFeatureOn์ ๊ธฐ๋ฅํ๋๊ทธํค๋ฅผ ์ ๋ฌํ์ฌ ํธ์ถํ๋ฉด on/off ์ฌ๋ถ๋ฅผ ๋ฆฌํด๋ฐ์ ์ ์์ต๋๋ค.
๊ธฐ๋ฅํ๋๊ทธํค: ๊ฐ ๊ธฐ๋ฅํ๋๊ทธ๋ณ๋ก ๊ฐ๊ฒ ๋๋ ๊ณ ์ ๋ฒํธ์ ๋๋ค. ๊ธฐ๋ฅํ๋๊ทธ๋ฅผ ์์ฑํ๋ฉด ์๋์ผ๋ก ๋ฐ๊ธ๋ฉ๋๋ค.
// ๊ธฐ๋ฅ ํค๊ฐ 42์ธ ๊ธฐ๋ฅ ํ๋๊ทธ์์ ์ฌ์ฉ์์ ์ํ๋ฅผ ๊ฒฐ์ ํฉ๋๋ค.
val featureOn = hackleApp.isFeatureOn(42)
if (featureOn) {
// ON ๊ธฐ๋ฅ
} else {
// OFF ๊ธฐ๋ฅ
}// ๊ธฐ๋ฅ ํค๊ฐ 42์ธ ๊ธฐ๋ฅ ํ๋๊ทธ์์ ์ฌ์ฉ์์ ์ํ๋ฅผ ๊ฒฐ์ ํฉ๋๋ค.
boolean featureOn = hackleApp.isFeatureOn(42);
if (featureOn) {
// ON ๊ธฐ๋ฅ
} else {
// OFF ๊ธฐ๋ฅ
}Updated 18 days ago
