A/B-тестирование интерфейса в iOS
В этом сценарии сервер выбирает вариант кнопки перехода к оплате, а приложение рисует его по content.custom?.json. Сначала инициализируйте SDK. Методы выбора контента сами не показывают UI; ограничения автопоказа описаны в Своём UI и Custom JSON.
Для ручного учёта показа отключите неявный impression в Options после инициализации:
GravitySDK.instance.setOptions(
options: Options(isImplicitImpression: false),
contentSettings: nil,
proxyUrl: nil
)
Настройка глобальная. Если приложение уже задаёт ContentSettings или proxyUrl, передайте их здесь вместо nil; остальные Options тоже сохраните явно. Проверьте tracking показов кампании по фактическому ответу сервера.
Подготовьте кампанию
- Создайте кампанию в приложении с двумя вариантами и нужным распределением аудитории для A/B-теста.
- Настройте кампанию с Custom JSON для selector
checkout_button, контекстомCARTи locationapp://cart. Для примера используйте один корневой content без дополнительных шагов (stepотсутствует). - В контрольном варианте задайте JSON:
{ "variant": "control", "label": "Перейти к оплате" }
- Во втором варианте задайте JSON:
{ "variant": "compact", "label": "Оформить заказ" }
- Опубликуйте кампанию. Названия
variantи типы полей должны совпадать с моделями приложения. Настройте цель по бизнес-событиюcheckout-started-v1, которое отправляется при нажатии кнопки.
Приложение не распределяет аудиторию случайным образом: оно использует вариант из ответа сервера. Повторный выбор контента выполняйте при новом открытии размещения или явном обновлении, а не при каждом пересчёте UI.
Получите и проверьте вариант
Добавьте в проект gravity_content.swift и ab_example.swift. Первый файл загружает корневой content и проверяет JSON; второй показывает кнопку и отправляет engagement. Модель принимает только control и compact, непустой label и корректные типы полей.
let cartContext = PageContext(type: .cart, data: [], location: "app://cart")
CheckoutExperimentView(pageContext: cartContext, onCheckout: openCheckout)
.id(placementKey)
placementKey — Hashable-ключ размещения, которым управляет приложение. Меняйте его при смене контекста, чтобы создать отдельное состояние загрузки. Сам PageContext в iOS SDK имеет Equatable, но не Hashable и не подходит для .id(...).
Fallback
Если нет кампании, запрос завершился ошибкой, JSON повреждён, variant неизвестен или label пуст, показывайте стандартную кнопку приложения. Пример не связывает такой fallback с campaign/content и не отправляет ему impression выбранного варианта.
Не считайте fallback контрольной группой теста: контрольный вариант должен прийти из опубликованной кампании. Сбой выбора контента — отдельное состояние интеграции.
Учтите фактический показ
getContentBySelector автоматически отправляет content load tracking. Это не подтверждение показа кнопки. Пример отправляет ContentImpressionEngagement только после появления UI с успешно разобранным вариантом и сохраняет исходные campaign/content для аналитики.
Показ в примере означает появление компонента в UI, без проверки перекрывающих слоёв. Если нужно учитывать видимость в scroll-контейнере, реализуйте detector и отправляйте ContentVisibleImpressionEngagement по правилам собственного UI. Не отправляйте impression ещё раз из callback загрузки.
При нажатии кнопки отдельно отправляется CustomEvent типа checkout-started-v1 с текущим PageContext. Публичного ContentClickEngagement у native SDK нет. Результат теста оценивайте по выбранной бизнес-цели, а не по числу загрузок JSON.
Проверка
- Убедитесь, что оба серверных варианта отображаются с ожидаемым label и отступами.
- Проверьте пустой ответ, ошибку сети, неизвестный variant и некорректные типы JSON: стандартный UI должен работать.
- Проверьте, что загрузка не учитывается как ручной показ, а повторный пересчёт UI не создаёт новый выбор варианта.
- Проверьте бизнес-событие после нажатия и отсутствие impression кампании для fallback.