Нативная реклама
Нативная реклама (Native) — реклама, внешний вид которой может определяться на стороне приложения. Эта особенность позволяет изменять визуальный стиль объявлений и места их размещения с учетом особенностей дизайна приложения.
Примечание
Пример работы всех типов форматов есть в демопроекте.
|
Сущность |
Описание |
|
|
При получении ошибки в |
|
|
В параметрах запроса вы можете указать идентификатор рекламного блока ( |
|
|
Используйте:
|
Пример создания нативной рекламы
Custom Native Ad
Нативная реклама, где UI полностью свой: создается кастомная реализация NativeCustomAdView и задаются внутренние элементы. SDK потом присоединяет к этим элементам компоненты рекламы, клики, трекинг, медиа и т. д.
Как устроено в коде:
-
NativeCustomViewController:
- Создается
NativeAdLoader. - Создается
NativeCustomAdView(кастомный UI). - Загружается реклама через
NativeAdRequestConfiguration(adUnitID:). - SDK связывает объект рекламы с кастомной реализацией View с помощью
try ad.bind(with: adView).
- Создается
-
NativeCustomAdView:
- Создается UILabel/UIImageView/Button и т. п.
- Они соотносятся со свойствами SDK (пример можно увидеть в функции
bindAssets).
import UIKit
import YandexMobileAds
class NativeCustomViewController: UIViewController {
private let adUnitID = "demo-native-video-yandex" // Use R-M-XXXXXX-Y or demo-block (look for the description below)
private lazy var adLoader: NativeAdLoader = {
let loader = NativeAdLoader()
loader.delegate = self
return loader
}()
private let adView: NativeCustomAdView = {
let adView = NativeCustomAdView()
adView.translatesAutoresizingMaskIntoConstraints = false
adView.isHidden = true
return adView
}()
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
loadAd()
}
private func setupUI() {
view.addSubview(adView)
NSLayoutConstraint.activate([
adView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16),
adView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16),
adView.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
}
private func loadAd() {
print("[NativeCustom] Loading ad...")
let configuration = NativeAdRequestConfiguration(adUnitID: adUnitID)
adLoader.loadAd(with: configuration)
}
}
// MARK: - NativeAdLoaderDelegate
extension NativeCustomViewController: NativeAdLoaderDelegate {
func nativeAdLoader(_ loader: NativeAdLoader, didLoad ad: NativeAd) {
print("[NativeCustom] didLoad")
ad.delegate = self
do {
try ad.bind(with: adView)
adView.isHidden = false
} catch {
print("[NativeCustom] Binding error: \(error)")
}
}
func nativeAdLoader(_ loader: NativeAdLoader, didFailLoadingWithError error: Error) {
print("[NativeCustom] didFailLoading: \(error)")
}
}
// MARK: - NativeAdDelegate
extension NativeCustomViewController: NativeAdDelegate {
func nativeAdDidClick(_ ad: NativeAd) {
print("[NativeCustom] didClick")
}
func nativeAdWillLeaveApplication(_ ad: NativeAd) {
print("[NativeCustom] willLeaveApplication")
}
func nativeAd(_ ad: NativeAd, willPresentScreen viewController: UIViewController?) {
print("[NativeCustom] willPresentScreen")
}
func nativeAd(_ ad: NativeAd, didTrackImpressionWith impressionData: ImpressionData?) {
print("[NativeCustom] didTrackImpression: \(impressionData?.rawData ?? "nil")")
}
func nativeAd(_ ad: NativeAd, didDismissScreen viewController: UIViewController?) {
print("[NativeCustom] didDismissScreen")
}
func close(_ ad: NativeAd) {
print("[NativeCustom] close")
}
}
import UIKit
import YandexMobileAds
class NativeCustomAdView: YMANativeAdView {
// Обязательные компоненты (Да)
// Заголовок — обязательный
private let titleLabel_: UILabel = {
let label = UILabel()
label.font = .systemFont(ofSize: 16, weight: .bold)
label.numberOfLines = 2
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
// Домен — обязательный
private let domainLabel_: UILabel = {
let label = UILabel()
label.font = .systemFont(ofSize: 12)
label.textColor = .tertiaryLabel
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
// Предупреждение — обязательный
private let warningLabel_: UILabel = {
let label = UILabel()
label.font = .systemFont(ofSize: 10)
label.textColor = .systemOrange
label.numberOfLines = 0
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
// Рекламная и возрастная метка — обязательный
private let sponsoredLabel_: UILabel = {
let label = UILabel()
label.font = .systemFont(ofSize: 10)
label.textColor = .tertiaryLabel
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
// Значок меню (feedback) — обязательный
private let feedbackButton_: UIButton = {
let button = UIButton(type: .system)
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()
// Кнопка действия — обязательный
private let callToActionButton_: UIButton = {
let button = UIButton(type: .system)
button.backgroundColor = .systemBlue
button.setTitleColor(.white, for: .normal)
button.layer.cornerRadius = 8
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()
// Медиа — обязательный
private let mediaView_: YMANativeMediaView = {
let mediaView = YMANativeMediaView()
mediaView.translatesAutoresizingMaskIntoConstraints = false
return mediaView
}()
// Обязательные для рекламы приложений
// Иконка приложения — обязательный для рекламы приложений
private let iconImageView_: UIImageView = {
let imageView = UIImageView()
imageView.contentMode = .scaleAspectFit
imageView.layer.cornerRadius = 8
imageView.clipsToBounds = true
imageView.translatesAutoresizingMaskIntoConstraints = false
return imageView
}()
// Цена — обязательный для рекламы приложений
private let priceLabel_: UILabel = {
let label = UILabel()
label.font = .systemFont(ofSize: 14, weight: .semibold)
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
// Необязательные компоненты (Нет)
// Фавиконка — необязательный
private let faviconImageView_: UIImageView = {
let imageView = UIImageView()
imageView.contentMode = .scaleAspectFit
imageView.translatesAutoresizingMaskIntoConstraints = false
return imageView
}()
// Количество оценок — необязательный
private let reviewCountLabel_: UILabel = {
let label = UILabel()
label.font = .systemFont(ofSize: 12)
label.textColor = .secondaryLabel
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
// Рейтинг — необязательный
private let ratingView_: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
// Основной текст — необязательный
private let bodyLabel_: UILabel = {
let label = UILabel()
label.font = .systemFont(ofSize: 14)
label.numberOfLines = 3
label.textColor = .secondaryLabel
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupUI()
bindAssets()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setupUI()
bindAssets()
}
private func setupUI() {
backgroundColor = .secondarySystemBackground
layer.cornerRadius = 12
addSubview(iconImageView_)
addSubview(titleLabel_)
addSubview(feedbackButton_)
addSubview(sponsoredLabel_)
addSubview(domainLabel_)
addSubview(bodyLabel_)
addSubview(warningLabel_)
addSubview(mediaView_)
addSubview(faviconImageView_)
addSubview(ratingView_)
addSubview(reviewCountLabel_)
addSubview(priceLabel_)
addSubview(callToActionButton_)
NSLayoutConstraint.activate([
// Иконка (слева сверху)
iconImageView_.topAnchor.constraint(equalTo: topAnchor, constant: 12),
iconImageView_.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 12),
iconImageView_.widthAnchor.constraint(equalToConstant: 50),
iconImageView_.heightAnchor.constraint(equalToConstant: 50),
// Заголовок (справа от иконки)
titleLabel_.topAnchor.constraint(equalTo: topAnchor, constant: 12),
titleLabel_.leadingAnchor.constraint(equalTo: iconImageView_.trailingAnchor, constant: 12),
titleLabel_.trailingAnchor.constraint(equalTo: feedbackButton_.leadingAnchor, constant: -8),
// Feedback кнопка (справа сверху)
feedbackButton_.topAnchor.constraint(equalTo: topAnchor, constant: 12),
feedbackButton_.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -12),
feedbackButton_.widthAnchor.constraint(equalToConstant: 24),
feedbackButton_.heightAnchor.constraint(equalToConstant: 24),
// Рекламная метка (под заголовком)
sponsoredLabel_.topAnchor.constraint(equalTo: titleLabel_.bottomAnchor, constant: 4),
sponsoredLabel_.leadingAnchor.constraint(equalTo: titleLabel_.leadingAnchor),
// Домен (под рекламной меткой)
domainLabel_.topAnchor.constraint(equalTo: sponsoredLabel_.bottomAnchor, constant: 2),
domainLabel_.leadingAnchor.constraint(equalTo: titleLabel_.leadingAnchor),
// Фавиконка (рядом с доменом)
faviconImageView_.centerYAnchor.constraint(equalTo: domainLabel_.centerYAnchor),
faviconImageView_.leadingAnchor.constraint(equalTo: domainLabel_.trailingAnchor, constant: 4),
faviconImageView_.widthAnchor.constraint(equalToConstant: 16),
faviconImageView_.heightAnchor.constraint(equalToConstant: 16),
// Основной текст (под иконкой)
bodyLabel_.topAnchor.constraint(equalTo: iconImageView_.bottomAnchor, constant: 12),
bodyLabel_.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 12),
bodyLabel_.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -12),
// Предупреждение (под основным текстом)
warningLabel_.topAnchor.constraint(equalTo: bodyLabel_.bottomAnchor, constant: 8),
warningLabel_.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 12),
warningLabel_.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -12),
// Медиа (под предупреждением)
mediaView_.topAnchor.constraint(equalTo: warningLabel_.bottomAnchor, constant: 12),
mediaView_.leadingAnchor.constraint(equalTo: leadingAnchor),
mediaView_.trailingAnchor.constraint(equalTo: trailingAnchor),
mediaView_.heightAnchor.constraint(equalTo: mediaView_.widthAnchor, multiplier: 9.0/16.0),
// Рейтинг (под медиа)
ratingView_.topAnchor.constraint(equalTo: mediaView_.bottomAnchor, constant: 12),
ratingView_.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 12),
ratingView_.heightAnchor.constraint(equalToConstant: 16),
ratingView_.widthAnchor.constraint(equalToConstant: 80),
// Количество оценок (рядом с рейтингом)
reviewCountLabel_.centerYAnchor.constraint(equalTo: ratingView_.centerYAnchor),
reviewCountLabel_.leadingAnchor.constraint(equalTo: ratingView_.trailingAnchor, constant: 8),
// Цена (справа)
priceLabel_.centerYAnchor.constraint(equalTo: ratingView_.centerYAnchor),
priceLabel_.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -12),
// Кнопка действия (внизу)
callToActionButton_.topAnchor.constraint(equalTo: ratingView_.bottomAnchor, constant: 12),
callToActionButton_.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 12),
callToActionButton_.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -12),
callToActionButton_.heightAnchor.constraint(equalToConstant: 44),
callToActionButton_.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -12)
])
}
private func bindAssets() {
// Обязательные (Да)
titleLabel = titleLabel_
domainLabel = domainLabel_
warningLabel = warningLabel_
sponsoredLabel = sponsoredLabel_
feedbackButton = feedbackButton_
callToActionButton = callToActionButton_
mediaView = mediaView_
// Обязательные для рекламы приложений
iconImageView = iconImageView_
priceLabel = priceLabel_
// Необязательные (Нет)
faviconImageView = faviconImageView_
reviewCountLabel = reviewCountLabel_
ratingView = ratingView_
bodyLabel = bodyLabel_
}
}
Native Template Ad
Нативная реклама, которую отрисовывает SDK внутри готовой NativeBannerView. После создания NativeAd SDK сам наполняет и показывает рекламу.
NativeTemplateViewController создает:
NativeAdLoader— загрузчик;NativeBannerView— готовый шаблонный UI-контейнер.
import UIKit
import YandexMobileAds
class NativeTemplateViewController: UIViewController {
private let adUnitID = "ad-unit-ID" // Use R-M-XXXXXX-Y or "demo-native-content-yandex" (look for the description below)
private lazy var adLoader: NativeAdLoader = {
let loader = NativeAdLoader()
loader.delegate = self
return loader
}()
private let adView: NativeBannerView = {
let adView = NativeBannerView()
adView.translatesAutoresizingMaskIntoConstraints = false
return adView
}()
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
loadAd()
}
private func setupUI() {
view.addSubview(adView)
NSLayoutConstraint.activate([
adView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10),
adView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -10),
adView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -10)
])
}
private func loadAd() {
print("[NativeTemplate] Loading ad...")
let configuration = NativeAdRequestConfiguration(adUnitID: adUnitID)
adLoader.loadAd(with: configuration)
}
}
// MARK: - NativeAdLoaderDelegate
extension NativeTemplateViewController: NativeAdLoaderDelegate {
func nativeAdLoader(_ loader: NativeAdLoader, didLoad ad: NativeAd) {
print("[NativeTemplate] didLoad")
ad.delegate = self
adView.ad = ad
}
func nativeAdLoader(_ loader: NativeAdLoader, didFailLoadingWithError error: Error) {
print("[NativeTemplate] didFailLoading: \(error)")
}
}
// MARK: - NativeAdDelegate
extension NativeTemplateViewController: NativeAdDelegate {
func nativeAdDidClick(_ ad: NativeAd) {
print("[NativeTemplate] didClick")
}
func nativeAdWillLeaveApplication(_ ad: NativeAd) {
print("[NativeTemplate] willLeaveApplication")
}
func nativeAd(_ ad: NativeAd, willPresentScreen viewController: UIViewController?) {
print("[NativeTemplate] willPresentScreen")
}
func nativeAd(_ ad: NativeAd, didTrackImpressionWith impressionData: ImpressionData?) {
print("[NativeTemplate] didTrackImpression: \(impressionData?.rawData ?? "nil")")
}
func nativeAd(_ ad: NativeAd, didDismissScreen viewController: UIViewController?) {
print("[NativeTemplate] didDismissScreen")
}
func close(_ ad: NativeAd) {
print("[NativeTemplate] close")
}
}
Обязательные компоненты нативной рекламы
|
Компонент в объявлении |
Компонент |
Тип |
Обязательность |
|
Заголовок |
titleLabel |
UILabel |
Да |
|
Домен |
domainLabel |
UILabel |
Да |
|
Предупреждение |
warningLabel |
UILabel |
Да |
|
Рекламная и возрастная метка |
sponsoredLabel |
UILabel |
Да |
|
Значок меню |
feedbackButton |
UIButton |
Да |
|
Кнопка действия |
callToActionButton |
UIButton |
Да |
|
Медиа |
mediaView |
YMANativeMediaView |
Да |
|
Иконка приложения |
iconImageView |
UIImageView |
Да, для рекламы приложений |
|
Цена |
priceLabel |
UILabel |
Да, для рекламы приложений |
|
Фавиконка |
faviconImageView |
UIImageView |
Нет |
|
Количество оценок |
reviewCountLabel |
UILabel |
Нет |
|
Рейтинг |
ratingView |
UIView |
Нет |
|
Основной текст |
bodyLabel |
UILabel |
Нет |