# Multiformat

Multiformat — это встраиваемые рекламные блоки внутри контента приложения c каруселями или одиночными баннерами. В каждом креативе поддерживается отображение картинок, в будущем появится поддержка видео.

Подробнее о форматах - в разделе Рекламные форматы.

# 1. Загрузка рекламы

При загрузке рекламы необходимо передать AdSlot, содержащий padId (идентификатор места размещения) и position (позиция в списке). padId можно получить в рекламной админке либо от менеджера. Для отладки можно использовать тестовые padId (см. Отладка).

Создайте загрузчик и подпишитесь через делегат:

import MadSDK

private let loader = InlineAdLoader()
loader.delegate = self

Вызовите loader.load(...):

let request = InlineAdRequest(
    slot: AdSlot(padId: "1"),
    targetings: ["some_targeting": "value"],
    isDebugCreativeEnabled: false
)

loader.load(request)

Отмена загрузки:

let cancellable = loader.load(request)

// Отмена в любой момент
cancellable.cancel()

Для загрузки вызовите MadsSDK.inLine.load(...):

import MadSDK

let request = InlineAdRequest(
    slot: AdSlot(padId: "1"),
    targetings: ["some_targeting": "value"],
    isDebugCreativeEnabled: false
)

let response = await MadsSDK.inLine.load(request)

Простановка таймаута загрузки рекламы:

let task = Task {
    await MadsSDK.inLine.load(request)
}

Task {
    try? await Task.sleep(for: .seconds(10))
    task.cancel()
}

Отмена загрузки:

let task = Task {
    await MadsSDK.inLine.load(request)
}

// Отмена в любой момент
task.cancel()

# Параметры запроса (InlineAdRequest)

Параметр Тип Обязательный Описание
slot AdSlot Идентификатор места размещения
targetings [String: String] Словарь таргетингов для персонализации рекламы (по умолчанию: [:])
isDebugCreativeEnabled Bool Загрузка дебаг-креативов (по умолчанию: false)

# Параметры AdSlot

при наличии нескольких рекламных блоков на экране можно передавать один padId и разные position. Например, в листинге товаров InLine блок может повторяться через каждые 3 ряда карточек. Необходимо для первой позиции передавать position: 0, для второй position: 1 и так далее, при этом padId один и тотже.

Параметр Тип Обязательный Описание
padId String Id места размещения
position Int Позиция внутри места размещения (по умолчанию: 0)

# 2. Таргетирование

Передайте словарь таргетингов при загрузке рекламы. Подробнее о таргетингах — в разделе Таргетирование.

let targetings: [String: String] = ["gender": "female"]

loader.load(
    InlineAdRequest(
        slot: AdSlot(padId: "1"),
        targetings: targetings
    )
)
let targetings: [String: String] = ["gender": "female"]

let request = InlineAdRequest(
    slot: AdSlot(padId: "1"),
    targetings: targetings
)

let response = await MadsSDK.inLine.load(request)

# 3. Обработка результата запроса и встраивание рекламы

Обработайте результат загрузки и встройте рекламу в интерфейс приложения:

extension ViewController: InlineAdLoaderDelegate {
    func inlineAdLoader(
        _ loader: InlineAdLoaderProtocol,
        didReceive response: InlineAdLoader.Response
    ) {
        switch response {
        case let .success(inlineAd, slot):
            // Получить UIView для встраивания
            let adView = MadsSDK.render(inlineAd, inVC: self)
            container.addSubview(adView)
        case let .failure(error, slot):
            // Загрузка завершилась с ошибкой
            break
        case let .noContent(slot):
            // Реклама не была подобрана
            break
        }
    }
}
let response = await MadsSDK.inLine.load(request)

switch response {
case let .success(inlineAd, slot):
    // Получить UIView для встраивания
    let adView = MadsSDK.render(inlineAd, inVC: self)
    container.addSubview(adView)
case let .failure(error, slot):
    // Загрузка завершилась с ошибкой
    break
case let .noContent(slot):
    // Реклама не была подобрана
    break
}

# Возможные состояния

Тип значения Параметры Описание
success inlineAd — загруженная реклама, slot — информация о размещении Реклама загружена успешно. Получить view вызвав MadsSDK.render(...).
failure error — причина ошибки, slot — информация о размещении Загрузка рекламы завершилась ошибкой.
noContent slot — информация о размещении Запрос завершился без ошибок, но реклама не была подобрана.

# Возможные ошибки загрузки (InlineAdLoadError)

Тип значения Описание
network Ошибка сети при загрузке рекламы
sdkNotInitialized SDK не инициализирован
adLoad Не удалось загрузить рекламу
cancelled Загрузка рекламы отменена

# 4. Реакция на действия пользователя

SDK не реагирует на действия пользователя на рекламном объявлении (такие как "нажатие на кнопку" и т.д.). Реакцию на эти действия необходимо реализовать на стороне интегрирующего приложения:

Подпишитесь на события рекламного объекта через делегат:

inlineAd.delegate = self

Реализуйте протокол:

extension ViewController: InlineAdDelegate {
    func inlineAd(_ ad: InlineAd, didEmit action: InlineAd.Action) {
        switch action {
        case let .onUrlClicked(info, type, url):
            openUrl(url) // открытие ссылки
        case let .onPromocodeCopy(info, promocode):
            applyPromocode(promocode) // применение промокода
        case let .onCustomAction(info, action, data):
            handleCustomAction(action, data: data) // обработка кастомного действия
        }
    }

