Native Ad
Last updated
Was this helpful?
Last updated
Was this helpful?
를 프로젝트에 추가합니다.
Native Ad용으로 발급받은 Ad Unit ID를 사용합니다.
광고를 요청하기 전에 를 먼저 진행합니다.
SDK 초기화는 앱 실행 시 한 번만 호출하여 주시고, 광고 요청은 초기화가 완료된 후에 이뤄져야 합니다.
iOS 14 이상 지원하는 경우, 권한 요청 완료 후 광고를 요청해주세요.
Native Ad의 경우, 광고에 사용 될 레이아웃을 직접 구성해야 합니다. 필수 구성 요소들은 다음과 같습니다.
Title : UILabel
Main Text : UILabel
Call-To-Action : UIButton
Icon Image : UIImageView
Main Image : UIImageView
Privacy Icon : UIImageView
Ad Tag : UIView (UILabel 또는 UIImageView)
Ad Tag 요소는 "Ad" 또는 "Advertisement" 문자열을 보여주는 UI 구성 요소를 포함하여, 광고라는 것을 명확하게 사용자에게 인식을 시켜야 합니다. 이 요소가 포함되지 않으면, 일부 광고 네트워크의 광고 송출이 중단될 수 있습니다.
2.1.0 버전부터 Native Ad의 CTA (Call-To-Action)가 UILabel
에서 UIButton
으로 변경
되었습니다.
이 요소들은 반드시 포함하여 구성하여 주시고, 광고 컨텐츠를 덮는 View가 없어야 합니다. 또한 텍스트 변경, 이미지 변경, 터치 시 액션 변경 등 광고 컨텐츠에 관련된 부분을 가공하거나 변경하지 않도록 주의 부탁드립니다.
// NativeAdView.h
#import <ADXLibrary/ADXNativeAdRendering.h>
@interface NativeAdView : UIView <ADXNativeAdRendering>
@property (nonatomic, weak) IBOutlet UILabel *titleLabel;
@property (nonatomic, weak) IBOutlet UILabel *mainTextLabel;
@property (nonatomic, weak) IBOutlet UIButton *callToActionButton;
@property (nonatomic, weak) IBOutlet UIImageView *iconImageView;
@property (nonatomic, weak) IBOutlet UIImageView *mainImageView;
@property (nonatomic, weak) IBOutlet UIImageView *privacyInformationIconImageView;
@end
// NativeAdView.m
@implementation NativeAdView
- (void)layoutSubviews {
[super layoutSubviews];
}
- (UILabel *)nativeMainTextLabel {
return self.mainTextLabel;
}
- (UILabel *)nativeTitleTextLabel {
return self.titleLabel;
}
- (UIButton *)nativeCallToActionButton {
return self.callToActionButton;
}
- (UILabel *)nativeSponsoredByCompanyTextLabel {
return self.sponsoredByLabel;
}
- (UIImageView *)nativeIconImageView {
return self.iconImageView;
}
- (UIImageView *)nativeMainImageView {
return self.mainImageView;
}
- (UIImageView *)nativePrivacyInformationIconImageView {
return self.privacyInformationIconImageView;
}
@end
import UIKit
import ADXLibrary
class NativeAdView: UIView {
@IBOutlet var contentsView: UIView!
@IBOutlet var titleLabel: UILabel!
@IBOutlet var mainTextLabel: UILabel!
@IBOutlet var callToActionButton: UIButton!
@IBOutlet var iconImageView: UIImageView!
@IBOutlet var privacyInformationIconImageView: UIImageView!
@IBOutlet var mainImageView: UIImageView!
convenience init() {
self.init(frame: .zero)
initView()
}
override init(frame: CGRect) {
super.init(frame: frame)
initView()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
initView()
}
func initView() {
Bundle.main.loadNibNamed("NativeAdView", owner: self, options: nil)
addSubview(contentsView)
contentsView.frame = self.bounds
contentsView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
}
}
extension NativeAdView: ADXNativeAdRendering {
func nativeMainTextLabel() -> UILabel {
return self.mainTextLabel
}
func nativeTitleTextLabel() -> UILabel {
return self.titleLabel
}
func nativeCallToActionButton() -> UIButton {
return self.callToActionButton
}
func nativeIconImageView() -> UIImageView {
return self.iconImageView
}
func nativeMainImageView() -> UIImageView {
return self.mainImageView
}
func nativePrivacyInformationIconImageView() -> UIImageView {
return self.privacyInformationIconImageView
}
}
Native Ad는 다음 2가지 방법 중 하나로 광고를 로드할 수 있습니다.
ADXNativeAdFactory
의 setRenderingViewClass:renderingViewClass:
메서드를 사용하여 RenderingViewClass
를 구성합니다.
ADXNativeAdFactoryDelegate
callback을 등록합니다.
ADXNativeAdFactoryDelegate
의 loadAd
를 호출하여 광고를 로드합니다.
광고 로드가 완료되면 ADXNativeAdFactoryDelegate
의 onSuccess:nativeAd:
가 호출됩니다.
#import "NativeAdViewController"
#import "NativeAdView.h"
#import <ADXLibrary/ADXNativeAdFactory.h>
@interface NativeAdViewController () <ADXNativeAdFactoryDelegate, ADXNativeAdDelegate>
@property (strong) ADXNativeAd *nativeAd;
@end
@implementation NativeAdViewController
- (void)viewDidLoad {
[super viewDidLoad];
[[ADXNativeAdFactory sharedInstance]
setRenderingViewClass:@"<ADX_NATIVE_AD_UNIT_ID>"
renderingViewClass:[NativeAdView class]];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[ADXNativeAdFactory sharedInstance] addDelegate:self];
[[ADXNativeAdFactory sharedInstance] loadAd:@"<ADX_NATIVE_AD_UNIT_ID>"];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[ADXNativeAdFactory sharedInstance] removeDelegate:self];
}
#pragma mark - ADXNativeAdFactoryDelegate
- (void)onSuccess:(NSString *)adUnitId nativeAd:(ADXNativeAd *)nativeAd {
NSLog(@"onSuccess : %@", adUnitId);
if([adUnitId isEqualToString:ADX_NATIVE_AD_UNIT_ID]) {
self.nativeAd = nativeAd;
self.nativeAd.delegate = self;
UIView *nativeAdView = [[ADXNativeAdFactory sharedInstance]
getNativeAdView:@"<ADX_NATIVE_AD_UNIT_ID>"];
nativeAdView.frame = CGRectMake(0.0,
100.0,
320.0,
300.0);
[self.view addSubview:nativeAdView];
}
}
- (void)onFailure:(NSString *)adUnitId {
NSLog(@"onFailure : %@", adUnitId);
}
#pragma mark - ADXNativeAdDelegate
- (UIViewController *)viewControllerForPresentingModalView {
return self;
}
@end
import UIKit
import ADXLibrary
class NativeAdViewController: UIViewController {
var nativeAd: ADXNativeAd?
override func viewDidLoad() {
super.viewDidLoad()
ADXNativeAdFactory.sharedInstance().setRenderingViewClass(
"<ADX_NATIVE_AD_UNIT_ID>",
renderingViewClass: NativeAdView.self)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
ADXNativeAdFactory.sharedInstance().add(self)
ADXNativeAdFactory.sharedInstance().loadAd("<ADX_NATIVE_AD_UNIT_ID>")
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
ADXNativeAdFactory.sharedInstance().remove(self)
}
}
extension NativeAdViewController: ADXNativeAdFactoryDelegate, ADXNativeAdDelegate {
// MARK: - ADXNativeAdFactoryDelegate
public func onSuccess(_ adUnitId: String!, nativeAd: ADXNativeAd!) {
if (adUnitId == ADX_NATIVE_AD_UNIT_ID) {
self.nativeAd = nativeAd
self.nativeAd?.delegate = self
let nativeAdView = ADXNativeAdFactory.sharedInstance()
.getNativeAdView("<ADX_NATIVE_AD_UNIT_ID>")
nativeAdView?.frame = CGRect(
x: (UIScreen.main.bounds.width - 300.0)/2,
y: 100.0,
width: 300.0,
height: 270.0)
self.view.addSubview(nativeAdView!)
} else {
print("fail to load")
}
}
public func onFailure(_ adUnitId: String!) {
print("onFailure :", adUnitId!)
}
// MARK: - ADXNativeAdDelegate
func viewControllerForPresentingModalView() -> UIViewController {
return self
}
}
ADXNativeAdFactory
의 setRenderingViewClass:renderingViewClass:
메서드를 사용하여 RenderingViewClass
를 구성합니다.
로드할 광고의 크기를 설정합니다.
광고의 크기는 xib파일에서 사이즈를 지정하시거나 frame으로 세팅해주셔야 합니다.
ADXAdPositioning
을 이용하여 고정 및 반복 위치를 지정합니다.
addFixedIndexPath
: 고정할 광고 위치
enableRepeatingPositionsWithInterval
: 광고 반복 위치
loadAdsForAdUnitID:
를 호출하여 광고를 로드합니다.
#import "NativeAdPlacerViewController.h"
#import "NativeAdView.h"
#import <ADXLibrary/ADXNativeAdFactory.h>
@interface NativeAdPlacerViewController () <UICollectionViewDataSource, UICollectionViewDelegate, ADXCollectionViewAdPlacerDelegate>
@property (weak) IBOutlet UICollectionView *colltionView;
@property (strong) ADXCollectionViewAdPlacer *placer;
@end
@implementation NativeAdPlacerViewController
- (void)viewDidLoad {
[super viewDidLoad];
[[ADXNativeAdFactory sharedInstance]
setRenderingViewClass:@"<ADX_NATIVE_AD_UNIT_ID>"
renderingViewClass:[NativeAdView class]];
// 광고 고정 및 반복 위치 지정
ADXAdPositioning *adPositioning = [ADXAdPositioning positioning];
[adPositioning addFixedIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
[adPositioning enableRepeatingPositionsWithInterval:3];
self.placer = [[ADXNativeAdFactory sharedInstance]
getCollectionViewAdPlacer:@"<ADX_NATIVE_AD_UNIT_ID>"
collectionView:self.colltionView
viewController:self
adPositioning:adPositioning];
[self.placer loadAdsForAdUnitID:@"<ADX_NATIVE_AD_UNIT_ID>"];
}
import UIKit
import ADXLibrary
class NativeAdPlacerViewController: UIViewController {
@IBOutlet var collectionView: UICollectionView!
var placer : ADXCollectionViewAdPlacer!
override func viewDidLoad() {
super.viewDidLoad()
ADXNativeAdFactory.sharedInstance().setRenderingViewClass(
"<ADX_NATIVE_AD_UNIT_ID>",
renderingViewClass: NativeAdView.self)
let adPositioning = ADXAdPositioning()
adPositioning.addFixedIndexPath(IndexPath(row: 0, section: 0))
adPositioning.enableRepeatingPositions(withInterval: 3)
self.placer = ADXNativeAdFactory.sharedInstance()
.getCollectionViewAdPlacer(
"<ADX_NATIVE_AD_UNIT_ID>",
collectionView: collectionView,
viewController: self,
adPositioning: adPositioning
)
self.placer.loadAds(forAdUnitID: "<ADX_NATIVE_AD_UNIT_ID>")
}
}
extension NativeAdPlacerViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 60;
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell : UICollectionViewCell = collectionView.adx_dequeueReusableCell(withReuseIdentifier: "CustomCell", for: indexPath) as! UICollectionViewCell
return cell
}
}
Cell의 position 정보가 달라지기 때문에, UITableView
는 ADXTableViewAdPlacer.h
, UICollectionView
는 ADXCollectionViewAdPlacer.h
파일을 참고하시어 대체 메서드를 사용해주시기 바랍니다.
광고 노출에 대한 예상 광고 수익을 확인할 수 있습니다.
이 기능은 iOS ADX SDK 2.6.2 이상 버전을 사용하시는 것이 권장됩니다.
아래 예제와 같이' paidEventHandler
' 를 사용하여 예상되는 eCPM 값을 확인할 수 있습니다.
'ADXCollectionViewAdPlacer' 및 'ADXTableViewAdPlacer' 를 사용하는 경우, 이 기능은 지원되지 않습니다.
미디에이션 설정 과정에서 수동적으로 설정한 값과 정확한 값이 섞여 있어서 예상 값으로 사용하시는 것을 권장드립니다.
eCPM의 통화(Currency) 단위는 USD입니다.
#import <UIKit/UIKit.h>
#import <ADXLibrary/ADXNativeAdFactory.h>
#import "NativeAdViewController.h"
#import "NativeAdView.h"
#import <FirebaseAnalytics/FirebaseAnalytics.h>
#import <AppsFlyerAdRevenue/AppsFlyerAdRevenue.h>
@interface NativeAdViewController () <ADXNativeAdFactoryDelegate, ADXNativeAdDelegate>
@property (nonatomic, strong) ADXNativeAd *nativeAd;
@end
@implementation NativeAdViewController
- (void)viewDidLoad {
[super viewDidLoad];
[[ADXNativeAdFactory sharedInstance]
setRenderingViewClass:@"<ADX_NATIVE_AD_UNIT_ID>"
renderingViewClass:[NativeAdView class]];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[ADXNativeAdFactory sharedInstance] addDelegate:self];
[[ADXNativeAdFactory sharedInstance] loadAd:@"<ADX_NATIVE_AD_UNIT_ID>"];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[ADXNativeAdFactory sharedInstance] removeDelegate:self];
}
- (void)handleAdRevenue:(NSNumber *)revenue {
// 1) Firebase Analytics
[FIRAnalytics logEventWithName:kFIREventAdImpression
parameters: @{
kFIRParameterAdPlatform: @"AD(X)",
kFIRParameterAdFormat: @"NativeAd",
kFIRParameterAdUnitName: @"ADX Native Ad",
kFIRParameterCurrency: @"USD",
kFIRParameterValue: revenune
}];
// 2) AppsFlyer
NSDictionary * adRevenueParams = @{
@"AdUnitName" : @"ADX Native Ad",
@"AdType" : @"NativeAd",
};
AppsFlyerAdRevenue * appsFlyerAdRevenue = [AppsFlyerAdRevenue shared];
[appsFlyerAdRevenue
logAdRevenueWithMonetizationNetwork:@"AD(X)"
mediationNetwork:AppsFlyerAdRevenueMediationNetworkTypeCustom
eventRevenue:revenune
revenueCurrency:@"USD"
additionalParameters:adRevenueParams];
}
#pragma mark - ADXNativeAdFactoryDelegate
- (void)onSuccess:(NSString *)adUnitId nativeAd:(ADXNativeAd *)nativeAd {
NSLog(@"onSuccess : %@", adUnitId);
if([adUnitId isEqualToString:@"<ADX_NATIVE_AD_UNIT_ID>"]) {
self.nativeAd = nativeAd;
self.nativeAd.delegate = self;
__weak typeof(self) weakSelf = self;
self.nativeAd.paidEventHandler = ^(double eCPM) {
__strong typeof(self) strongSelf = weakSelf;
if(!strongSelf) { return; }
NSNumber * revenue = [NSNumber numberWithDouble:eCPM/1000];
[strongSelf handleAdRevenue:revenue];
};
UIView *nativeAdView = [[ADXNativeAdFactory sharedInstance]
getNativeAdView:@"<ADX_NATIVE_AD_UNIT_ID>"];
nativeAdView.frame = CGRectMake(0.0,
100.0,
320.0,
300.0);
[self.view addSubview:nativeAdView];
}
}
- (void)onFailure:(NSString *)adUnitId {
NSLog(@"onFailure : %@", adUnitId);
}
#pragma mark - ADXNativeAdDelegate
- (UIViewController *)viewControllerForPresentingModalView {
return self;
}
@end
import UIKit
import ADXLibrary
import FirebaseAnalytics
import AppsFlyerAdRevenue
class NativeAdViewController: UIViewController {
var nativeAd: ADXNativeAd?
override func viewDidLoad() {
super.viewDidLoad()
ADXNativeAdFactory.sharedInstance().setRenderingViewClass(
"<ADX_NATIVE_AD_UNIT_ID>",
renderingViewClass: NativeAdView.self)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
ADXNativeAdFactory.sharedInstance().add(self)
ADXNativeAdFactory.sharedInstance().loadAd("<ADX_NATIVE_AD_UNIT_ID>")
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
ADXNativeAdFactory.sharedInstance().remove(self)
}
func handleAdRevenue(revenue:NSNumber) {
// 1) Firebase Analytics
Analytics.logEvent(
AnalyticsEventAdImpression,
parameters: [
AnalyticsParameterAdPlatform: "AD(X)",
AnalyticsParameterAdUnitName: "ADX Native Ad",
AnalyticsParameterAdFormat: "NativeAd",
AnalyticsParameterValue: revenune,
AnalyticsParameterCurrency: "USD",
])
// 2) AppsFlyer
let adRevenueParams:[AnyHashable: Any] = [
"AdUnitName" : "ADX Native Ad",
"AdType" : "NativeAd",
]
AppsFlyerAdRevenue.shared().logAdRevenue(
monetizationNetwork: "AD(X)",
mediationNetwork: .custom,
eventRevenue: revenune,
revenueCurrency: "USD",
additionalParameters: adRevenueParams)
}
}
extension NativeAdViewController: ADXNativeAdFactoryDelegate,
ADXNativeAdDelegate
{
// MARK: - ADXNativeAdFactoryDelegate
public func onSuccess(_ adUnitId: String!, nativeAd: ADXNativeAd!) {
if (adUnitId == "<ADX_NATIVE_AD_UNIT_ID>") {
self.nativeAd = nativeAd
self.nativeAd?.delegate = self
self.nativeAd?.paidEventHandler = { [weak self] eCPM in
let revenue:NSNumber = (eCPM / 1000) as NSNumber
self?.handleAdRevenue(revenue: revenue)
}
let nativeAdView = ADXNativeAdFactory.sharedInstance()
.getNativeAdView("<ADX_NATIVE_AD_UNIT_ID>")
nativeAdView?.frame = CGRect(
x: (UIScreen.main.bounds.width - 300.0)/2,
y: 100.0,
width: 300.0,
height: 270.0)
self.view.addSubview(nativeAdView!)
} else {
print("fail to load")
}
}
public func onFailure(_ adUnitId: String!) {
print("onFailure :", adUnitId!)
}
// MARK: - ADXNativeAdDelegate
func viewControllerForPresentingModalView() -> UIViewController {
return self
}
}
AdJust의 광고 매출 데이터 연동을 지원합니다. 상세한 내용은 를 확인 부탁드립니다.