Оптимизация загрузки пейвола в iOS SDK
Надёжная загрузка пейвола на iOS решает три задачи: быстрый рендеринг, возврат пейвола с нужной аудиторией и корректный фолбэк при медленной сети. Правила ниже охватывают тайминг, кэширование и резервные сценарии.
Правила предполагают, что Adapty.activate() и Adapty.identify() уже завершились. См. Порядок вызовов в iOS SDK.
Правила и подводные камни
| Делайте это | Не делайте это | Почему |
|---|---|---|
Загружайте плейсмент перед показом или прогревайте кэш с помощью preloadFlows (SDK 4.1+). | Не запускайте свои параллельные вызовы getFlow при старте приложения. | Самодельный burst-префетч блокирует главный поток и вызывает чёрный экран. preloadFlows создан для этого и использует единый таймаут для всего пакета. |
Вызывайте getPaywall после того, как атрибуция успела разрешиться — например, через 1–2 секунды после activate или после срабатывания onProfileUpdate. | Не вызывайте getPaywall в App.init(). | Атрибуция ещё не поступила. Пейвол разрешается по дефолтной аудитории и молча обходит сегменты и персонализацию ASA. |
Задайте loadTimeout и настройте резервный пейвол для каждого плейсмента. | Не ждите ответа getPaywall бесконечно. | Без таймаута пользователи с плохим соединением видят пустой экран до тех пор, пока сеть не ответит, — или закрывают приложение. |
Подробнее о параметрах fetchPolicy и loadTimeout — в разделе Получение пейволов и продуктов, о выборе подходящего плейсмента — в разделе Плейсменты.
Предзагрузка плейсментов
Эти методы доступны начиная с версии SDK 4.1.
preloadFlows и preloadOnboardings заранее загружают плейсменты в кэш SDK. Последующий вызов getFlow или getOnboarding для того же плейсмента разрешается из кэша, а не из сети — пейвол отображается без видимой задержки.
Используйте их, когда вы заранее знаете, какие плейсменты понадобятся в текущей сессии, но не хотите показывать их прямо сейчас — например, сразу после завершения activate и identify, для пейвола за кнопкой, которую пользователь ещё не нажал.
Параметры:
placementIds(обязательный): плейсменты для предзагрузки. Пустые и дублирующиеся идентификаторы игнорируются.locale(необязательный, только дляpreloadOnboardings): локаль онбординга для кэширования.loadTimeout(необязательный): таймаут в секундах для всего пакета, а не для отдельного плейсмента. По умолчанию — 5 секунд; значения ниже 1 секунды округляются до 1 секунды.
Важные особенности поведения:
- Методы выбрасывают исключение только после попытки обработать все плейсменты, а ошибка агрегирует сбои по каждому из них. Сбой в одном плейсменте не останавливает остальные.
- Если плейсмент завершается таймаутом или сетевой ошибкой, SDK откатывается к варианту для аудитории по умолчанию для этого плейсмента. Остальные сбои сообщаются как есть.
- Если таймаут срабатывает до завершения запроса с таргетингом по аудитории, SDK всё равно пытается получить вариант для аудитории по умолчанию в рамках оставшегося бюджета.
- Предзагрузка только прогревает кэш. Она не возвращает контент — для отображения по-прежнему нужно вызывать
getFlowилиgetOnboarding.
Определите, какой плейсмент не загрузился
Выброшенная ошибка — это один объект AdaptyError, охватывающий весь пакет, с кодом networkFailed (2002). Чтобы увидеть отдельные сбои, обратитесь к свойству preloadErrors — словарю с ключами по идентификаторам плейсментов:
do {
try await Adapty.preloadFlows(placementIds: ["onboarding", "main_paywall"])
} catch {
for (placementId, placementError) in error.preloadErrors ?? [:] {
// log or retry the individual placement
}
}
preloadErrors равен nil для любой ошибки, которая не возникла в результате вызова preload, поэтому значение nil означает «не ошибка предзагрузки», а не «ошибок нет».
Чтобы прогреть кэш без ожидания сегментации аудитории, используйте варианты для аудитории по умолчанию:
try await Adapty.preloadFlowsForDefaultAudience(placementIds: ["main_paywall"])
try await Adapty.preloadOnboardingsForDefaultAudience(placementIds: ["intro"])
Настройка для слабого соединения
Для рынков с постоянно плохим интернетом (сельская местность, транспорт, регионы с проблемами маршрутизации):
- Используйте
fetchPolicy: .returnCacheDataElseLoadдля всех запросов, кроме самого первого. - Настройте резервный пейвол для каждого плейсмента в дашборде Adapty.
- Установите
loadTimeoutв диапазоне 3–5 секунд и принимайте резервный пейвол при срабатывании таймаута. - Не блокируйте отображение пейвола вызовом
getProfile(). ВызывайтеgetPaywallнезависимо, чтобы медленный профиль не задерживал интерфейс.