    func inlineAd(_ ad: InlineAd, didEmit event: InlineAd.Event) {
        // см. секцию «5. Реакция на события показа рекламы»
    }
}
for await action in inlineAd.actions {
    switch action {
    case let .onUrlClicked(info, type, url):
        openUrl(url) // открытие ссылки
    case let .onPromocodeCopy(info, promocode):
        applyPromocode(promocode) // применение промокода
    case let .onCustomAction(info, action, data):
        handleCustomAction(action, data: data) // обработка кастомного действия
    }
}

# Возможные значения InlineAd.Action

Тип значения Параметры Описание
onUrlClicked info — информация о рекламном объявлении
type — тип ссылки
url — ссылка для перехода
Нажатие на кнопку перехода по ссылке
onPromocodeCopy info — информация о рекламном объявлении
promocode — промокод для копирования
Нажатие на кнопку копирования промокода
onCustomAction info — информация о рекламном объявлении
action — идентификатор действия
data — словарь данных
Кастомное действие, заданное в админке

# 5. Реакция на события показа рекламы

При необходимости приложение может отслеживать события показа рекламы. События разделены по типу формата — Banner и Stories:

func inlineAd(_ ad: InlineAd, didEmit event: InlineAd.Event) {
    switch event {
    case let .banner(bannerEvent):
        switch bannerEvent {
        case let .onBlockView(info):
            break // блок баннеров стал видимым
        case let .onCreativeView(info):
            break // баннер стал видимым
        }
    case let .stories(storiesEvent):
        switch storiesEvent {
        case let .onBlockView(info):
            break // блок Stories стал видимым
        case let .onCoverView(info):
            break // обложка стала видимой
        case let .onCreativeView(info):
            break // история открыта
        case let .onSlideView(info):
            break // слайд показан
        case let .onSlideDismissed(info):
            break // плеер закрыт
        }
    }
}
for await event in inlineAd.events {
    switch event {
    case let .banner(bannerEvent):
        switch bannerEvent {
        case let .onBlockView(info):
            break // блок баннеров стал видимым
        case let .onCreativeView(info):
            break // баннер стал видимым
        }
    case let .stories(storiesEvent):
        switch storiesEvent {
        case let .onBlockView(info):
            break // блок Stories стал видимым
        case let .onCoverView(info):
            break // обложка стала видимой
        case let .onCreativeView(info):
            break // история открыта
        case let .onSlideView(info):
            break // слайд показан
        case let .onSlideDismissed(info):
            break // плеер закрыт
        }
    }
}

# События Banner (InlineAd.Event.Banner)

Тип значения Параметры Описание
onBlockView MultiformatInfo Блок баннеров стал видимым на экране
onCreativeView MultiformatInfo Конкретный баннер стал видимым на экране

# События Stories (InlineAd.Event.Stories)

Тип значения Параметры Описание
onBlockView StoryInfo Блок Stories стал видимым на экране
onCoverView StoryInfo Обложка стала видимой на экране
onCreativeView StoryInfo Первое открытие группы в текущей сессии плеера
onSlideView StoryInfo Слайд показан
onSlideDismissed StoryInfo Плеер закрыт пользователем

# Информация о рекламе (MultiformatInfo)

Поле Тип Описание
slot AdSlot Информация о размещении
creativeId String? Идентификатор креатива
format String Название рекламного формата

# 6. Провайдер (InlineAdProvider)

InlineAdProvider упрощает работу с несколькими рекламными слотами — вместо создания множества InlineAdLoader достаточно одного провайдера. Рекомендуется для сценариев с лентой контента и множеством рекламных мест.

# Создание и загрузка

import MadSDK

let provider = InlineAdProvider()
provider.loadingDelegate = self
provider.delegate = self

// Загрузка одного слота
provider.load(
    InlineAdRequest(slot: AdSlot(padId: "123", position: 0))
)

// Загрузка нескольких слотов
provider.load([
    InlineAdRequest(slot: AdSlot(padId: "123", position: 1)),
    InlineAdRequest(slot: AdSlot(padId: "456", position: 0))
])

# Обработка результатов загрузки

extension ViewController: InlineAdProviderLoadingDelegate {
    func inlineAdProvider(
        _ provider: InlineAdProvider,
        didReceive response: InlineAdProvider.Response,
        for slot: AdSlot
    ) {
        switch response {
        case .success(let slot):
            // Реклама загружена — получить view
            if let adView = provider.view(for: slot, in: self) {
                container.addSubview(adView)
            }
        case .failure(let error, let slot):
            // Ошибка загрузки
            break
        case .noContent(let slot):
            // Нет контента
            break
        }
    }
}

# Обработка событий и действий

extension ViewController: InlineAdProviderDelegate {
    func inlineAdProvider(
        _ provider: InlineAdProvider,
        didEmit event: InlineAd.Event,
        for slot: AdSlot
    ) {
        // Обработка событий показа (аналогично секции 5)
    }

    func inlineAdProvider(
        _ provider: InlineAdProvider,
        didEmit action: InlineAd.Action,
        for slot: AdSlot
    ) {
        // Обработка действий пользователя (аналогично секции 4)
    }
}

# Перезагрузка и отмена

// Перезагрузка конкретного слота
provider.reload(
    InlineAdRequest(slot: AdSlot(padId: "123", position: 0))
)

// Перезагрузка всех загруженных слотов
provider.reload()

// Отмена загрузки конкретного слота
provider.cancel(slot: AdSlot(padId: "123", position: 0))

// Отмена всех активных загрузок
provider.cancelAll()

# Возможные состояния (InlineAdProvider.Response)

Тип значения Параметры Описание
success slot — информация о размещении Реклама для слота загружена. Получить view: provider.view(for: slot).
failure error — причина ошибки, slot — информация о размещении Загрузка завершилась ошибкой.
noContent slot — информация о размещении Реклама не была подобрана.

# 7. Пример

Полный пример интеграции InLine рекламы — в репозитории на GitHub.