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-адрес пользователя.