Кампании и рекомендации в iOS
Сначала подключите SDK и опубликуйте кампанию в приложении. Навигация по URL/deeplink реализуется в приложении через callback.
In-App кампании
SDK автоматически показывает кампании с deliveryMethod:
fullScreenmodalbottomSheetsnackBar
Что требуется для автопоказа:
- подходящая активная кампания на backend;
- корректный
PageContext; - доступный
UIViewControllerв момент показа после загрузки и задержки кампании; - заполненный
variables.elementsв ответе и снятая presentation lock. Блокировка новых in-app показов описана в Конфигурации.
Inline-компоненты
iOS SDK предоставляет компоненты для загрузки по selector и группе:
GravityInlineSwiftUIView— для SwiftUI-экранов;GravityInlineView— для UIKit-экранов, включая ячейкиUITableView;GravityInlineListView— горизонтальный список блоков из группы кампаний для UIKit.
SwiftUI:
GravityInlineSwiftUIView(
selector: "homepage-recommendations",
pageContext: PageContext(
type: .homepage,
data: [],
location: "app://homepage"
)
)
UIKit:
let inlineView = GravityInlineView(selector: "homepage-recommendations")
inlineView.initialize(
pageContext: PageContext(
type: .homepage,
data: [],
location: "app://homepage"
)
)
Что важно учесть:
selectorдолжен совпадать с selector кампании на backend;PageContextдолжен соответствовать таргетингу кампании;- если backend не вернул подходящий контент, компонент останется пустым;
- для UIKit-компонента нужно корректно настроить constraints и вызвать
initialize(pageContext:); - высота inline-блока может обновляться по
frameUI.container.style.size.height, если это значение пришло с backend.
Оба одиночных компонента поддерживают loader:
GravityInlineSwiftUIView(selector: "homepage-recommendations", pageContext: pageContext) {
ProgressView()
}
inlineView.initialize(pageContext: pageContext) {
ProgressView()
}
Для группы кампаний:
let listView = GravityInlineListView(groupSelector: "homepage-group")
listView.initialize(pageContext: pageContext) {
ProgressView()
}
У UIKit list-компонента высота берётся из максимального frameUI.container.style.size.height среди загруженных блоков. Если ни у одного блока высота не задана, SDK устанавливает 0; задайте размер в кампании.
После успешной загрузки эти компоненты сохраняют полученный контент. Изменение PageContext на том же экземпляре не гарантирует новый запрос: UIKit-компоненты прекращают загрузку, когда контент уже сохранён, а SwiftUI-компонент загружает его в onAppear. Для смены товара/контекста создайте новый UIKit view или измените identity SwiftUI view через .id(...). Публичных методов сброса inline-кэша, как в Android SDK, здесь нет.
Встроенный iOS рендерер отображает товарный контейнер только в layout row; для grid он возвращает EmptyView. Если нужна сетка, используйте собственный рендерер.
Карточки товаров
ProductViewBuilder нужен для отображения карточек товара в product-based или recommendation-блоках. Это обязательная часть интеграции товарных рекомендаций: приложение должно передать SDK шаблон карточки, иначе SDK не знает, какой UI использовать для товара в вашем приложении.
SDK получает блок рекомендаций, управляет контейнером, списком слотов и tracking-контекстом, но сам шаблон товарной карточки задает приложение. Разработчик реализует ProductViewBuilder или LegacyProductViewBuilder и передает его в GravitySDK.initialize(...) через параметр productViewBuilder.
После этого SDK использует переданный шаблон для каждого товара в блоке: вызывает builder для каждого slot и передает в него slot, content и campaign. Поэтому карточка отображается как native UI приложения, а не как готовая карточка, нарисованная SDK.
slot содержит данные одного рекомендованного товара:
slot.item- словарь с полями товара из фида или из запрошенныхfields: напримерsku,name,price,old_price,image_url,url,brand,currencyи другие кастомные поля;slot.strIdиslot.slotId- идентификаторы позиции товара в выдаче;slot.fallback- признак, что товар пришел из fallback-логики;slot.events- tracking-данные товара, которые SDK использует при отправке engagement.
Названия ключей в slot.item должны совпадать с вашим фидом и настройкой fields. Например, если в ответе приходит imageUrl, читайте imageUrl; если используется поле фида image_url, читайте image_url.
Сигнатуры протоколов — в справочнике API.
Пример шаблона карточки:
Полный пример: product_view_builder.swift. Реализуйте openProduct и передайте MyProductBuilder в initialize. Изображения через SwiftUI.AsyncImage доступны с iOS 15; для iOS 14 подключите свой загрузчик.
Что важно учесть:
ProductViewBuilderполучаетslot,contentиcampaign, поэтому карточка товара может учитывать контекст кампании и content block;- если в приложении уже есть UIKit-карточка товара, используйте
LegacyProductViewBuilderи вернитеUIViewизcreateView(...); - SDK автоматически отслеживает visible impression товара во встроенном блоке, а tap по кастомной карточке приложение отправляет вручную через
sendProductEngagement(...)перед навигацией; productFilterприменяется кProducts.slotsпри декодировании ответа SDK. Используйте его только для простого клиентского исключения слотов, когда это действительно нужно в приложении.
Кто отправляет engagement
Успешная загрузка автоматически отправляет content load tracking. Встроенные UI-компоненты отправляют показы контента, видимость товаров и tracking для поддерживаемых действий. Карточка из ProductViewBuilder уже обёрнута detector SDK: вручную отправляйте её клик перед навигацией, не дублируйте visible impression.
Ручные вызовы engagement не генерируют tracking callback. Для собственного UI используйте отдельные правила аналитики.
iOS учитывает не менее 50% площади в окне сразу, один раз на экземпляр detector.