Native Ad
1. 基本要求
ADX iOS SDK添加到项目中。
请使用为 Native Ad 签发的 Ad Unit ID。
在请求广告之前 SDK 初始化请先进行。
SDK 初始化请在应用运行时只调用一次,并且 广告请求必须在初始化完成后进行。
如果支持 iOS 14 及以上, ATT(应用追踪透明性) 权限请求完成后再请求广告。
2. 布局设置
对于 Native Ad,需要您自行构建将用于展示广告的布局。必需的组成元素如下。
Title :
UILabelMain Text :
UILabelCall-To-Action :
UIButtonIcon Image :
UIImageViewMain Image :
UIImageViewPrivacy Icon :
UIImageViewAd Tag :
UIView (UILabel 또는 UIImageView)
这些元素必须包含并进行配置,广告内容上不应有覆盖的 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;
}
@endimport 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
}
}3. 实现
Native Ad 可以通过下面两种方法之一加载广告。
Case 1: 使用单个 View 的情况
使用
ADXNativeAdFactory的setRenderingViewClass:renderingViewClass:方法来配置RenderingViewClass。ADXNativeAdFactoryDelegate回调。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;
}
@endimport 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
}
}Case 2: 在 UITableView / UICollectionView 中使用 AdPlacer 的情况
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
}
}4. Ad Revenue (paidEventHandler)
您可以查看广告展示的预估广告收入。
#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;
}
@endimport 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
}
}最后更新于
这有帮助吗?