关于 GNWrapperAdSDK 的实现方法
概述
使用 GNWrapperAdSDK 获取 CustomTargeting 信息,并结合 UPR 和 HB 进行优化以增加收益,使用 Google AdManager 进行广告显示。
因此,使用 Firebase 的 RemoteConfig 功能和 Google AdManager。
- 使用 Firebase 的 RemoteConfig 功能获取广告框信息。
- 使用 GNWrapperAdSDK 从上述获取的广告框信息中获取 UnitId 和 CustomTargeting 信息。
- 使用 Google AdManager 使用上述获取的 UnitId 和 CustomTargeting 信息进行广告展示。
实现步骤
1. 应用程序项目设置
1.1. Firebase 初始设置
-
从 Firebase 管理界面创建项目并注册应用程序。
-
在注册应用程序时,有一个关于如何下载包含访问Firebase所需信息的文件
GoogleService-Info.plist
的步骤,请进行下载。(或者,您也可以从已注册应用程序的设置界面下载文件。) -
将下载的文件
GoogleService-Info.plist
添加到应用程序的项目中。有关Firebase初始设置的详细信息,请参考以下URL。 将Firebase添加到iOS项目中
1.2. RemoteConfig初始设置
-
创建plist文件并记录default信息(广告框信息)。这是在Firebase的RemoteConfig功能无法获取广告框信息时使用。
广告框信息可以用以下JSON格式的字符串指定。
第1层 第2层 类型 概述 unit_id 字符串 AdManager中使用的UnitId。 timeout 数值 每个适配器的要求等待时间(秒)。 is_refresh 布尔值 刷新功能的启用/禁用。 refresh_interval 数值 刷新时间(秒)。 use_upr 布尔值 启用/禁用UPR。 upr_settings 字典 upr_key 字符串 UPR键。 upr_value 字符串 UPR值。 use_hb 布尔值 Header Bidding的启用/禁用。 hb_list 列表 hb_name 字符串 使用HB的名称。 hb_values 字符串 获取信息所需的字符串。 当hb_name="Prebid"时的"hb_values"
第1层 类型 概述 prebid_server_host_type 字符串 Prebid信息(server_host_type)。
"APPNEXUS"
"RUBICON"
"CUSTOM"prebid_server_host_url 字符串 Prebid信息(server_host_url)。 prebid_server_account_id 字符串 Prebid信息(server_account_id)。 config_id 字符串 Prebid信息(config_id)。 ad_size 字符串 广告尺寸。
宽x高当hb_name="Pubmatic"时的"hb_value"
第1层 类型 概述 app_store_url 字符串 Pubmatic信息(app_store_url)。 pub_id 字符串 Pubmatic信息(pub_id)。 profile_id 字符串 Pubmatic信息(profile_id)。 open_wrap_ad_unit_id 字符串 Pubmatic信息(UnitId)。 ad_size 字符串 广告尺寸。
宽x高示例代码
{"unit_id":"/15671365/pm_sdk/PMSDK-Demo-App-Banner","timeout":3.2,"is_refresh":true,"refresh_interval":10,"use_upr":true,"upr_settings":{"upr_key":"geniee-upr","upr_value":"prod"},"use_hb":true,"hb_list":[{"hb_name":"Prebid","hb_values":{"prebid_server_host_type":"APPNEXUS","prebid_server_host_url":"","prebid_server_account_id":"bfa84af2-bd16-4d35-96ad-31c6bb888df0","config_id":"6ace8c7d-88c0-4623-8117-75bc3f0a2e45","ad_size":"320x50"}}, {"hb_name":"Pubmatic","hb_values":{"app_store_url":"https://play.google.com/store/apps/details?id=com.example.android&hl=en","pub_id":"156276","profile_id":"1165","open_wrap_ad_unit_id":"/15671365/pm_sdk/PMSDK-Demo-App-Banner","ad_size":"320x50"}},{"hb_name":"aaaa","hb_values":{}}]}
有关Firebase RemoteConfig的初始设置,请参考以下URL。
设置应用程序内默认参数值
1.3. 框架集成
-
请将以下内容添加到Podfile中。(如果没有Podfile,请使用
pod init
命令创建)-
Firebase
# Firebase pod 'Firebase/Core' pod 'Firebase/RemoteConfig'
-
GoogleMobileAdSDK
# GoogleAdSDK pod 'Google-Mobile-Ads-SDK'
-
GNWrapperAdSDK
# GNWrapperAdSDK pod 'Geniee-Wrapper-Ad-SDK-iOS'
如果您需要在本地集成GNWrapperAdSDK,请将"GNWrapperAdSDK.framework"添加到项目中,并在项目设置中修改Build Settings的Framework Search Paths,指定"GNWrapperAdSDK.framework"的路径。
-
使用Prebid广告的情况
# Prebid pod 'PrebidMobile' # GNHBPrebidBannerAdapter pod 'Geniee-Wrapper-Ad-Banner-Adapter-Prebid-iOS'
如果需要在本地集成GNHBPrebidBannerAdapter,请将"GNHBPrebidBannerAdapter.framework"添加到项目中,并在项目设置中修改Build Settings的Framework Search Paths,指定"GNHBPrebidBannerAdapter.framework"的路径。
-
使用Pubmatic广告的情况
# PubMatic pod 'OpenWrapSDK' pod 'OpenWrapEventHandler/DFP' # GNHBPubmaticBannerAdapter pod 'Geniee-Wrapper-Ad-Banner-Adapter-Pubmatic-iOS'
如果需要在本地集成GNHBPubmaticBannerAdapter,请将"GNHBPubmaticBannerAdapter.framework"添加到项目中,并在项目设置中修改Build Settings的Framework Search Paths,指定"GNHBPubmaticBannerAdapter.framework"的路径。
-
-
使用
pod install
命令将Framework集成到项目中。
1.4. Google AdManager初始设置
-
选择用于广告显示的功能。
将以下内容添加到文件Info.plist
中。
如果不进行指定,则应用程序启动时可能会崩溃。功能 键 类型 值 使用Google AdManager的情况 GADIsAdManagerApp 布尔值 YES
2. 应用程序处理实现
2.1. 初始化处理
在应用程序启动后处理(AppDelegate)中添加Firebase的初始化处理。
·objective-c
@import Firebase;
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
[FIRApp configure];
return YES;
}
@end
·swift
import Firebase
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
FirebaseApp.configure()
return true
}
}
2.2. Firebase处理
有关Firebase的详细RemoteConfig功能,请参考以下URL。
参考资料:在iOS中使用Firebase Remote Config
2.2.1 初始处理
-
为使用Firebase功能,请添加import处理。
·objective-c
@import Firebase;
·swift
import Firebase
-
在方法
viewDidLoad
中执行以下初始处理。- 获取RemoteConfig对象。
- 指定 RemoteConfig功能获取信息失败时的默认值(使用
remoteConfig.setDefaults
处理指定plist文件(1.2.
创建))
·objective-c
@interface ViewController () @property(nonatomic, weak) FIRRemoteConfig *remoteConfig; @end @implementation ViewController // For Firebase. static NSString* const FIREBASE_DEFAULT_REMOTE_CONFIG = @"DefaultRemoteConfig"; static double const FIREBASE_FETCH_TIME_INTERVAL_SECONDS = 720; - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. _remoteConfig = [FIRRemoteConfig remoteConfig]; FIRRemoteConfigSettings *remoteConfigSettings = [[FIRRemoteConfigSettings alloc] init]; remoteConfigSettings.minimumFetchInterval = FIREBASE_FETCH_TIME_INTERVAL_SECONDS; _remoteConfig.configSettings = remoteConfigSettings; [_remoteConfig setDefaultsFromPlistFileName:FIREBASE_DEFAULT_REMOTE_CONFIG]; }
·swift
// For Firebase. let FIREBASE_DEFAULT_REMOTE_CONFIG: String = "DefaultRemoteConfig" let FIREBASE_FETCH_TIME_INTERVAL_SECONDS: Double = 720 var remoteConfig: RemoteConfig! = nil override func viewDidLoad() { self.remoteConfig = RemoteConfig.remoteConfig() self.remoteConfig.setDefaults(fromPlist: FIREBASE_DEFAULT_REMOTE_CONFIG) }
2.2.2 广告框信息获取处理
-
使用
remoteConfig.fetch
处理进行Firebase广告框信息的获取请求。
如果在初始处理中进行了默认值注册,则在获取失败的情况下也会返回已注册的默认值,因此不需要进行特别错误检查。·objective-c
static NSString* const FIREBASE_KEY_CONFIG = @"GNWrapperConfig_iOS"; [_remoteConfig fetchWithCompletionHandler:^(FIRRemoteConfigFetchStatus status, NSError *error) { if (status == FIRRemoteConfigFetchStatusSuccess) { [self.remoteConfig activateWithCompletion:^(BOOL changed, NSError * _Nullable error) { NSString *data = self.remoteConfig[FIREBASE_KEY_CONFIG].stringValue; }]; } else { NSString *data = self.remoteConfig[FIREBASE_KEY_CONFIG].stringValue; } }];
·swift
let FIREBASE_KEY_CONFIG: String = "GNWrapperConfig_iOS" remoteConfig.fetch(withExpirationDuration: TimeInterval(FIREBASE_FETCH_TIME_INTERVAL_SECONDS)) { (status, error) -> Void in if (status == .success) { self.remoteConfig.activate() { (changed, error) in let data = self.remoteConfig[self.FIREBASE_KEY_CONFIG].stringValue } } else { let data = self.remoteConfig[self.FIREBASE_KEY_CONFIG].stringValue } }
2.3. GNWrapperAdSDK处理
2.3.1 初始处理
-
为了使用GNWrapperAdSDK功能,请添加import处理。
·objective-c
#import <GNWrapperAdSdk/GNWrapperAdSDK.h>
· 创建swift桥接头文件并添加以下内容。
#import <GNWrapperAdSdk/GNWrapperAdSDK.h>
-
在方法
viewDidLoad
中执行以下初始处理。- GNWrapperAdBanner对象的创建、初始化和addView处理。
·objective-c
// Ad Size. #define ADMANAGER_AD_SIZE kGADAdSizeBanner @interface ViewController () <GNWrapperAdDelegate> @property(nonatomic, retain) GNWrapperAdBanner *gnWrapperAd; @property(nonatomic, retain) GNCustomTargetingParams *targetParams; @end @implementation ViewController - (void)viewDidLoad { [GNWrapperAdSDK setLogPriority:GNLogPriorityInfo]; _gnWrapperAdBanner = [[GNWrapperAdBanner alloc] init]; [_gnWrapperAd setHidden:true]; [self.view addSubview:_gnWrapperAd]; _gnWrapperAd.frame = CGRectMake(0, 0, ADMANAGER_AD_SIZE.size.width, ADMANAGER_AD_SIZE.size.height); _gnWrapperAd.center = CGPointMake(self.view.center.x, self.view.center.y); } @end
·swift
let ADMANAGER_AD_SIZE: GADAdSize = kGADAdSizeBanner var gnWrapperAd: GNWrapperAdBanner! = nil var targetParams: GNCustomTargetingParams! = nil override func viewDidLoad() { GNWrapperAdSDK.setLogPriority(GNLogPriorityInfo) self.gnWrapperAd = GNWrapperAdBanner.init() self.gnWrapperAd.isHidden = true self.view.addSubview(self.gnWrapperAd) self.gnWrapperAd.frame = CGRect(x: 0, y: 0, width: ADMANAGER_AD_SIZE.size.width, height: ADMANAGER_AD_SIZE.size.height) self.gnWrapperAd.center = CGPoint(x: self.view.center.x, y: self.view.center.y) }
2.3.2 加载处理
-
在RemoteConfig的fetch处理完成后,执行以下操作。
·objective-c
NSString *data = self.remoteConfig[FIREBASE_KEY_CONFIG].stringValue; [self.gnWrapperAd initWithLoad:data delegate:self viewController:self];
·swift
let data = self.remoteConfig[self.FIREBASE_KEY_CONFIG].stringValue self.gnWrapperAd.initWithLoad(data, delegate: self, viewController: self)
-
添加Delegate处理。
·objective-c
// GNWrapperAdBannerDelegate - (void)onComplete:(GNWrapperAdBanner*)view params:(GNCustomTargetingParams *)params { _targetParams = params; } - (void)onError:(GNWrapperAdBanner*)view error:(NSError *)error{ NSLog(@"ViewController: onError = %@", error.localizedDescription); }
·swift
// GNWrapperAdBannerDelegate extension ViewController: GNWrapperAdBannerDelegate { func onComplete(_ view:GNWrapperAdBanner, params: GNCustomTargetingParams) { self.targetParams = params } func onError(_ view:GNWrapperAdBanner) { print("ViewController: onError") } }
2.4. 广告展示处理(AdManager)
有关详细的AdManager功能实现方法,请参考以下URL。
参考资料:
2.4.1 初始处理
-
为了使用AdManager功能,请添加import处理。
·objective-c
@import GoogleMobileAds;
·swift
import GoogleMobileAds
-
在方法
viewDidLoad
中执行以下初始处理。- DFPBannerView对象的创建、初始化和addView处理。
·objective-c
@interface ViewController () <GADBannerViewDelegate, GADAppEventDelegate, GNWrapperAdDelegate> @property(nonatomic, strong) DFPBannerView *bannerView; @end @implementation ViewController - (void)viewDidLoad { _bannerView = [[DFPBannerView alloc] initWithAdSize:ADMANAGER_AD_SIZE]; _bannerView.delegate = self; _bannerView.appEventDelegate = self; _bannerView.rootViewController = self; [self.view addSubview:_bannerView]; _bannerView.center = CGPointMake(self.view.center.x, self.view.center.y); } @end
·swift
var bannerView: DFPBannerView! = nil override func viewDidLoad() { self.bannerView = DFPBannerView.init(adSize: ADMANAGER_AD_SIZE) self.bannerView.delegate = self self.bannerView.appEventDelegate = self self.bannerView.rootViewController = self self.view.addSubview(self.bannerView) self.bannerView.center = CGPoint(x: self.view.center.x, y: self.view.center.y) }
-
添加Delegate处理,并为当前显示的广告View设置GNWrapperAdSDK。
- GADBannerViewDelegate。
·objective-c
// GADBannerViewDelegate - (void)adViewDidReceiveAd:(DFPBannerView *)adView { [_gnWrapperAd requestRefresh:_bannerView]; } - (void)adView:(DFPBannerView *)adView didFailToReceiveAdWithError:(GADRequestError *)error { NSLog(@"ViewController: didFailToReceiveAdWithError: %@", [error localizedDescription]); }
·swift
extension ViewController: GADBannerViewDelegate { func adViewDidReceiveAd(_ bannerView: GADBannerView) { self.gnWrapperAd.requestRefresh(self.bannerView) } func adView(_ bannerView: GADBannerView, didFailToReceiveAdWithError error: GADRequestError) { print("ViewController: didFailToReceiveAdWithError: \(error.localizedDescription)") } }
- GADAppEventDelegate。
·objective-c
/// GADAppEventDelegate. - (void)adView:(DFPBannerView *)banner didReceiveAppEvent:(NSString *)name withInfo:(NSString *)info { }
·swift
extension ViewController: GADAppEventDelegate { func adView(_ banner: GADBannerView, didReceiveAppEvent name: String, withInfo info: String?) { } }
2.4.2 加载处理
-
在GNWrapperAdSDK的onComplete处理时执行以下操作。
·objective-c
- (void)onComplete:(GNWrapperAd*)view params:(GNCustomTargetingParams *)params { _targetParams = params; [_gnWrapperAd setHidden:true]; [_bannerView setHidden:false]; _bannerView.adUnitID = _targetParams.unitId; DFPRequest * request = [DFPRequest request]; request.customTargeting = _targetParams.targetParams; [self.bannerView loadRequest:request]; }
·swift
func onComplete(_ view:GNWrapperAd, params: GNCustomTargetingParams) { self.targetParams = params self.gnWrapperAd.isHidden = true self.bannerView.isHidden = false self.bannerView.adUnitID = self.targetParams.unitId let request: DFPRequest = DFPRequest.init() request.customTargeting = (self.targetParams.targetParams as! [AnyHashable : Any]) self.bannerView.load(request) }
-
如果广告框信息中存在"Prebid"信息,则在AdManager加载完成后,添加以下处理。
·objective-c
func adViewDidReceiveAd(_ bannerView: GADBannerView) { self.gnWrapperAd.requestRefresh(self.bannerView) if ("Prebid" == self.gnWrapperAd.getAfterLoadedGAMBanner()) { AdViewUtils.findPrebidCreativeSize(self.bannerView, success: { (size) in self.bannerView.resize(GADAdSizeFromCGSize(size)) }, failure: { (error) in print("ViewController: adViewDidReceiveAd error = \(error.localizedDescription)") } ) } }
·swift
- (void)adViewDidReceiveAd:(DFPBannerView *)adView { [_gnWrapperAd requestRefresh:_bannerView]; if ([@"Prebid" isEqualToString:[_gnWrapperAd getAfterLoadedGAMBanner]]) { [AdViewUtils findPrebidCreativeSize:adView success:^(CGSize size) { [adView resize:GADAdSizeFromCGSize(size)]; } failure:^(NSError * _Nonnull error) { [GNLog logWithPriority:GNLogPriorityError message:[NSString stringWithFormat:@"ViewController: adViewDidReceiveAd error = %@", [error localizedDescription]]]; }]; } }
-
如果广告框信息中存在"Pubmatic"信息,则在AdManager的AppEvent时,添加以下处理。
·objective-c
func adView(_ banner: GADBannerView, didReceiveAppEvent name: String, withInfo info: String?) { if ("pubmaticdm" == name) { if (self.gnWrapperAd.isNecessaryShow()) { self.gnWrapperAd.isHidden = false self.bannerView.isHidden = true self.gnWrapperAd.show() self.gnWrapperAd.requestRefresh(self.gnWrapperAd) } } }
·swift
- (void)adView:(DFPBannerView *)banner didReceiveAppEvent:(NSString *)name withInfo:(NSString *)info { if ([@"pubmaticdm" isEqualToString:name]) { if ([_gnWrapperAd isNecessaryShow]) { [_gnWrapperAd setHidden:false]; [_bannerView setHidden:true]; [_gnWrapperAd show]; [_gnWrapperAd requestRefresh:_gnWrapperAd]; } } }
备注
- 有关一系列实现代码,请参阅示例应用程序。
- 自iOS 14以来,使用IDFA需要用户的明确许可。(本响应尚在准备中,Apple于2021年初宣布响应。响应方法请参阅此处。)