# 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 Не удалось загрузить рекламу
requestTimeout Превышен таймаут загрузки рекламы (см. adRequestTimeoutMillis)
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.