---
metadata:
  - name: generator
    content: Diplodoc Platform v5.63.0
alternate:
  - https://ads.yandex.com/helpcenter/ru/dev/ios/swiftui/slider.md
  - href: https://ads.yandex.com/helpcenter/ru/dev/ios/swiftui/slider.md
    type: text/markdown
    title: Markdown version
  - href: https://ads.yandex.com/helpcenter/ru/dev/ios/llms.txt
    rel: describedby
---
> **Documentation Index:** Fetch the complete configuration index at https://ads.yandex.com/helpcenter/ru/llms.txt

[//]: # (Эта страница переводится также на бразильский португальский — pt-BR)

<!--
Используется в Boost: boost/ru/ad-monetization/dev/ios
-->

<!--
Публиковать вместе с релизом SDK, в который вошел PR 15737236: до него SwiftUI-API слайдера
недоступен интеграторам.
-->

# Слайдер рекламных объявлений (SwiftUI)

<!-- source: ru/dev/_includes/slider.md -->
Слайдер — набор объявлений, которые сменяют друг друга, когда пользователь их пролистывает. Ключевые факторы, от которых зависит последовательность — релевантность рекламы для пользователя и потенциальный доход от объявления для владельца приложения. При формировании слайдера система учитывает размещенные рекламные блоки во всем приложении, чтобы исключить повторы. Формат хорошо подойдет приложениям, в которых количество рекламных мест ограничено.
<!-- endsource: ru/dev/_includes/slider.md -->

<!-- source: ru/dev/_includes/slider.md -->
Кроме статичных изображений, в слайдере возможен показ видео, как и для других видов нативной рекламы. Дизайн объявлений можно настроить на стороне разработки мобильного приложения. При этом важно использовать обязательные элементы для корректной отрисовки баннера и учета всех показов.
<!-- endsource: ru/dev/_includes/slider.md -->

<!-- source: ru/dev/_includes/slider.md -->
Слайдер позволяет владельцам приложений увеличить доход за счет разнообразия объявлений и оптимального подбора в рекламном блоке.
<!-- endsource: ru/dev/_includes/slider.md -->

Это руководство покажет, как интегрировать слайдер рекламных объявлений в iOS-приложение на SwiftUI. В дополнение к примерам кода и инструкции оно содержит рекомендации и ссылки на дополнительные ресурсы.

## Пререквизит {#pre}

<!-- source: ru/dev/_includes/pre-ios.md -->
1. Выполните шаги по интеграции SDK, описанные в [Быстром старте](https://ads.yandex.com/helpcenter/ru/dev/ios/quick-start.md).
2. Заранее [проинициализируйте](https://ads.yandex.com/helpcenter/ru/dev/ios/quick-start.md#init) рекламный SDK.
3. Убедитесь, что используете [последнюю версию Yandex Mobile Ads SDK](https://ads.yandex.com/helpcenter/ru/dev/platforms.md), а в случае использования медиации — актуальную [версию единой сборки](https://ads.yandex.com/helpcenter/ru/dev/platforms.md).
<!-- endsource: ru/dev/_includes/pre-ios.md -->

## Имплементация {#implement}

Основные шаги по интеграции слайдера в SwiftUI:

1. Создать `SliderAdState(request:options:)` с запросом `AdRequest` и идентификатором рекламного места. Состояние должно жить дольше одного рендера: держите его в `@StateObject` или во вью-модели.
1. Добавить в иерархию `View` контейнер `SliderAdContainer(state:content:placeholder:)` с этим состоянием.
1. Показать каждую карточку из `SliderAdLayoutInfo.ads` отдельным `NativeAdContainer` внутри горизонтального `ScrollView` с `LazyHStack`.
1. Отрисовать компоненты самого блока, если они есть, примитивами `NativeAdAsset` прямо в содержимом `SliderAdContainer`.
1. Подписаться на события через модификаторы `.onAdLoad`, `.onAdFailure`, `.onAdBindingFailure`, `.onAdImpression` — у слайдера и `.onAdClick`, `.onAdImpression`, `.onAdBindingFailure` — у карточек.
1. Передать [дополнительные настройки](https://ads.yandex.com/helpcenter/ru/dev/ios/target-adfox.md), если вы работаете через систему Adfox (через параметры `AdRequest`).
1. Запустить загрузку вызовом `loadAd()`, например в `onAppear`.

## Особенности подключения слайдера {#features}

1. Все вызовы методов Yandex Mobile Ads SDK необходимо выполнять из главного потока.

2. Карточки должны находиться внутри `SliderAdContainer`. Если показать их отдельно от контейнера блока, каждая карточка засчитает свой показ, а показ самого блока будет потерян.

3. У блока нет собственного клика, поэтому у `SliderAdContainer` нет модификатора `onAdClick`. Нажатия приходят из `NativeAdContainer.onAdClick` каждой карточки.

4. Блок может не содержать собственных компонентов — тогда достаточно карточек, блок все равно будет привязан и его показ будет засчитан. Если же загруженный блок помечает свой компонент как обязательный (обычно это `sponsored`), а примитив для него не отрисован, блок не привязывается и приходит `.onAdBindingFailure`. Поэтому блочные примитивы оборачивайте в проверку `layout.has(_:)`.

5. Если вы получили ошибку в `.onAdFailure`, не пытайтесь загрузить новое объявление снова. Если это необходимо сделать, ограничьте число повторных попыток загрузки рекламы.

6. Содержимое слайдера должно иметь ненулевую высоту и ширину: карточка нулевого размера показ не засчитает.

7. Для каждого объявления в слайдере рекомендуется использовать макет, который включает весь набор возможных компонентов. Как показывает практика, макет, включающий весь набор компонентов, приводит к лучшим конверсиям.

## Загрузка слайдера {#load}

Загрузкой владеет `SliderAdState`. Текущее состояние загрузки публикуется в свойстве `phase`:

* `.idle` — загрузка еще не начиналась;
* `.loading` — загрузка идет;
* `.loaded(SliderAd)` — слайдер загружен и может быть показан;
* `.failed(Error)` — загрузка завершилась ошибкой.

Загрузка начинается только по явному вызову `loadAd()`; после ошибки повторный `loadAd()` отправляет запрос еще раз. Чтобы загрузить слайдер заново с новыми параметрами, создайте новый `SliderAdState` с нужным `AdRequest`. Это аналог повторного вызова `loadAd(with:)` у `SliderAdLoader` в UIKit.

Параметры запроса за рекламой настраиваются через объект класса `AdRequest`, параметры загрузки изображений — через `NativeAdOptions`. Подробнее читайте в разделе [Таргетирование рекламы](https://ads.yandex.com/helpcenter/ru/dev/ios/target.md).

```swift
import SwiftUI
import YandexMobileAds

struct SliderAdView: View {
    @StateObject private var sliderState = SliderAdState(request: AdRequest(adUnitID: "R-M-XXXXX-YY"))

    var body: some View {
        SliderAdContainer(state: sliderState) { layout in
            block(layout)
        } placeholder: {
            ProgressView().frame(maxWidth: .infinity, minHeight: 200)
        }
        .onAdLoad { adInfo in
            // ...
        }
        .onAdFailure { error in
            // ...
        }
        .onAdBindingFailure { error in
            // ...
        }
        .onAdImpression { impressionData in
            // ...
        }
        .onAppear { sliderState.loadAd() }
    }
}
```

Идентификатор рекламного места (adUnitId) получается в интерфейсе Рекламной сети Яндекса.

## Показ слайдера {#ad-view}

В замыкание `content` приходит `SliderAdLayoutInfo`:

* `ads` — состояния `NativeAdState` карточек блока, по одному на объявление, в том порядке, в котором их перечислил блок;
* `has(_:)` — есть ли у самого блока компонент указанного вида, без учета компонентов карточек.

Каждая карточка показывается своим `NativeAdContainer`, а ее верстка ничем не отличается от [обычной нативной карточки](https://ads.yandex.com/helpcenter/ru/dev/ios/swiftui/native.md#ad-view): те же примитивы `NativeAdAsset` и тот же `NativeAdLayoutInfo`. Полный перечень компонентов приведен в разделе [Компоненты нативной рекламы](https://ads.yandex.com/helpcenter/ru/dev/ios/components.md).

```swift
private func block(_ layout: SliderAdLayoutInfo) -> some View {
    VStack(alignment: .leading, spacing: 8) {
        if layout.has(.sponsored) {
            NativeAdAsset.Sponsored()
                .font(.caption2)
                .foregroundColor(.secondary)
        }

        ScrollView(.horizontal, showsIndicators: false) {
            LazyHStack(spacing: 8) {
                ForEach(layout.ads) { adState in
                    card(adState)
                }
            }
        }
    }
}

private func card(_ adState: NativeAdState) -> some View {
    NativeAdContainer(state: adState) { layout in
        VStack(alignment: .leading, spacing: 8) {
            HStack(spacing: 8) {
                NativeAdAsset.Icon()
                    .frame(width: 40, height: 40)
                    .clipShape(RoundedRectangle(cornerRadius: 8))
                VStack(alignment: .leading) {
                    NativeAdAsset.Title().font(.headline).lineLimit(2)
                    HStack(spacing: 4) {
                        NativeAdAsset.Domain().font(.caption).foregroundColor(.secondary)
                        NativeAdAsset.Sponsored().font(.caption2).foregroundColor(.secondary)
                        NativeAdAsset.Age().font(.caption2).foregroundColor(.secondary)
                    }
                }
                Spacer()
                NativeAdAsset.Feedback()
                    .frame(width: 24, height: 24)
            }

            NativeAdAsset.Media()
                .clipShape(RoundedRectangle(cornerRadius: 12))

            NativeAdAsset.Body().font(.subheadline).lineLimit(3)

            NativeAdAsset.CallToAction { text in
                Text(text)
                    .bold()
                    .frame(maxWidth: .infinity, minHeight: 44)
                    .background(Color.accentColor)
                    .foregroundColor(.white)
                    .clipShape(Capsule())
            }

            NativeAdAsset.Warning().font(.caption2).foregroundColor(.secondary)
        }
        .padding(12)
        .frame(width: 320)
    } placeholder: {
        ProgressView().frame(width: 320, height: 200)
    }
    .onAdClick { }
    .onAdImpression { _ in }
    .onAdBindingFailure { _ in }
}
```

{% note tip %}

Начиная с iOS 17 к горизонтальному `ScrollView` можно добавить `.scrollTargetBehavior(.viewAligned)` и `.scrollTargetLayout()` на `LazyHStack`, чтобы карточки листались по одной.

{% endnote %}

## События {#events}

#|
|| **Модификатор** | **Значение в замыкании** | **Когда вызывается** ||
|| `onAdLoad` | `AdInfo?` | Слайдер успешно загружен ||
|| `onAdFailure` | `Error` | Загрузка завершилась ошибкой ||
|| `onAdBindingFailure` | `Error` | Загруженный блок не удалось связать с отрисованным содержимым ||
|| `onAdImpression` | `ImpressionData?` | Показ блока засчитан ||
|#

Показы и клики отдельных объявлений приходят в `onAdImpression` и `onAdClick` соответствующего `NativeAdContainer`.

## Ручная загрузка изображений {#manual-images}

Если изображения нужно загружать самостоятельно, передайте в состояние `NativeAdOptions(shouldLoadImagesAutomatically: false)`. Метод `SliderAdState.loadImages()` загружает изображения блока и всех его карточек сразу и завершается, когда они загружены; примитивы перерисовываются сами.

```swift
@StateObject private var sliderState = SliderAdState(
    request: AdRequest(adUnitID: "R-M-XXXXX-YY"),
    options: NativeAdOptions(shouldLoadImagesAutomatically: false)
)

func loadImages() {
    Task { await sliderState.loadImages() }
}
```

{% note warning %}

Показ засчитывается по видимости и не ждет изображений. Пока `loadImages()` не завершился, показывайте свой плейсхолдер.

{% endnote %}

## Тестирование интеграции слайдера {#test}

### Использование демоблоков для тестирования рекламы {#demo-blocks}

Для проверки корректной интеграции слайдера, а также для тестирования вашего приложения, рекомендуется использовать тестовую рекламу.

Демонстрационный adUnitId для слайдера: `demo-native-slider-yandex`.

{% note warning %}

Убедитесь, что перед выкладыванием приложения в store, вы заменили демонстрационный идентификатор рекламного места на настоящий, полученный в интерфейсе Рекламной сети Яндекса.

{% endnote %}

### Проверка корректной интеграции рекламы {#test-int}

<!-- source: ru/dev/_includes/test-integration-ios.md -->
Проверить корректность интеграции рекламы можно через нативный инструмент Console.

Чтобы получить возможность просматривать расширенные логи, необходимо вызвать метод `enableLogging` класса `YandexAds`.

```swift
YandexAds.enableLogging()
```

Для просмотра логов SDK в инструменте Console установите `Subsystem = com.mobile.ads.ads.sdk`. Вы можете фильтровать логи по категории и уровню ошибки.

В случае обнаружения проблем при интеграции рекламы вы увидите подробный отчет о проблемах и рекомендации по их устранению.

<img src= "https://yastatic.net/s3/doc-binary/src/dev/mobile-ads/common/integration-ios-2.png">
<!-- endsource: ru/dev/_includes/test-integration-ios.md -->

## Дополнительные ресурсы {#resources}

* <!-- source: ru/dev/_includes/github-pubdev-links.md -->
  Ссылка на [github](https://github.com/yandexmobile/yandex-ads-sdk-ios).
  <!-- endsource: ru/dev/_includes/github-pubdev-links.md -->
