Передача данных во флоу в iOS SDK
Пользовательский тег — это кастомная переменная, значение которой задаётся в вашем приложении. Если в настройках переменной выбрать Value comes from outside the app, приложение сможет передавать её значение через Adapty SDK. Например, текстовый элемент содержит «Coins:» и пользовательский тег. Если приложение передаёт «120» для этого тега, пользователь видит «Coins: 120».
Прежде чем начать
Вам необходим Adapty SDK версии 4 или выше. Версии ниже v4 не отображают флоу.
Добавление кастомных тегов во флоу
Чтобы отображать значения из вашего приложения во флоу, настройте кастомные теги в билдере:
-
Создайте кастомный тег для каждого значения, которое передаёт ваше приложение.
-
Запишите полное имя каждого тега, включая его группу. Именно под этим именем код вашего приложения передаёт каждое значение. Например, если группа
userсодержит тегstreak, полное имя тега —user.streak.
Передача значений кастомных тегов
Передайте значения вашего приложения в параметр tagResolver метода getFlowConfiguration в виде словаря [String: String]:
- Каждый ключ — это полное имя кастомного тега, например
user.streak. - Каждое значение — это строка, которую пользователи видят вместо тега.
- Каждое значение должно быть удобочитаемым, например “1 250”, а не “1250.0”. Adapty не форматирует и не переводит его.
let customTags = [
"username": "DragonSlayer42",
"coins": "1,250",
]
do {
let flowConfiguration = try await AdaptyUI.getFlowConfiguration(
forFlow: flow,
tagResolver: customTags
)
// present the flow
} catch {
// handle the error
}
SwiftUI модификатор .flow и AdaptyFlowView, а также UIKit контроллер флоу не имеют параметра для пользовательских значений тегов. Они отображают значения из конфигурации флоу, которую вы им передаёте.
Чтобы протестировать пользовательские теги, откройте флоу в своём приложении после добавления кода, который устанавливает их значения. Холст конструктора и предпросмотр на устройствах отображают только начальные значения: мобильное приложение Adapty не устанавливает значения пользовательских тегов.
Если ваше приложение уже задаёт пользовательские значения тегов для пейволов старого Paywall Builder, ознакомьтесь с тем, чем пользовательские теги во флоу отличаются.
Что видят пользователи при отсутствии значения
Пользователи видят Начальное значение пользовательского тега как резервное в следующих случаях:
- Ваше приложение не передаёт никакого значения для тега.
- Пользователь не обновил приложение до версии, которая передаёт это значение.
- Имя в коде вашего приложения не совпадает с полным именем тега, включая регистр букв.
- Другой пользовательский тег в том же текстовом элементе не имеет значения. В этом случае каждый пользовательский тег в этом текстовом элементе показывает своё начальное значение.
Чтобы ничего не отображалось вместо тега, передайте пустую строку. Adapty считает пустую строку значением, поэтому резервный вариант не показывается.
Пример: показ ИМТ по ответам из онбординга
Флоу может собирать ответы пользователей, а кастомный тег — показывать значение из вашего приложения. Объедините эти возможности, чтобы показывать пользователям результат, который приложение вычисляет на основе их ответов: оценку, рекомендованный план или метрику здоровья:
- Флоу собирает ответы и передаёт их в ваше приложение.
- Приложение вычисляет результат.
- Приложение передаёт результат в следующий флоу в виде значения кастомного тега.
В этом примере онбординг-флоу собирает вес и рост пользователя. Когда пользователь закрывает онбординг-флоу после последнего экрана, приложение вычисляет индекс массы тела (ИМТ). Затем открывается пейвол-флоу, который показывает этот ИМТ.
Настройка флоу
-
Создайте два флоу: онбординг-флоу, собирающий вес и рост пользователя, и флоу-пейвол, показывающий его ИМТ.
-
Добавьте два поля Number в онбординг-флоу:
- Одно для веса в килограммах с Element ID
weight. - Одно для роста в сантиметрах с Element ID
height.
Для обоих полей установите Format в значение Integer. Поле отправляет значение как текст, точно так, как его ввёл пользователь, а пример кода не воспринимает «70.5» и «70,5» одинаково. Целые числа не содержат разделителя дробной части, поэтому код читает их одинаково в любой локали.
- Одно для веса в килограммах с Element ID
-
Чтобы убедиться, что приложение получает оба значения, завершите онбординг-флоу экраном без полей ввода. На этом экране добавьте кнопку с действием Close flow. Поля отправляют свои значения при потере фокуса или при переходе пользователя на другой экран. Действие Close flow не отправляет их. Пример кода открывает пейвол только в том случае, если пользователь добрался до последнего экрана.
-
В флоу-пейволе создайте кастомный тег с именем
bmi. В поле Initial value введите тире (—). Пользователь увидит тире, если приложение не передало значение ИМТ. -
Добавьте текстовый элемент со словами «Your BMI:» в флоу-пейвол. После этих слов вставьте кастомный тег
bmi. -
Добавьте онбординг-флоу в плейсмент, например
onboarding. Добавьте флоу-пейвол в плейсмент с IDbmi_paywall. Код из раздела Pass the BMI to the paywall получает пейвол по этому ID.
Передайте BMI на пейвол
Соберите вес и рост пользователя из событий flow_user_input флоу онбординга, как описано в Обработка данных из флоу. Чтобы определить, что пользователь дошёл до последнего экрана, отслеживайте событие flow_screen_showed с is_last_screen равным true, как описано в Отслеживание просмотров экранов флоу. Когда пользователь закрывает флоу онбординга после этого экрана, вычислите BMI. Затем загрузите конфигурацию флоу пейвола и передайте BMI для кастомного тега bmi.
Следующий код написан для UIKit. В нём реализованы методы AdaptyFlowControllerDelegate в одном контроллере представления, который является делегатом как контроллера флоу онбординга, так и контроллера пейвола. Контроллер представления также должен реализовывать методы делегата для покупки и восстановления — в этом примере они опущены. Чтобы их увидеть, перейдите в раздел Отображение флоу и пейволов в UIKit.
private var bodyAnswers: [String: String] = [:]
private var reachedLastScreen = false
func flowController(
_ controller: AdaptyFlowController,
didReceiveAnalyticEvent name: String,
params: [String: any Sendable]
) {
if name == "flow_screen_showed", params["is_last_screen"] as? Bool == true {
reachedLastScreen = true
return
}
guard name == "flow_user_input",
let elementId = params["element_id"] as? String,
let value = params["value"] as? String
else { return }
bodyAnswers[elementId] = value
}
func flowControllerDidDisappear(_ controller: AdaptyFlowController) {
// This delegate receives events from both flows. Reset `bodyAnswers` and
// `reachedLastScreen` whenever a flow disappears, so that the paywall
// doesn't open again when the user closes it.
let answers = bodyAnswers
let finished = reachedLastScreen
bodyAnswers.removeAll()
reachedLastScreen = false
// Number inputs send their values as strings.
guard finished,
let weight = answers["weight"].flatMap({ Double($0) }),
let height = answers["height"].flatMap({ Double($0) }),
height > 0
else { return }
let heightInMeters = height / 100
let bmi = weight / (heightInMeters * heightInMeters)
Task {
await showBMIPaywall(bmi: bmi.formatted(.number.precision(.fractionLength(1))))
}
}
func showBMIPaywall(bmi: String) async {
do {
let flow = try await Adapty.getFlow(placementId: "bmi_paywall")
let flowConfiguration = try await AdaptyUI.getFlowConfiguration(
forFlow: flow,
tagResolver: ["bmi": bmi]
)
let flowController = try AdaptyUI.flowController(
with: flowConfiguration,
delegate: self
)
present(flowController, animated: true)
} catch {
// handle the error
}
}
formatted использует десятичный разделитель из локали пользователя: “22.7” в английской, “22,7” в немецкой.
В SwiftUI используйте замыкания модификатора .flow онбординг-флоу вместо методов делегата:
didReceiveAnalyticEvent: собирайте вес и рост, а также отслеживайте событиеflow_screen_showedпоследнего экрана.didDisappear: если пользователь дошёл до последнего экрана, вычислите ИМТ. Затем получите конфигурацию флоу пейвола и передайте ИМТ в кастомный тегbmi. Отобразите эту конфигурацию с помощью второго модификатора.flow.
Сохранение ИМТ в профиль пользователя
Чтобы показывать пользователям разные флоу в зависимости от ИМТ, сохраните его как пользовательский атрибут профиля. В дашборде Adapty создайте пользовательский атрибут типа Number с ключом bmi. Затем покажите каждый флоу нужной аудитории, сформированной на основе этого атрибута.
Вызовите метод updateProfile внутри flowControllerDidDisappear — сразу после строки, где вычисляется bmi. Передавайте именно Double, а не форматированную строку, чтобы сегмент мог сравнивать ИМТ с пороговым значением:
do {
let params = try AdaptyProfileParameters.Builder()
.with(customAttribute: bmi, forKey: "bmi")
.build()
try await Adapty.updateProfile(params: params)
} catch {
// handle the error
}