Geniee-Wrapper-Ad-SDK-iOS 1.0.2

Geniee-Wrapper-Ad-SDK-iOS 1.0.2

“takaaki.kobayashi”Nguyen Duy LongNguyen Thanh LongHironobu Yazaki维护。



  • Geniee

关于GNWrapperAdSDK的实施方案

概要

为了通过UPR优化+HB提高收益,使用GNWrapperAdSDK获取CustomTargeting信息,并使用Google AdManager进行广告展示。
因此,需要使用Firebase的RemoteConfig功能和Google AdManager。

  • 使用Firebase的RemoteConfig功能来获取广告区域信息。
  • 使用上述获取的广告区域信息,通过GNWrapperAdSDK获取UnitId和CustomTargeting信息。
  • 使用上述获取的UnitId和CustomTargeting信息,并通过Google AdManager进行广告展示。

实现步骤

1. 应用项目设置

1.1. Firebase初期設定

  1. 从Firebase管理界面创建项目并进行应用程序注册。

  2. 在注册应用程序时,会有一个下载步骤来下载包含访问Firebase所需信息的文件GoogleService-Info.plist,请进行下载。(或者,您可以直接从已注册应用程序的设置界面下载文件。)

  3. 将下载的文件GoogleService-Info.plist添加到应用程序的项目中。

    有关Firebase初始设置,请参考以下URL:将Firebase添加到iOS项目

1.2. RemoteConfig初期設定

  1. 创建一个plist文件,并写明default信息(广告框信息)。这是在无法从Firebase的RemoteConfig功能获取广告框信息时使用的。

    广告框信息可以使用以下json格式的字符串指定。

    第一层次 第二层次 类型 概述
    unit_id 字符串 AdManager中使用的UnitId。
    timeout 数字 各适配器中的请求等待时间(秒)。
    is_refresh 布尔值 刷新功能的启用/禁用。
    refresh_interval 数字 刷新时间(秒)。
    use_upr 布尔值 UPR的启用/禁用。
    upr_settings 字典
    upr_key 字符串 UPR键。
    upr_value 字符串 UPR值。
    use_hb 布尔值 HeaderBidding的启用/禁用。
    hb_list 列表
    hb_name 字符串 使用HB名。
    hb_values 字符串 获取信息的字符串。

    hb_name="Prebid"时的"hb_values"

    第一层次 类型 概述
    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"

    第一层次 类型 概述
    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. Frameworkの取り込み

  1. 请向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"的路径。

  2. 使用命令pod install将Framework导入到项目中。

1.4. Google AdManager初期設定

  1. 选择用于广告显示的功能。
    在文件Info.plist中写入以下内容。
    如果不指定,应用启动时会崩溃。

    功能 类型
    使用Google AdManager的情况 GADIsAdManagerApp 布尔值

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 初始化处理
  1. 为了使用Firebase功能,请添加import处理。

    ·objective-c

    @import Firebase;

    ·swift

    import Firebase
  2. 在方法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 广告框信息获取处理
  1. 使用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 初始化处理
  1. 使用GNWrapperAdSDK功能时,请添加import处理。

    ·objective-c

    #import <GNWrapperAdSdk/GNWrapperAdSDK.h>

    · 创建Swift桥接头文件,并添加以下内容。

    #import <GNWrapperAdSdk/GNWrapperAdSDK.h>
  2. 在方法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 加载处理
  1. 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)
  2. 添加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功能实现的详细信息,请参阅以下网址。

参考资料:

2.4.1 初始化处理
  1. 使用AdManager功能时,请添加import处理。

    ·objective-c

    @import GoogleMobileAds;

    ·swift

    import GoogleMobileAds
  2. 在方法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)
    }
  3. 添加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 加载处理
  1. 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)
    }
  2. 如果广告框信息中包含"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]]];
                                        }];
        }
    }
  3. 如果广告框信息中包含"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];
            }
        }
    }

备考

  • 关于一系列的实现代码,请参考示例应用程序。
  • 从iOS14开始,使用IDFA需要用户的明确许可。(此响应已从Apple的2021年初公布中响应。)有关应对方法,请参阅这里