# Пример: проверка товаров перед показом in-app

Пример для Android и iOS SDK 1.1.0: приложение проверяет, о каких купленных товарах пользователь может оставить отзыв, и передаёт их SDK для показа. Для проверки используется `inAppPreparation`, для перехода к форме — `dismissInApp`.

## Подготовьте кампанию

Создайте [кампанию в приложении](/personalization/Campaigns/app_campaigns/getting_started.md) с selector `purchase-reviews`, форматом bottom sheet и строкой товаров. Выберите стратегию недавно купленных товаров без fallback на непокупавшиеся. Настройте триггер, контекст и частоту показа, затем опубликуйте кампанию.

Покупки должны передаваться с корректными SKU и [идентификацией пользователя](../identification.md). Доступность отзыва проверяет API приложения.

## Подключите пример

1. Установите [Android SDK](./android/overview.md) или [iOS SDK](./ios/overview.md) версии 1.1.0.
2. Добавьте в приложение полный пример: [review_prompt.kt](./android/examples/review_prompt.kt) или [review_prompt.swift](./ios/examples/review_prompt.swift).
3. Реализуйте `ReviewEligibilityAPI`: один отменяемый запрос принимает ключ аккаунта и список SKU, возвращает SKU, доступные для отзыва. Запрос должен использовать авторизацию указанного аккаунта.
4. Создайте один экземпляр `ReviewPromptIntegration`. Передайте API, selector кампании, потокобезопасный `currentAccountKey`, обычный `ProductViewBuilder` для остальных кампаний и обработчик открытия формы `onOpenReview`.
5. При инициализации SDK передайте `reviewIntegration.productViewBuilder` в `productViewBuilder`, а результат `reviewIntegration.preparation()` — в `inAppPreparation`. Остальные параметры возьмите из быстрого старта своей платформы.

`ReviewPromptIntegration` и `ReviewEligibilityAPI` — код примера, а не встроенные типы SDK. Selector в конструкторе примера — обычная строка без JSON-кавычек.

## Показ и переход к форме

Обработчик проверяет все SKU одним запросом и фильтрует исходные слоты через `filteringProducts`. Порядок и tracking сохраняются. Другие кампании возвращаются без изменений. Если подходящих товаров нет, API вернул ошибку или проверка превысила 5 секунд, in-app пропускается.

Кнопка отправляет `ProductClickEngagement`, затем вызывает `dismissInApp`. Форма открывается после результата `true`, когда SDK закрыл сообщение. Повторный вызов во время закрытия получает `false`. Close отправляет SDK — дублировать его вручную не нужно.

После успешного сохранения отзыва вызовите `didSubmitReview` с SKU и ключом аккаунта, для которого открывали форму. Локальный статус разделён по аккаунтам и хранится в памяти; после перезапуска доступность отзыва определяет API приложения.

## Условия работы

Подготовка выполняется при автопоказе после `trackView`/`triggerEvent` и переходах между шагами. Ручные `getContentBy*` и inline её не вызывают. Пропущенный контент не отправляет impression и visible impression; content load tracking означает только загрузку.

При смене аккаунта обновляйте пользователя через `setUser`. Для навигации внутри одной Activity или контроллера используйте presentation lock. Устаревший результат проверки не показывается; после разблокировки нужен новый просмотр или событие.

Сигнатуры, параметры и ограничения: [Android API](./android/api_reference.md#подготовка-и-закрытие-in-app) и [iOS API](./ios/api_reference.md#подготовка-и-закрытие-in-app).
