Skip to main content

SigmaSDK - Android

Sigma - это платформа для экспериментов, которая позволяет вам быстро оценивать влияние новых функций и предлагать продукты, которые нравятся вашим клиентам.

Требования

  • Android API level 21+

Настройка Gradle

В файле build.gradle, который находится в корневой папке проекта, нужно добавить репозиторий jitpack. Для этого в конце списка репозиториев добавьте maven { url 'https://jitpack.io' }:

allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}

Если ваши репозитории для получения зависимостей объявлены в файле settings.gradle, то добавьте следующий код в dependencyResolutionManagement:

dependencyResolutionManagement {
...
repositories {
...
maven { url "https://jitpack.io" }
}
}

Затем добавьте следующую зависимость в файл build.gradle нужного вам модуля приложения (например, :app):

dependencies {
...
//SigmaSDK
implementation "ru.expf-team.sigma:kotlin-sdk:VERSION"
...
}

VERSION замените актуальной версией Sigma-SDK.

Инициализация SigmaSDK

Для инициализации SigmaSDK в классе, унаследованном от класса Application, в теле переопределенного метода onCreate() добавьте вызов статического метода Sigma.initializeClient().

Данный метод принимает следующие параметры:

  • application - объект класса приложения.
  • projectToken - токен проекта (указан в панели управления).
  • initialUserProperties - необязательный параметр, лямбда для назначения свойств пользователя.
  • cacheTtlMillis - необязательный параметр, время жизни кеша полученного конфига из сети (по умолчанию равен 60 секундам, если указать значение меньшее 10 секунд, то оно будет проигнорировано, и будет использовано значение по умолчанию).
  • retryCount - необязательный параметр, количество повторных попыток запрашивания конфига при неудачном запросе (по умолчанию равен 3).
  • tag - необязательный параметр, тег клиента Sigma (по умолчанию равен 'default'). Необходим для создания нескольких инстансов SigmaClient.
  • sigmaJsonAdapter - необязательный параметр, адаптер, который будет использоваться при получении значений типа JSON в параметрах эксперимента и Feature Flag (по умолчанию равен SigmaGsonAdapter с конструктором по умолчанию).

Пример вызова метода:

import ru.expf.sigma.Sigma
...
Sigma.initializeClient(
application = this,
projectToken = "projectToken",
initialUserProperties = { setUserId("...") },
cacheTtlMillis = 20,
retryCount = 10,
)

Получение объекта SigmaClient

Чтобы получить инстанс SigmaClient используется статический метод Sigma.getClient(). Данный метод принимает следующие параметры:

  • tag - необязательный параметр, тег клиента Sigma (по умолчанию равен 'default').

Завершение работы клиента

Когда работа с клиентом завершена, рекомендуется освободить память от уже ненужного объекта SigmaClient. Для этого используется статический метод Sigma.removeClient().
Данный метод принимает следующие параметры:

  • tag - необязательный параметр, тег клиента Sigma (по умолчанию равен 'default').

Пример создания нескольких клиентов Sigma

Инициализация:

import ru.expf.sigma.Sigma
...
const val TAG_1 = "TAG_1"
const val TAG_2 = "TAG_2"
...
Sigma.initializeClient(
application = this,
projectToken = "...",
tag = TAG_1,
)
Sigma.initializeClient(
application = this,
projectToken = "...",
tag = TAG_2,
)

Использование:

import ru.expf.sigma.*
...
val firstClient = Sigma.getClient(TAG_1)
val secondClient = Sigma.getClient(TAG_2)
...
async {
firstClient.getAllUserExperiments()
secondClient.checkFlag<Float>("...")
}.await()
...
firstClient.setUserProperties { setDeviceId("...") }

Свойства пользователя

Назначение свойств пользователя

Для назначения свойств пользователя используется интерфейс SigmaUserPropertiesSetter. Получить реализацию этого интерфейса можно вызвав методы:

  • Sigma.initializeClient(initialUserProperties = { ... }) - назначение свойств пользователя при инициализации клиента Sigma.
  • SigmaClient.setUserProperties { ... } - назначение свойств пользователя в уже существующем объекте клиента.

В обоих случаях выше - кешированная информация о свойствах пользователя для этого токена проекта + тега инстанса SigmaClient стирается и записывается новая.

Описание методов SigmaUserPropertiesSetter

SigmaUserPropertiesSetter обладает методами для построения набора key-value свойств пользователя. Эти свойства можно разделить на следующие категории:

