Skip to main content

네이티브 광고 형태 소개

  • 광고 뷰를 미디에이션 SDK가 구현해주는 타 광고 형태와 달리 네이티브 광고 형태는 구성 요소들을 전달받아 앱에서 직접 광고 뷰를 구현합니다.
  • UI/UX 기반으로 레이아웃을 직접 구현하므로써 위화감을 적게 만들 수 있다는 것이 가장 큰 특징입니다. 단, 유저가 광고가 아닌 컨텐츠로써 착각하는 경우를 방지하기 위해 광고 표시와 함께 최소한의 차별성은 부여해야합니다.
네이티브 광고 예시

광고 단위 설정

대시보드에서 발급받은 ad unit ID를 사용하여 광고 단위를 설정하세요.
let adUnit = DaroAdUnit(unitId: "your_native_unit_id")

네이티브 광고 구현

기본 구현

DaroAdNativeView를 상속하는 뷰를 구현합니다. 아래는 샘플코드입니다.

final class DaroLargeNativeAdContentView: DaroAdNativeView {
    override init(unit: DaroAdUnit) {
        super.init(unit: unit)
        layout()
    }

    @available(*, unavailable)
    public required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    var containerView = UIView()

    var iconImageView: UIImageView = {
        let view = UIImageView()
        view.contentMode = .scaleAspectFill
        view.layer.cornerRadius = 4
        view.clipsToBounds = true
        view.isHidden = false
        return view
    }()

    var titleLabel: UILabel = {
        let label = UILabel()
        label.isUserInteractionEnabled = false
        label.clipsToBounds = true
        label.font = .systemFont(ofSize: 15, weight: .bold)
        label.textColor = UIColor.white
        label.numberOfLines = 2
        return label
    }()

    var advertiserLabel: UILabel = {
        let label = UILabel()
        label.isUserInteractionEnabled = false
        label.clipsToBounds = true
        label.font = .systemFont(ofSize: 12, weight: .regular)
        label.numberOfLines = 2
        label.textColor = UIColor.white
        return label
    }()

    /// Media View
    let mediaContentView: UIView = UIView()

    /// Call to Action
    var callToActionButton: UIButton = {
        let button = UIButton()
        button.translatesAutoresizingMaskIntoConstraints = false
        button.clipsToBounds = true
        button.titleLabel?.font = .systemFont(ofSize: 20, weight: .bold)
        button.setTitleColor(.label, for: .normal)
        button.backgroundColor = UIColor.systemGray3
        button.layer.cornerRadius = 4
        return button
    }()

    /// Body
    var bodyLabel: UILabel = {
        let label = UILabel()
        label.isUserInteractionEnabled = false
        label.clipsToBounds = true
        label.font = .systemFont(ofSize: 15, weight: .regular)
        label.numberOfLines = 2
        label.textColor = UIColor.white
        return label
    }()

    private func layout() {
        translatesAutoresizingMaskIntoConstraints = false
        let blurEffect = UIBlurEffect(style: .systemMaterialDark)
        let blurView = UIVisualEffectView(effect: blurEffect)
        blurView.translatesAutoresizingMaskIntoConstraints = false
        blurView.isUserInteractionEnabled = false
        containerView.addSubview(blurView)
        NSLayoutConstraint.activate([
            blurView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
            blurView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
            blurView.topAnchor.constraint(equalTo: containerView.topAnchor),
            blurView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor),
        ])
        containerView.clipsToBounds = true

