네이티브 광고는 앱의 UI에 자연스럽게 통합되는 광고 포맷입니다. 광고 요소(제목, 이미지, 설명 등)를 앱 디자인에 맞게 자유롭게 커스터마이징할 수 있습니다.
주요 특징
- 앱 UI와 완벽하게 통합 가능한 커스텀 디자인
- 광고 요소 개별 접근 및 배치
- 광고주 프로필 정보 표시 옵션
- 추가 커스텀 필드 지원
구현 방법
네이티브 광고 구현은 다음 단계로 진행됩니다:
- 광고 로드
- 커스텀 뷰 생성
- 뷰 바인딩
- Delegate 처리
1. 광고 로드
AdropNativeAd 인스턴스를 생성하고 광고를 로드합니다.
import AdropAds
class MyViewController: UIViewController {
private var nativeAd: AdropNativeAd?
override func viewDidLoad() {
super.viewDidLoad()
// 네이티브 광고 생성
nativeAd = AdropNativeAd(unitId: "YOUR_NATIVE_UNIT_ID")
nativeAd?.delegate = self
// 광고 로드
nativeAd?.load()
}
}
Context ID 설정
문맥 타겟팅을 위해 Context ID를 설정할 수 있습니다.
// contextId는 읽기 전용 — 초기화 시 설정
let nativeAd = AdropNativeAd(unitId: "YOUR_UNIT_ID", contextId: "article_123")
개발 중에는 테스트 유닛 ID를 사용하세요. 테스트 유닛 ID 섹션을 참고하세요.
2. 커스텀 뷰 생성
스토리보드 또는 코드로 네이티브 광고 뷰를 구성합니다.
UIKit (Storyboard/XIB)
스토리보드에서 AdropNativeAdView를 생성하고 광고 요소를 IBOutlet으로 연결합니다.
import AdropAds
class NativeAdViewCell: UITableViewCell {
@IBOutlet weak var nativeAdView: AdropNativeAdView!
@IBOutlet weak var iconImageView: UIImageView!
@IBOutlet weak var headlineLabel: UILabel!
@IBOutlet weak var bodyLabel: UILabel!
@IBOutlet weak var mediaView: UIView!
@IBOutlet weak var callToActionButton: UIButton!
// 광고주 프로필 (선택사항)
@IBOutlet weak var advertiserLogoImageView: UIImageView!
@IBOutlet weak var advertiserNameLabel: UILabel!
func configure(with ad: AdropNativeAd) {
// 뷰 바인딩 (다음 섹션 참고)
}
}
UIKit (코드)
import AdropAds
class NativeAdView: UIView {
let nativeAdView = AdropNativeAdView()
let iconImageView = UIImageView()
let headlineLabel = UILabel()
let bodyLabel = UILabel()
let mediaView = UIView()
let callToActionButton = UIButton()
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
}
private func setupViews() {
addSubview(nativeAdView)
nativeAdView.addSubview(iconImageView)
nativeAdView.addSubview(headlineLabel)
nativeAdView.addSubview(bodyLabel)
nativeAdView.addSubview(mediaView)
nativeAdView.addSubview(callToActionButton)
// Auto Layout 설정
// ...
}
}
3. 뷰 바인딩
AdropNativeAdView에 광고 요소를 바인딩하여 광고 데이터를 표시합니다.
func configure(with ad: AdropNativeAd) {
// 각 요소를 AdropNativeAdView에 바인딩
nativeAdView.setIconView(iconImageView)
nativeAdView.setHeadLineView(headlineLabel)
nativeAdView.setBodyView(bodyLabel)
nativeAdView.setMediaView(mediaView)
nativeAdView.setCallToActionView(callToActionButton)
// 광고주 프로필 (선택사항)
if let advertiserLogoView = advertiserLogoImageView,
let advertiserNameView = advertiserNameLabel {
nativeAdView.setProfileLogoView(advertiserLogoView)
nativeAdView.setProfileNameView(advertiserNameView)
}
// 광고 데이터 설정 (자동으로 바인딩된 뷰에 표시됨)
nativeAdView.setNativeAd(ad)
}
바인딩 메서드
| 메서드 | 설명 | 필수 |
|---|
setIconView(_:onClick:) | 아이콘 이미지 뷰 설정. onClick: ((AdropNativeAd?, UIView) -> Void)? = nil | 선택 |
setHeadLineView(_:onClick:) | 제목 레이블 설정. onClick: ((AdropNativeAd?, UIView) -> Void)? = nil | 선택 |
setBodyView(_:) | 설명 레이블 설정 | 선택 |
setMediaView(_:) | 메인 이미지/비디오 뷰 설정 | 선택 |
setCallToActionView(_:onClick:) | CTA 버튼 설정. onClick: ((AdropNativeAd?, UIView) -> Void)? = nil | 선택 |
setAdvertiserView(_:onClick:) | 광고주 뷰 설정. onClick: ((AdropNativeAd?, UIView) -> Void)? = nil | 선택 |
setProfileLogoView(_:onClick:) | 광고주 로고 이미지 뷰 설정. onClick: ((AdropNativeAd?, UIView) -> Void)? = nil | 선택 |
setProfileNameView(_:onClick:) | 광고주 이름 레이블 설정. onClick: ((AdropNativeAd?, UIView) -> Void)? = nil | 선택 |
setNativeAd(_:) | 광고 데이터 설정 | 필수 |
onClick 클로저는 사용자가 바인딩된 뷰를 탭할 때 호출됩니다. 현재 AdropNativeAd? 인스턴스와 탭된 UIView를 파라미터로 받습니다. 제공하지 않으면 기본 클릭 동작(목적지 URL 열기)이 사용됩니다.
광고주 프로필을 표시하려면 애드컨트롤 콘솔에서 해당 광고 유닛의 광고주 프로필 표시를 활성화해야 합니다.
4. Delegate 처리
AdropNativeAdDelegate를 구현하여 광고 이벤트를 처리합니다.
extension MyViewController: AdropNativeAdDelegate {
// 광고 수신 성공
func onAdReceived(_ nativeAd: AdropNativeAd) {
print("네이티브 광고 수신 성공")
// 광고 데이터에 접근
print("제목: \(nativeAd.headline)")
print("설명: \(nativeAd.body)")
print("CTA: \(nativeAd.callToAction)")
// 뷰에 광고 바인딩
configureNativeAdView(with: nativeAd)
}
// 광고 수신 실패
func onAdFailedToReceive(_ nativeAd: AdropNativeAd, _ errorCode: AdropErrorCode) {
print("네이티브 광고 수신 실패: \(errorCode)")
}
// 광고 클릭 (선택사항)
func onAdClicked(_ nativeAd: AdropNativeAd) {
print("네이티브 광고 클릭")
}
// 광고 노출 (선택사항)
func onAdImpression(_ nativeAd: AdropNativeAd) {
print("네이티브 광고 노출")
}
}
Delegate 메서드
| 메서드 | 필수 | 설명 |
|---|
onAdReceived(_:) | 필수 | 광고 로드 성공 시 호출 |
onAdFailedToReceive(_:_:) | 필수 | 광고 로드 실패 시 호출 |
onAdClicked(_:) | 선택 | 사용자가 광고를 클릭했을 때 호출 |
onAdImpression(_:) | 선택 | 광고가 노출되었을 때 호출 |
클로저 콜백
Delegate 대신 클로저 기반 콜백을 사용할 수 있습니다.
let nativeAd = AdropNativeAd(unitId: "YOUR_UNIT_ID")
nativeAd.onAdReceived = { ad in
print("네이티브 광고 수신 성공")
}
nativeAd.onAdFailedToReceive = { ad, errorCode in
print("네이티브 광고 수신 실패: \(errorCode)")
}
nativeAd.onAdImpression = { ad in
print("네이티브 광고 노출")
}
nativeAd.onAdClicked = { ad in
print("네이티브 광고 클릭")
}
Delegate와 클로저를 동시에 설정하면 두 가지 모두 호출됩니다.
광고 속성
AdropNativeAd 객체를 통해 광고 데이터에 접근할 수 있습니다.
기본 속성
// 광고 수신 성공 시
func onAdReceived(_ nativeAd: AdropNativeAd) {
// 제목
print("제목: \(nativeAd.headline)")
// 설명
print("설명: \(nativeAd.body)")
// CTA 버튼 텍스트
print("CTA: \(nativeAd.callToAction)")
// 메인 이미지/비디오
print("미디어 URL: \(nativeAd.asset)")
}
광고주 프로필
// 광고주 정보 (profile 및 하위 프로퍼티는 non-optional)
let profile = nativeAd.profile
print("광고주 로고: \(profile.displayLogo)")
print("광고주 이름: \(profile.displayName)")
// 프로필 링크 (선택사항 — 광고주 페이지 링크)
if let link = profile.link {
print("프로필 링크: \(link)")
}
커스텀 필드
애드컨트롤 콘솔에서 설정한 추가 텍스트 항목에 접근할 수 있습니다.
// 추가 텍스트 항목 (extra는 non-optional [String: String])
let extra = nativeAd.extra
if !extra.isEmpty {
// 예: 가격 정보
if let price = extra["price"] {
print("가격: \(price)")
}
// 예: 할인율
if let discount = extra["discount"] {
print("할인율: \(discount)")
}
// 예: 평점
if let rating = extra["rating"] {
print("평점: \(rating)")
}
}
extra 필드는 애드컨트롤 콘솔의 광고 유닛 설정에서 정의한 추가 텍스트 항목 ID를 키로 사용합니다.
속성 목록
| 속성 | 타입 | 설명 |
|---|
unitId | String | 광고 유닛 ID |
contextId | String | 문맥 타겟팅용 ID |
headline | String | 광고 제목 |
body | String | 광고 설명 |
callToAction | String | CTA 버튼 텍스트 |
icon | String | 아이콘 이미지 URL |
cover | String | 커버 이미지 URL |
asset | String | 메인 이미지/비디오 URL |
creative | String | 크리에이티브 HTML 콘텐츠 |
creativeSize | CGSize | 크리에이티브 콘텐츠 사이즈 |
advertiser | String | 광고주 이름 |
advertiserURL | String | 광고주 URL |
profile | AdropNativeAdProfile | 광고주 프로필 정보 |
extra | [String: String] | 추가 커스텀 필드 |
accountTag | [String: Any] | 계정 레벨 태그 데이터 |
creativeTag | [String: Any] | 크리에이티브 레벨 태그 데이터 |
destinationURL | String? | 광고 목적지 URL |
txId | String | 트랜잭션 ID |
campaignId | String | 캠페인 ID |
creativeId | String | 크리에이티브 ID |
browserTarget | BrowserTarget? | 광고 클릭 시 URL 열기 방식 |
isLoaded | Bool | 광고 로드 여부 |
isBackfilled | Bool | 백필 광고 여부 |
AdropNativeAdProfile
| 속성 | 타입 | 설명 |
|---|
displayLogo | String | 광고주 로고 이미지 URL |
displayName | String | 광고주 표시 이름 |
link | String? | 광고주 페이지 링크 |
커스텀 클릭
커스텀 클릭을 사용하면 기본 동작(목적지 URL 열기) 대신 광고 클릭 동작을 직접 처리할 수 있습니다.
let nativeAd = AdropNativeAd(unitId: "YOUR_UNIT_ID")
nativeAd.useCustomClick = true
전체 클릭 영역
setIsEntireClick(_:)을 사용하여 AdropNativeAdView 전체를 클릭 가능하게 만듭니다.
nativeAdView.setIsEntireClick(true)
useCustomClick이 true인 경우, setNativeAd(_:)에서 setIsEntireClick(true)가 자동으로 호출됩니다.
수동 클릭
performClick()을 사용하여 수동으로 클릭 이벤트를 트리거합니다.
nativeAdView.performClick()
URL 열기
open(_:useInAppBrowser:)를 사용하여 프로그래밍 방식으로 URL을 엽니다.
// 목적지 URL 열기
nativeAd.open(nativeAd.destinationURL)
// 인앱 브라우저로 열기
nativeAd.open(nativeAd.destinationURL, useInAppBrowser: true)
모범 사례
에러 처리
광고 로드 실패 시 대체 UI를 표시하여 사용자 경험을 유지하세요.
func onAdFailedToReceive(_ nativeAd: AdropNativeAd, _ errorCode: AdropErrorCode) {
print("네이티브 광고 수신 실패: \(errorCode)")
// 광고 영역 숨기기
nativeAdContainerView.isHidden = true
// 또는 대체 콘텐츠 표시
showFallbackContent()
}
테스트 유닛 ID
개발 및 테스트 시 다음 테스트 유닛 ID를 사용하세요.
| 광고 타입 | 테스트 유닛 ID |
|---|
| 네이티브 (이미지) | PUBLIC_TEST_UNIT_ID_NATIVE |
| 네이티브 비디오 (16:9) | PUBLIC_TEST_UNIT_ID_NATIVE_VIDEO_16_9 |
| 네이티브 비디오 (9:16) | PUBLIC_TEST_UNIT_ID_NATIVE_VIDEO_9_16 |
// 테스트 광고 로드
nativeAd = AdropNativeAd(unitId: AdropUnitId.PUBLIC_TEST_UNIT_ID_NATIVE)
실제 배포 시에는 반드시 애드컨트롤 콘솔에서 생성한 실제 유닛 ID를 사용하세요.
백필 광고
백필 광고가 활성화된 경우, 직광고가 없을 때 자동으로 백필 광고가 로드됩니다. isBackfilled 프로퍼티로 백필 광고 여부를 확인할 수 있습니다.
class ViewController: UIViewController, AdropNativeAdDelegate {
private var nativeAd: AdropNativeAd?
func onAdReceived(_ nativeAd: AdropNativeAd) {
if nativeAd.isBackfilled {
print("백필 광고가 로드되었습니다")
} else {
print("직광고가 로드되었습니다")
}
}
func onAdFailedToReceive(_ nativeAd: AdropNativeAd, _ errorCode: AdropErrorCode) {
switch errorCode {
case .ERROR_CODE_AD_NO_FILL:
print("직광고 없음, 백필 광고 요청 중...")
case .ERROR_CODE_AD_BACKFILL_NO_FILL:
print("백필 광고도 없습니다")
// 광고 영역 숨김 처리
default:
print("광고 로드 실패: \(errorCode)")
}
}
}
백필 광고를 사용하려면 AdropAds-Backfill 의존성을 추가해야 합니다. 시작하기를 참고하세요.
관련 문서