Идентификаторы использующиеся для назначения вариантов эксперимента:

  • setUserId() - назначение свойства пользователя с названием userId.
  • setDeviceId() - назначение свойства пользователя с названием deviceId.
  • setProfileId() - назначение свойства пользователя с названием profileId.

Свойства которые определяются на уровне SDK, но могут быть переопределены:

  • setAppVersion() - назначение cвойства пользователя с названием appVersion.
  • setGeoCode() - назначение cвойства пользователя с названием geo.code.
  • setGeoCountry() - назначение cвойства пользователя с названием geo.country.
  • setGeoState() - назначение cвойства пользователя с названием geo.state.
  • setGeoCity() - назначение cвойства пользователя с названием geo.city.
  • setOsName() - назначение cвойства пользователя с названием os.name.
  • setOsVersion() - назначение cвойства пользователя с названием os.version.

Свойства которые определяются только разработчиком

  • setEmail() - назначение свойства пользователя с названием email.

Сustom свойства

Такие свойства могут иметь любое название, но при этом к их названию добавится префикс custom.* . (прим. custom.nickname, custom.language).

  • setCustomProperty() - назначение custom-свойства пользователя

Данный метод принимает название и значения свойства и имеет 3 варианта использования:

setCustomProperty("***" to "***")
setCustomProperty { "***" to "***" }
setCustomProperty("***", "***")

Пример использования SigmaUserPropertiesSetter


val client = Sigma.getClient()
client.setUserProperties {
setUserId("id")
setCustomProperty { "length" to "10" }
setAppVersion("7.2.1")
}

Изменение свойств пользователя

Если необходимо добавить или удалить конкретные свойства пользователя или добавить новые используется интерфейс SigmaUserPropertiesEditor. Получить реализацию этого интерфейса можно с вызвав:

  • SigmaClient.editUserProperties { ... }

Работа с ним происходит аналогично с SigmaUserPropertiesSetter, но, в отличии от него, данный интерфейс обладает методами для удаления пользовательских свойств.

Пример:

import ru.expf.sigma.Sigma
...
val client = Sigma.getClient()
client.editUserProperties {
setGeoCountry("USA")
removeEmail()
removeOsVersion()
removeCustomProperty("myProperty")
}

Для удаления всех свойств пользователя используется метод SigmaClient.clearUserProperties().

Пример вызова метода:

import ru.expf.sigma.Sigma
...
val client = Sigma.getClient()
client.clearUserProperties()

Получение значения Feature Flag

Для получения значения Feature Flag используется метод: SigmaClient.checkFlag()

Данный метод принимает следующие параметры:

  • name - название Feature Flag.
  • jClass - необязательный параметр при использовании SigmaClient extension-функции с аналогичным названием, java-класс типа в который преобразуется значение получаемого Feature Flag (Float, Long, Int, Double, String, Boolean), (JSON-класс - см. SigmaJsonAdapter) или null
  • callback - необязательный параметр при использовании suspend версии метода, объект интерфейса SigmaCheckFlagCallback реализующий его методы onSuccess() и onError().

Примеры вызова метода:

*Без использования kotlin.coroutines*

import ru.expf.sigma.*
...
val client = Sigma.getClient()
client.checkFlag(
name = "***",
callback = object: SigmaCheckFlagCallback<String> {
override fun onSuccess(value: String?) {
/** Some code with received value */
}

override fun onError(throwable: Throwable) {
/** Some code with received error */
}
}
)

*С использованием kotlin.coroutines*

import ru.expf.sigma.*
...
async {
val client = Sigma.getClient()
val flagValue = client.checkFlag<String>(name = "***")
}.await()

Стоит обратить внимание на то, что в случае несоответсвия ни одному условию в правилах результат работы метода будет равен null. \ Также, если в данный метод передать тип значения Feature Flag, который не поддерживается со стороны SDK, то он вернет ошибку InvalidParameterSpecException.

Получение эксперимента

Для получения эксперимента используется метод SigmaClient.getExperiment().

Данный метод принимает следующие параметры:

  • id - идентификатор эксперимента.
  • callback - необязательный параметр при использовании suspend версии метода, объект интерфейса SigmaGetExperimentCallback реализующий его методы onSuccess() и onError().

Примеры вызова метода:

*Без использования kotlin.coroutines*

import ru.expf.sigma.Sigma
import ru.expf.sigma.SigmaExperiment
import ru.expf.sigma.SigmaGetExperimentCallback
...
val client = Sigma.getClient()
client.getExperiment(
id = "***",
callback = object : SigmaGetExperimentCallback {
override fun onSuccess(experiment: SigmaExperiment?) {
/** Some code with received experiment */
}

override fun onError(throwable: Throwable) {
/** Some code with received error */
}
}
)