        addSubview(containerView)
        containerView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            containerView.leadingAnchor.constraint(equalTo: leadingAnchor),
            containerView.trailingAnchor.constraint(equalTo: trailingAnchor),
            containerView.topAnchor.constraint(equalTo: topAnchor),
            containerView.bottomAnchor.constraint(equalTo: bottomAnchor),
        ])

        [
            mediaContentView,
            iconImageView,
            titleLabel,
            advertiserLabel,
            bodyLabel,
            callToActionButton,
        ]
        .forEach {
            containerView.addSubview($0)
            $0.translatesAutoresizingMaskIntoConstraints = false
        }

        activateLayout()
    }

    func activateLayout() {
        NSLayoutConstraint.activate([
            iconImageView.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 10),
            iconImageView.leftAnchor.constraint(equalTo: containerView.leftAnchor, constant: 10),
            iconImageView.heightAnchor.constraint(equalToConstant: 70),
            iconImageView.widthAnchor.constraint(equalToConstant: 70),

            titleLabel.topAnchor.constraint(equalTo: iconImageView.topAnchor),
            titleLabel.leftAnchor.constraint(equalTo: iconImageView.rightAnchor, constant: 10),
            titleLabel.rightAnchor.constraint(equalTo: containerView.rightAnchor, constant: -10),

            advertiserLabel.bottomAnchor.constraint(equalTo: iconImageView.bottomAnchor),
            advertiserLabel.leftAnchor.constraint(equalTo: iconImageView.rightAnchor, constant: 10),

            bodyLabel.topAnchor.constraint(equalTo: iconImageView.bottomAnchor, constant: 10),
            bodyLabel.leftAnchor.constraint(equalTo: containerView.leftAnchor, constant: 10),
            bodyLabel.rightAnchor.constraint(equalTo: containerView.rightAnchor, constant: -10),

            mediaContentView.topAnchor.constraint(equalTo: bodyLabel.bottomAnchor, constant: 10),
            mediaContentView.widthAnchor.constraint(equalTo: containerView.widthAnchor),
            mediaContentView.heightAnchor.constraint(equalTo: containerView.widthAnchor),
            mediaContentView.centerYAnchor.constraint(equalTo: containerView.centerYAnchor),
            mediaContentView.centerXAnchor.constraint(equalTo: containerView.centerXAnchor),

            callToActionButton.topAnchor.constraint(equalTo: mediaContentView.bottomAnchor, constant: 10),
            callToActionButton.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -10),
            callToActionButton.leftAnchor.constraint(equalTo: containerView.leftAnchor, constant: 20),
            callToActionButton.rightAnchor.constraint(equalTo: containerView.rightAnchor, constant: -20),
        ])

        bindViews(
            titleLabel: titleLabel,
            advertiserLabel: advertiserLabel,
            bodyLabel: bodyLabel,
            iconImageView: iconImageView,
            mediaContentView: mediaContentView,
            callToActionButton: callToActionButton
        )
    }
}

네이티브 광고 사용 예제

네이티브 광고를 사용하는 예시입니다.

기본 사용법

class ExampleViewController: UIViewController {
    private var nativeAdView: DaroLargeNativeAdContentView?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupNativeAd()
    }
    
    private func setupNativeAd() {
        let adUnit = DaroAdUnit(unitId: "your_native_unit_id")
        nativeAdView = DaroLargeNativeAdContentView(unit: adUnit)
        
        guard let nativeAdView = nativeAdView else { return }
        
        nativeAdView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(nativeAdView)
        
        NSLayoutConstraint.activate([
            nativeAdView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            nativeAdView.widthAnchor.constraint(equalToConstant: 300),
            nativeAdView.heightAnchor.constraint(equalToConstant: 500),
            nativeAdView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20)
        ])
        
        nativeAdView.listener.onAdClicked = { adInfo in
            print("[DARO] Listener Native Ad clicked: \(adInfo)")
        }
        nativeAdView.listener.onAdImpression = { adInfo in
            print("[DARO] Listener Native Ad impression: \(adInfo)")
        }
        nativeAdView.listener.onAdLoadSuccess = { ad, adInfo in
            print("[DARO] Listener Native Ad loaded: \(ad) \(adInfo)")
        }
        nativeAdView.listener.onAdLoadFail = { error in
            print("[DARO] Listener Native Ad failed: \(error)")
        }
        
        nativeAdView.loadAd()
    }
}
Note: 네이티브 광고는 생성 시 자동으로 초기 광고를 로드합니다.

수동 초기 로드 설정

광고의 초기 로드 시점을 직접 제어하려면 autoLoad 파라미터를 사용할 수 있습니다.
// 네이티브 광고 - 수동 초기 로드 모드
let nativeAdView = DaroLargeNativeAdContentView(
    unit: adUnit,
    autoLoad: false  // 자동 초기 로드 비활성화
)