*С использованием kotlin.coroutines*

import ru.expf.sigma.Sigma
import ru.expf.sigma.SigmaExperiment
...
async {
val client = Sigma.getClient()
val experiment = client.getExperiment(id = "***")
}.await()

Стоит обратить внимание на то, что в случае непопадания пользователем в эксперимент результат работы метода будет равен null.

Данный метод возвращает объект интерфейса SigmaExperiment, который реализует следующие поля и методы:

  • поле groupIndex - возвращает индекс группы пользователя.
  • метод getParamValue() - принимают название параметра, возвращают его значение преобразованное в указанный тип (Float, Long, Int, Double, String, Boolean) или null.
  • метод getFeatureFlagValue() - работает аналогично Sigma.checkFlag(), но в пределах эксперимента. (см. Получение значения Feature Flag)

Пример использования

*Без использования kotlin.coroutines*

import ru.expf.sigma.*
...
val client = Sigma.getClient()
client.getExperiment(
id = "***",
callback = object : SigmaGetExperimentCallback {
override fun onSuccess(experiment: SigmaExperiment?) {
val featureFlagValue = experiment?.getFeatureFlagValue<String>("flagName")
val paramValue = experiment?.getParamValue<Double>("paramName")
}

override fun onError(throwable: Throwable) {
/** Some code with received error */
}
}
)

*С использованием kotlin.coroutines*

import ru.expf.sigma.*
...
async {
val client = Sigma.getClient()
val experiment = client.getExperiment(id = "***")
val featureFlagValue = experiment?.getFeatureFlagValue<String>(name = "flagName")
val paramValue = experiment?.getParamValue<Double>(name = "paramName")
}.await()

Получение всех экспериментов пользователя

Для получения всех экспериментов пользователя используется статический метод Sigma.getAllUserExperiments().

Данный метод принимает следующие параметры:

  • callback - необязательный параметр при использовании suspend версии метода, объект интерфейса SigmaGetAllUserExperimentsCallback реализующий его методы onSuccess() и onError() .

Примеры вызова метода:

*Без использования kotlin.coroutines*

import ru.expf.sigma.Sigma
import ru.expf.sigma.SigmaGetAllUserExperimentsCallback
...
val client = Sigma.getClient()
client.getAllUserExperiments(
callback = object : SigmaGetAllUserExperimentsCallback {
override fun onSuccess(experiments: String?) {
/** Some code with received experiments string */
}

override fun onError(throwable: Throwable) {
/** Some code with received error */
}
}
)

*С использованием kotlin.coroutines*

import ru.expf.sigma.Sigma
...
async {
val client = Sigma.getClient()
val experiments = client.getAllUserExperiments()
}.await()

Данный метод возвращает строку вида "expId.userGroupIndex|expId.userGroupIndex|...", где expId - идентификатор эксперимента и userGroupIndex индекс группы пользователя в эксперименте.

Стоит обратить внимание на то, что в случае непопадания пользователем ни в один эксперимент результат работы метода будет равен null.

SigmaJsonAdapter

При получении значения Feature Flag или параметра эксперимента можно указать класс, в поля которого будут записаны значения указанные в JSON по логике выбранного адаптера.

Для того, чтобы не подключать к проекту ещё один JSON-сериализатор в SDK представлены 3 реализации SigmaJsonAdapter для самых популярных:

  • SigmaGsonAdapter - конструктор принимает объект типа Gson
  • SigmaMoshiAdapter - конструктор принимает объект типа Moshi
  • SigmaKotlinAdapter - конструктор принимает объект типа kotlinx.serialization.json.Json

Если в проекте используется не представленный SDK JSON-сериализатор, то можно реализовать свой адаптер. Для этого необходимо унаследовать абстрактный класс SigmaJsonAdapter и реализовать его метод convert.

Список свойств автоматически определяющихся на стороне SDK

  • appVersion - версия приложения пользователя (по умолчанию используется versionCode, а не versionName).
  • os.version - номер версии Android на устройстве пользователя (допустимые значения можно посмотреть тут) .
  • os.name - название операционной системы пользователя (сейчас всегда будет равно " android").
  • time - текущее время пользователя.
  • date - текущая дата пользователя.
  • geo.country - страна пользователя.
  • geo.state - район пользователя.
  • geo.city - город пользователя.
  • geo.ip - IP-адрес пользователя.