// 원하는 시점에 초기 광고 로드
nativeAdView.loadAd()
autoLoad 파라미터
  • true (기본값): 뷰 생성 시 자동으로 초기 광고 로드
  • false: 수동으로 loadAd() 호출 시 초기 광고 로드
수동 초기 로드는 다음과 같은 경우에 유용합니다:
  • 특정 사용자 액션 후에 광고를 표시하고 싶을 때
  • 화면 전환 시 광고 로드 타이밍을 제어하고 싶을 때
  • 네트워크 상태를 확인한 후 광고를 로드하고 싶을 때
참고: 로드 이후 광고 새로고침은 SDK가 자동으로 관리합니다.

네이티브 템플릿

DARO SDK는 기본적인 네이티브 광고 템플릿을 제공합니다. 이를 통해 커스텀 뷰를 구현하지 않고도 네이티브 광고를 쉽게 구현할 수 있습니다.

라인 배너 템플릿

DaroAdLineBannerView는 가로 형태의 네이티브 광고 템플릿입니다. 다음과 같은 특징을 가집니다:
  • 아이콘, 제목, 광고주 정보를 포함한 기본적인 레이아웃
  • 광고 마크 표시
라인 배너 템플릿 광고 예시
class ExampleViewController: UIViewController {
    private var lineBannerView: DaroAdLineBannerView?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupLineBannerAd()
    }
    
    private func setupLineBannerAd() {
        let adUnit = DaroAdUnit(unitId: "your_native_unit_id")
        lineBannerView = DaroAdLineBannerView(unit: adUnit)
        
        guard let lineBannerView = lineBannerView else { return }
        
        lineBannerView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(lineBannerView)
        
        NSLayoutConstraint.activate([
            lineBannerView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            lineBannerView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            lineBannerView.heightAnchor.constraint(equalToConstant: 36),
            lineBannerView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
        ])
        
        lineBannerView.listener.onAdClicked = { adInfo in
            print("[DARO] Listener Line Banner Ad clicked: \(adInfo)")
        }
        lineBannerView.listener.onAdImpression = { adInfo in
            print("[DARO] Listener Line Banner Ad impression: \(adInfo)")
        }
        lineBannerView.listener.onAdLoadSuccess = { ad, adInfo in
            print("[DARO] Listener Line Banner Ad loaded: \(ad) \(adInfo)")
        }
        lineBannerView.listener.onAdLoadFail = { error in
            print("[DARO] Listener Line Banner Ad failed: \(error)")
        }
        
        lineBannerView.loadAd()
    }
}
Note: 라인 배너 템플릿도 생성 시 자동으로 초기 광고를 로드합니다.

수동 초기 로드 설정

라인 배너 템플릿도 autoLoad 파라미터를 지원합니다:
// 라인 배너 - 수동 초기 로드 모드
let lineBannerView = DaroAdLineBannerView(
    unit: adUnit,
    autoLoad: false  // 자동 초기 로드 비활성화
)

// 원하는 시점에 초기 광고 로드
lineBannerView.loadAd()
템플릿을 사용하면 광고 뷰의 레이아웃을 직접 구현할 필요 없이, SDK에서 제공하는 기본 레이아웃을 사용할 수 있습니다. 필요한 경우 템플릿의 스타일을 커스터마이징할 수 있습니다.

템플릿 설정

DaroLineNativeAdConfiguration을 통해 템플릿의 스타일을 커스터마이징할 수 있습니다
let configuration = DaroLineNativeAdConfiguration()
configuration.backgroundColor = // 배경색
configuration.adMarkTextColor = // 광고 마크 텍스트 색상
configuration.adMarkBackgroundColor = // 광고 마크 배경색
configuration.titleTextColor = // 제목 텍스트 색상
configuration.ctaTextColor = // CTA 버튼 텍스트 색상
configuration.ctaBackgroundColor = // CTA 버튼 배경색

lineBannerView.configuration = configuration
I