# iOS自定义平台适配器 **Repository Path**: admobile/ios-custom-platform-adapter ## Basic Information - **Project Name**: iOS自定义平台适配器 - **Description**: No description available - **Primary Language**: Objective-C - **License**: GPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2021-11-09 - **Last Updated**: 2025-07-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # iOS - 自定义平台适配器对接文档 [TOC] ## 1.1 概述 尊敬的开发者,欢迎您使用Suyi聚合广告SDK自定义适配广告平台。通过本文档,您可以在几分钟之内轻松完成自定义广告平台对接过程。 操作系统及要求:iOS10.0及以上;依赖库中含有5G网络字段,故需Xcode包含最低14.5 SDK 自定义适配器平台支持广告类型:开屏,横幅,插屏,激励视频,信息流等; ## 2.1 采用 cocoapods 进行自定义平台依赖库SDK的导入 推荐使用Pod命令导入自定义平台所需要的依赖库: ```ruby pod 'ADSuyiSDK', '~> 4.0.1.06132' pod 'ADSuyiSDK/ADSuyiSDKPlatforms/tianmu' # 天目 #必选 ``` ## 3.1 在 ADmobile 运营后台增加自定义适配平台 1、**广告平台**:因ADSuyiSDK与运营后台的通信是依赖于双端协定的平台名称来进行逻辑处理(**新增自定义平台尚未开通开发者后台自主添加功能,如有需要请联系ADmobile运营同学协助添加**),故新增自定义平台不能与现有平台名称冲突且SDK端与后台录入平台名称一致;需谨记在运营后台添加的广告平台名称字段,该字段在自定义适配器开发时需要用到且必须与后台所填一致,否则会有广告加载异常问题;在后台添加新平台时需要添加该三方平台的申请的AppId和AppKey,该参数用于SDK端三方平台SDK初始化; 2、**广告类型**:因自定义平台适配器不能增加新的广告类型,故只能使用现有广告类型来进行平台广告的添加,在添加自定义平台广告位时,需严格按照平台的广告类型创建广告位id,现有广告类型(模板,自渲染,模板2.0等),如不清楚平台所示广告为何种类型时,请咨询我们技术同学;自定义平台适配器开发时,需明确该类为何种广告类型的加载器; 3、**平台及广告加载器注册**:自定义适配器平台开发中,需要继承对应的初始化父类及广告类型适配器父类,并应在load方法中调用注册方法来告知主SDK注册的平台及广告类型; 4、**初始化类**:自定义平台初始化类继承自自定义适配平台SDK,应在父类开放方法实现中来初始化三方平台SDK; 5、**广告加载类**:自定义适配平台加载器类中,需要继承自适配平台SDK依赖库对应广告类型父类,并在子类中实现响应加载方法及展示方法(**部分广告类型无展示方法,仅需实现请求方法且务必正确调用相应track方法确保广告正常展示**),方法中有广告请求参数model,根据平台加载广告所需参数从model拿到相应参数; 6、**广告回调**:因ADmobile需要根据平台回调时机来统计广告相关数据,故开发者在适配器开发过程中,需要根据平台广告回调中,调用响应方法,告知主SDK端进行数据统计(如:- (void)trackSplashAdRequest广告请求时调用此方法),需严格按照对应回调调用相应方法; ## 4.1 自定义适配器平台示例 以下自定义广告适配示例采用已适配平台:穿山甲(toutiao),优量汇(gdt) ### 4.1.1 初始化类适配 1. 需继承 `ADSuyiCustomAdapterInitialize` 2. 通过以下方法 & 子类实现完成适配 |
方法
|
参数说明
| |:-----------|:------| | + (void)registPlatformAdLoaderClass:(id)klass forSdkName:(NSString *)sdkName | 注册初始化类 需要在load方法中调用

kclass: 初始化自定义平台的管理类
sdkName: 平台名称,需与后台配置管理类名一致且不能与现有平台名称冲突,例如:toutiao | | **需子类实现:** | | | +(void)initAdSDKWithConfigInfo:(ADSuyiCustomAdapterRequestContext *)config | 初始化方法

config: 初始化参数 | | +(NSString *)platformSDKVersion | 平台版本号 | **demo示例:** `ADSuyiCustomAdapterBUInitialize.h` ```objc #import /// 初始化 @interface ADSuyiCustomAdapterBUInitialize : ADSuyiCustomAdapterInitialize @end ``` `ADSuyiCustomAdapterBUInitialize.m` ```objc #import "ADSuyiCustomAdapterBUInitialize.h" #import #import #import @implementation ADSuyiCustomAdapterBUInitialize + (void)load { // 调用注册方法 //以现有广告平台穿山甲作为demo示例 [self registPlatformInitializeClass:self forSdkName:@"toutiao"]; } // MARK: - Override + (void)initAdSDKWithConfigInfo:(ADSuyiCustomAdapterRequestContext *)config { static NSString *_appid; if(config.appId && [_appid isEqualToString:config.appId]) { return; } _appid = config.appId.copy; // 初始化三方SDK [BUAdSDKManager setAppID:_appid]; BUAdSDKConfiguration *configuration = [BUAdSDKConfiguration configuration]; configuration.territory = BUAdSDKTerritory_CN; // 需要设置 if (![ADSuyiSDK enablePersonalAd]){ NSString *userExtData = @"[{\"name\":\"personal_ads_type\",\"value\":\"0\"}]"; configuration.userExtData = userExtData; } configuration.appID = _appid; configuration.secretKey = config.appKey; [BUAdSDKManager startWithAsyncCompletionHandler:^(BOOL success, NSError *error) { if (success) { // Success NSLog(@"toutiao sdk init success"); }else{ // Error NSLog(@"toutiao sdk init error = %@",error); } }]; } // 需要实现改方法 返回三方平台当前版本号 + (NSString *)platformSDKVersion { // 12221:可以为当前修改时间去的时间,也可以直接返回版本号 return [NSString stringWithFormat:@"%@.12221",[BUAdSDKManager SDKVersion]]; } @end ``` ### 4.1.2 开屏广告适配 1. 需继承 `ADSuyiCustomAdapterSplashAd` 2. 通过以下方法子类进行调用 & 子类进行实现来完成适配 |
方法
|
参数说明
| |:-----------|:------| | -(void)trackSplashAdSucceed | 三方平台请求成功时子类适配器中调用方法 | | -(void)trackSplashAdDisplay | 三方平台展示回调回调时子类适配器中调用方法 | | -(void)trackSplashAdSuccessToPresent | 三方平台展示成功时子类适配器中调用方法 | | -(void)trackSplashAdFailedWithError:(nullable NSError*)error | 三方平台请求失败回调时子类适配器中调用方法 | | -(void)trackSplashAdFailedToPresentWithError:(nullable NSError*)error | 三方平台渲染失败回调时子类适配器中调用方法 | | -(void)trackSplashAdClicked | 三方平台点击时子类适配器中调用方法 | | -(void)trackSplashAdSkip | 三方平台跳过回调时子类适配器中调用方法 | | -(void)trackSplashAdClosed | 三方平台关闭回调时子类适配器中调用方法 | | -(void)trackSplashAdLandingPageClosed | 三方平台关闭落地页回调时子类适配器中调用方法 | | | | | -(void)showSplashWithAdView:( UIView * _Nullable )adView customSkipBtn:(BOOL)isCustomBtn | (非必须调用)若平台是以返回 View 为形式,让我们自行添加至 Window, 可将 View 通过该方法添加至 Window, 并管理视图销毁, 并处理屏幕翻转问题 | | **需子类实现:** | | | -(void)requestAdWithContext:(ADSuyiCustomAdapterSplashRequestContext *)context | 请求广告方法,必须于子类中实现 | | -(void)customAdapter_onAdReceive | 聚合告知可进行展示时触发,需要在子类实现并调用展示方法 | **demo示例:** `ADSuyiCustomAdapterBUSplashAd.h` ```objc #import @interface ADSuyiCustomAdapterBUSplashAd : ADSuyiCustomAdapterSplashAd @end ``` `ADSuyiCustomAdapterBUSplashAd.m` ```objc #import "ADSuyiCustomAdapterBUSplashAd.h" #import @interface ADSuyiCustomAdapterBUSplashAd () @property (nonatomic, strong) BUSplashAd *splashAd; @property (nonatomic, strong) ADSuyiCustomAdapterSplashRequestContext *context; @end @implementation ADSuyiCustomAdapterBUSplashAd // MARK: - Override + (void)load { [self registPlatformAdLoaderClass:self forSdkName:@"toutiao" renderType:ADSuyiAdapterRenderTypeNative]; [self registPlatformAdLoaderClass:self forSdkName:@"toutiao" renderType:ADSuyiAdapterRenderTypeExpress]; } /// 请求 - (void)requestAdWithContext:(ADSuyiCustomAdapterSplashRequestContext *)context{ _context = context; if(!_splashAd) { CGFloat width = UIScreen.mainScreen.bounds.size.width; CGFloat height = UIScreen.mainScreen.bounds.size.height - context.bottomView.frame.size.height; _splashAd = [[BUSplashAd alloc] initWithSlotID:context.posId adSize:CGSizeMake(width, height)]; _splashAd.delegate = self; _splashAd.tolerateTimeout = 3; } [_splashAd loadAdData]; } /// 展示 -(void)customAdapter_onAdReceive{ UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow; [_splashAd showSplashViewInRootViewController:keyWindow.rootViewController]; } // MARK: - BUSplashAdDelegate /// This method is called when material load successful - (void)splashAdLoadSuccess:(BUSplashAd *)splashAd{ [self trackSplashAdSucceed]; } /// This method is called when material load failed - (void)splashAdLoadFail:(BUSplashAd *)splashAd error:(BUAdError *)error { [self trackSplashAdFailedWithError:error]; } /// This method is called when splash view render successful - (void)splashAdRenderSuccess:(nonnull BUSplashAd *)splashAd { // 渲染成功再展示视图控制器,目前统一放置需要展示的时候 UIView *bottomView = _context.bottomView; if(bottomView){ bottomView.frame = CGRectMake(0, UIScreen.mainScreen.bounds.size.height - bottomView.frame.size.height, UIScreen.mainScreen.bounds.size.width, bottomView.frame.size.height); [splashAd.splashRootViewController.view addSubview:_context.bottomView]; } } /// This method is called when splash view render failed - (void)splashAdRenderFail:(BUSplashAd *)splashAd error:(BUAdError *)error { [self trackSplashAdFailedToPresentWithError:error]; } /// This method is called when splash view will show - (void)splashAdWillShow:(nonnull BUSplashAd *)splashAd {} /// This method is called when splash view did show - (void)splashAdDidShow:(BUSplashAd *)splashAd { [self trackSplashAdSuccessToPresent]; [self trackSplashAdDisplay]; } /// This method is called when splash view is clicked. - (void)splashAdDidClick:(BUSplashAd *)splashAd { [self trackSplashAdClicked]; } /// This method is called when splash view is closed. - (void)splashAdDidClose:(BUSplashAd *)splashAd closeType:(BUSplashAdCloseType)closeType { if(_context.bottomView){ [_context.bottomView removeFromSuperview]; } if (closeType == BUSplashAdCloseType_ClickSkip) { [self trackSplashAdSkip]; } [self trackSplashAdClosed]; } /// This method is called when splash viewControllr is closed. - (void)splashAdViewControllerDidClose:(nonnull BUSplashAd *)splashAd {} /** This method is called when another controller has been closed. @param interactionType : open appstore in app or open the webpage or view video ad details page. */ - (void)splashDidCloseOtherController:(BUSplashAd *)splashAd interactionType:(BUInteractionType)interactionType { [self trackSplashAdLandingPageClosed]; } /// This method is called when when video ad play completed or an error occurred. - (void)splashVideoAdDidPlayFinish:(nonnull BUSplashAd *)splashAd didFailWithError:(nonnull NSError *)error {} @end ``` ### 4.1.3 横幅广告 1. 需继承 `ADSuyiCustomAdapterBannerAd` 2. 通过以下方法子类进行调用 & 子类进行实现来完成适配 |
方法
|
参数说明
| |:-----------|:------| | -(void)trackBannerAdDidReceived | 三方平台广告请求成功时,子类适配器中调用方法 | | -(void)trackBannerAdFailToReceivedWithError:(nullable NSError *)error | 三方平台广告请求失败时,子类适配器中调用方法 | | -(void)trackBannerAdClicked | 三方平台广告点击时,子类适配器中调用方法 | | -(void)trackBannerAdExposure | 三方平台广告曝光时,子类适配器调用方法 | | -(void)trackBannerAdClosed | 三方平台广告关闭时,子类适配器中调用方法 | | -(void)trackBannerAdLandingPageClosed | 三方平台广告落地页关闭时,子类适配器中调用方法 | | **需子类实现:** | | | -(UIView *)requestBannerViewWithContext:(ADSuyiCustomAdapterBannerRequestContext *)context | 在子类实现该方法用于请求平台banner广告 | **demo示例:** `ADSuyiCustomAdapterBUBanner.h` ```objc #import @interface ADSuyiCustomAdapterBUBanner : ADSuyiCustomAdapterBannerAd @end ``` `ADSuyiCustomAdapterBUBanner.m` ```objc #import "ADSuyiCustomAdapterBUBanner.h" #import @interface ADSuyiCustomAdapterBUBanner () { BUNativeExpressBannerView *_bannerAd; } @end @implementation ADSuyiCustomAdapterBUBanner // MARK: - Override + (void)load { [self registPlatformAdLoaderClass:self forSdkName:@"toutiao"]; } - (UIView *)requestBannerViewWithContext:(ADSuyiCustomAdapterBannerRequestContext *)context{ _bannerAd = [[BUNativeExpressBannerView alloc] initWithSlotID:context.posId rootViewController:context.viewController adSize:context.adSize interval:context.refreshTime]; _bannerAd.delegate = self; [_bannerAd loadAdData]; return _bannerAd; } // MARK: - banner delegate /** This method is called when bannerAdView ad slot loaded successfully. @param bannerAdView : view for bannerAdView */ - (void)nativeExpressBannerAdViewDidLoad:(BUNativeExpressBannerView *)bannerAdView { [self trackBannerAdDidReceived]; } /** This method is called when bannerAdView ad slot failed to load. @param error : the reason of error */ - (void)nativeExpressBannerAdView:(BUNativeExpressBannerView *)bannerAdView didLoadFailWithError:(NSError *_Nullable)error { [self trackBannerAdFailToReceivedWithError:error]; } /** This method is called when rendering a nativeExpressAdView successed. */ - (void)nativeExpressBannerAdViewRenderSuccess:(BUNativeExpressBannerView *)bannerAdView {} /** This method is called when a nativeExpressAdView failed to render. @param error : the reason of error */ - (void)nativeExpressBannerAdViewRenderFail:(BUNativeExpressBannerView *)bannerAdView error:(NSError * __nullable)error {} /** This method is called when bannerAdView ad slot showed new ad. */ - (void)nativeExpressBannerAdViewWillBecomVisible:(BUNativeExpressBannerView *)bannerAdView { [self trackBannerAdExposure]; } /** This method is called when bannerAdView is clicked. */ - (void)nativeExpressBannerAdViewDidClick:(BUNativeExpressBannerView *)bannerAdView { [self trackBannerAdClicked]; } /** This method is called when the user clicked dislike button and chose dislike reasons. @param filterwords : the array of reasons for dislike. */ - (void)nativeExpressBannerAdView:(BUNativeExpressBannerView *)bannerAdView dislikeWithReason:(NSArray *_Nullable)filterwords { [self trackBannerAdClosed]; } /** This method is called when another controller has been closed. @param interactionType : open appstore in app or open the webpage or view video ad details page. */ - (void)nativeExpressBannerAdViewDidCloseOtherController:(BUNativeExpressBannerView *)bannerAdView interactionType:(BUInteractionType)interactionType { [self trackBannerAdLandingPageClosed]; } /** This method is called when the Ad view container is forced to be removed. @param bannerAdView : Express Banner Ad view container */ - (void)nativeExpressBannerAdViewDidRemoved:(BUNativeExpressBannerView *)bannerAdView {} @end ``` ### 4.1.4 插屏广告 1. 需继承 `ADSuyiCustomAdapterInterstitalAd` 2. 通过以下方法子类进行调用 & 子类进行实现来完成适配 |
方法
|
参数说明
| |:-----------|:------| | -(void)trackInterstitialAdSuccessToLoad | 三方平台请求成功时,子类适配器中调用方法 | | -(void)trackInterstitialAdDidPresent | 三方平台广告展示时,子类适配器中调用方法 | | -(void)trackInterstitialAdFailToLoadError:(nullable NSError *)error | 三方平台请求失败时,子类适配器中调用方法 | | -(void)trackInterstitialAdFailToPresentError:(nullable NSError *)error | 三方平台广告展示失败时,子类适配器中调用方法 | | -(void)trackInterstitialAdDidClick | 三方平台广告点击时,子类适配器中调用方法 | | -(void)trackInterstitialAdDidClose | 三方平台广告关闭时,子类适配器中调用方法 | | -(void)trackInterstitialAdDidExposure | 三方平台广告曝光时,子类适配器中调用方法 | | -(void)trackInterstitialAdLandingPageClosed | 三方平台广告落地页关闭时,子类适配器中调用方法 | | **需子类实现:** | | | -(void)requestAdWithContext:(ADSuyiCustomAdapterInterstitalRequestContext *)context | 请求广告方法,必须于子类中实现 | | -(void)showInterstitalAdFromViewController:(UIViewController * _Nullable )viewController | 展示插屏广告 | **demo示例:** `ADSuyiCustomAdapterBUIntertitalAd.h` ```objc #import @interface ADSuyiCustomAdapterBUIntertitalAd : ADSuyiCustomAdapterInterstitalAd @end ``` `ADSuyiCustomAdapterBUIntertitalAd.m` ```objc #import "ADSuyiCustomAdapterBUIntertitalAd.h" #import @interface ADSuyiCustomAdapterBUIntertitalAd () { BUNativeExpressFullscreenVideoAd *_interstitialAd; ADSuyiCustomAdapterInterstitalRequestContext *_context; } @end @implementation ADSuyiCustomAdapterBUIntertitalAd // MARK: - Override + (void)load { [self registPlatformAdLoaderClass:self forSdkName:@"toutiao" renderType:(ADSuyiAdapterRenderTypeExpress)]; [self registPlatformAdLoaderClass:self forSdkName:@"toutiao" renderType:(ADSuyiAdapterRenderTypeExpressPro)]; } - (void)requestAdWithContext:(ADSuyiCustomAdapterInterstitalRequestContext *)context { _context = context; if(!_interstitialAd) { _interstitialAd = [[BUNativeExpressFullscreenVideoAd alloc]initWithSlotID:context.posId]; _interstitialAd.delegate = self; } [_interstitialAd loadAdData]; } - (void)showInterstitalAdFromViewController:(UIViewController *)viewController { if (!viewController) { viewController = _context.viewController; } [_interstitialAd showAdFromRootViewController:viewController]; } // MARK: - BUNativeExpressFullscreenVideoAdDelegate /** This method is called when video ad material loaded successfully. */ - (void)nativeExpressFullscreenVideoAdDidLoad:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd {} /** This method is called when video cached successfully. For a better user experience, it is recommended to display video ads at this time. And you can call [BUNativeExpressFullscreenVideoAd showAdFromRootViewController:]. */ - (void)nativeExpressFullscreenVideoAdDidDownLoadVideo:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd { [self trackInterstitialAdSuccessToLoad]; } /** This method is called when video ad materia failed to load. @param error : the reason of error */ - (void)nativeExpressFullscreenVideoAd:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd didFailWithError:(NSError *_Nullable)error { [self trackInterstitialAdFailToLoadError:error]; } /** This method is called when rendering a nativeExpressAdView successed. It will happen when ad is show. */ - (void)nativeExpressFullscreenVideoAdViewRenderSuccess:(BUNativeExpressFullscreenVideoAd *)rewardedVideoAd {} /** This method is called when a nativeExpressAdView failed to render. @param error : the reason of error */ - (void)nativeExpressFullscreenVideoAdViewRenderFail:(BUNativeExpressFullscreenVideoAd *)rewardedVideoAd error:(NSError *_Nullable)error {} - (void)nativeExpressFullscreenVideoAdDidVisible:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd { [self trackInterstitialAdDidPresent]; [self trackInterstitialAdDidExposure]; } - (void)nativeExpressFullscreenVideoAdDidClick:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd { [self trackInterstitialAdDidClick]; } - (void)nativeExpressFullscreenVideoAdDidClose:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd { [self trackInterstitialAdDidClose]; } - (void)nativeExpressFullscreenVideoAdDidCloseOtherController:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd interactionType:(BUInteractionType)interactionType { [self trackInterstitialAdLandingPageClosed]; } @end ``` ### 4.1.5 激励视频 1. 需继承 `ADSuyiCustomAdapterRewardVodAd` 2. 通过以下方法子类进行调用 & 子类进行实现来完成适配 |
方法
|
参数说明
| |:-----------|:------| | -(void)trackRwardvodAdLoadSuccess | 三方平台请求成功时,子类适配器中调用方法 | | -(void)trackRewardvodAdReadyToPlay | 三方平台视频准备播放时,子类适配器中调用方法 | | -(void)trackRewardvodAdVideoLoadSuccess | 三方平台视频准备完成时,子类适配器中调用方法 | | -(void)trackRewardvodAdWillVisible | 三方平台视频即将展示时,子类适配器中调用方法 | | -(void)trackRewardvodAdDidVisible | 三方平台视频展示时,子类适配器中调用方法 | | -(void)trackRewardvodAdDidClose | 三方平台视频关闭时,子类适配器中调用方法 | | -(void)trackRewardvodAdDidClick | 三方平台视频点击时,子类适配器中调用方法 | | -(void)trackRewardvodAdDidPlayFinish | 三方平台视频播放完成时,子类适配器中调用方法 | | -(void)trackRewardVodAdDidRewardEffective | 三方平台视频播放达到激励条件时,子类适配器中调用方法 | | -(void)trackRewardvodAdFailToLoadError:(NSError *)error | 三方平台请求失败时,子类适配器中调用方法 | | -(void)trackRewardvodAdFailToPresentError:(NSError *)error | 三方平台展示失败时,子类适配器中调用方法 | | -(void)trackRewardvodAdVideoFailToPlayError:(NSError *)error | 三方平台视频播放错误时,子类适配器中调用方法 | | -(void)trackRewardvodAdLandingPageClosed | 三方平台关闭落地页时,子类适配器中调用方法 | | -(void)trackRewardvodAdVideoAdServerRewardDidSucceedWithInfo: | 三方平台广告服务器验证成功(携带激励验证相关参数),子类适配器中调用方法 | | -(void)trackRewardvodAdVideoAdServerRewardDidFailed: | 广告服务器验证失败 | | **需子类实现:** | | | -(void)requestAdWithContext:(ADSuyiCustomAdapterRewardRequestContext *)context | 请求广告方法,必须于子类中实现 | | -(void)showRewardVodAdFromViewController:(UIViewController * _Nullable)viewController | 展示激励视频方法方法,在该方法实现中调用平台展示方法 | | -(bool)isReady | 激励视频广告是否准备好 | | -(bool)isValid | 激励视频广告物料是否有效 | | -(bool)canServerVerrify | 激励视频广告是否支持服务端验证 | **demo示例:** `ADSuyiCustomAdapterBURewardAd.h` ```objc #import @interface ADSuyiCustomAdapterBURewardAd : ADSuyiCustomAdapterRewardVodAd @end ``` `ADSuyiCustomAdapterBURewardAd.m` ```objc #import "ADSuyiCustomAdapterBURewardAd.h" #import #import @interface ADSuyiCustomAdapterBURewardAd () { BUNativeExpressRewardedVideoAd *_rewardVideoAd; ADSuyiCustomAdapterRewardRequestContext *_context; BOOL _isReady; } @end @implementation ADSuyiCustomAdapterBURewardAd // MARK: - Override + (void)load { [self registPlatformAdLoaderClass:self forSdkName:@"toutiao" renderType:(ADSuyiAdapterRenderTypeExpress)]; } /// 请求 - (void)requestAdWithContext:(ADSuyiCustomAdapterRewardRequestContext *)context { _context = context; BURewardedVideoModel *model= [BURewardedVideoModel new]; model.userId = context.userId; if (context.extra){ model.extra = context.extra; } if (context.rewardName){ model.rewardName = context.rewardName; } if (context.rewardAmount){ model.rewardAmount = context.rewardAmount.integerValue; } _rewardVideoAd = [[BUNativeExpressRewardedVideoAd alloc] initWithSlotID:context.posId rewardedVideoModel:model]; _rewardVideoAd.delegate = self; _rewardVideoAd.rewardPlayAgainInteractionDelegate = self; [_rewardVideoAd loadAdData]; } /// 展示 - (void)showRewardVodAdFromViewController:(UIViewController *)viewController { if (!viewController) { viewController = _context.viewController; } [_rewardVideoAd showAdFromRootViewController:viewController]; } - (bool)isReady{ return _isReady; } - (bool)isValid{ return _isReady; } - (bool)canServerVerrify{ return true; } // MARK: - Method - (void)setIsReady:(BOOL)isReady { if(_isReady == NO && isReady == YES) { _isReady = isReady; [self trackRewardvodAdReadyToPlay]; } else { _isReady = isReady; } } // MARK: - BUNativeExpressRewardedVideoAdDelegate /** This method is called when video ad material loaded successfully. */ - (void)nativeExpressRewardedVideoAdDidLoad:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd { [self trackRwardvodAdLoadSuccess]; self.isReady = true; } /** This method is called when video ad materia failed to load. @param error : the reason of error */ - (void)nativeExpressRewardedVideoAd:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd didFailWithError:(NSError *_Nullable)error { [self trackRewardvodAdFailToLoadError:error]; } /** This method is called when cached successfully. For a better user experience, it is recommended to display video ads at this time. And you can call [BUNativeExpressRewardedVideoAd showAdFromRootViewController:]. */ - (void)nativeExpressRewardedVideoAdDidDownLoadVideo:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd { [self trackRewardvodAdVideoLoadSuccess]; _isReady = YES; } /** This method is called when rendering a nativeExpressAdView successed. It will happen when ad is show. */ - (void)nativeExpressRewardedVideoAdViewRenderSuccess:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd {} /** This method is called when a nativeExpressAdView failed to render. @param error : the reason of error */ - (void)nativeExpressRewardedVideoAdViewRenderFail:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd error:(NSError *_Nullable)error { [self trackRewardvodAdFailToPresentError:error]; } /** This method is called when video ad slot will be showing. */ - (void)nativeExpressRewardedVideoAdWillVisible:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd { [self trackRewardvodAdWillVisible]; } /** This method is called when video ad slot has been shown. */ - (void)nativeExpressRewardedVideoAdDidVisible:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd { [self trackRewardvodAdDidVisible]; } /** This method is called when video ad is about to close. */ - (void)nativeExpressRewardedVideoAdWillClose:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd {} /** This method is called when video ad is closed. */ - (void)nativeExpressRewardedVideoAdDidClose:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd { [self trackRewardvodAdDidClose]; } /** This method is called when video ad is clicked. */ - (void)nativeExpressRewardedVideoAdDidClick:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd { [self trackRewardvodAdDidClick]; } /** This method is called when the user clicked skip button. */ - (void)nativeExpressRewardedVideoAdDidClickSkip:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd {} /** This method is called when video ad play completed or an error occurred. @param error : the reason of error */ - (void)nativeExpressRewardedVideoAdDidPlayFinish:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd didFailWithError:(NSError *_Nullable)error { if(error){ [self trackRewardvodAdVideoFailToPlayError:error]; }else{ [self trackRewardvodAdDidPlayFinish]; } } /** Server verification which is requested asynchronously is succeeded. now include two v erify methods: 1. C2C need server verify 2. S2S don't need server verify @param verify :return YES when return value is 2000. */ - (void)nativeExpressRewardedVideoAdServerRewardDidSucceed:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd verify:(BOOL)verify { [self trackRewardVodAdDidRewardEffective]; if(verify){ [self trackRewardvodAdVideoAdServerRewardDidSucceedWithInfo:nil]; }else{ // 自定义 NSError *error = [[NSError alloc]initWithDomain:@"custom.adapter.error" code:22052 userInfo:@{NSLocalizedDescriptionKey : @"服务端验证失败,请服务端正确响应穿山甲服务端"}]; [self trackRewardvodAdVideoAdServerRewardDidFailed:error]; } } /** Server verification which is requested asynchronously is failed. @param rewardedVideoAd express rewardVideo Ad @param error request error info */ - (void)nativeExpressRewardedVideoAdServerRewardDidFail:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd error:(NSError *_Nullable)error { [self trackRewardvodAdVideoAdServerRewardDidFailed:error]; } /** This method is called when another controller has been closed. @param interactionType : open appstore in app or open the webpage or view video ad details page. */ - (void)nativeExpressRewardedVideoAdDidCloseOtherController:(BUNativeExpressRewardedVideoAd *)rewardedVideoAd interactionType:(BUInteractionType)interactionType { [self trackRewardvodAdLandingPageClosed]; } @end ``` ### 4.1.6 模板信息流 1. 需继承 `ADSuyiCustomAdapterNativeAd` 2. 通过以下方法子类进行调用 & 子类进行实现来完成适配 |
方法
|
参数说明
| |:-----------|:------| | -(void)trackNativeAdSucceedToLoadWithNativeAdViews:(NSArray *)nativeViews | 信息流请求成功 | | -(void)trackNativeAdFailToLoadWithError:(NSError * _Nullable)error | 信息流请求失败 | | -(void)trackNativeAdRenderSucceedWithNativeView:(ADSuyiCustomAdapterNativeAdView *)nativeView | 信息流广告渲染成功 | | -(void)trackNativeAdRenderFailedWithNativeView:(ADSuyiCustomAdapterNativeAdView *)nativeView | 信息流广告渲染失败 | | -(void)trackNativeAdExposuredWithNativeView:(ADSuyiCustomAdapterNativeAdView *)nativeView | 信息流广告展示 | | -(void)trackNativeAdClickedWithNativeView:(ADSuyiCustomAdapterNativeAdView *)nativeView | 信息流广告点击 | | -(void)trackNativeAdClosedWithNativeView:(ADSuyiCustomAdapterNativeAdView *)nativeView | 信息流广告关闭 | | -(void)trackNativeAdLandingPageClosedWithNativeView:(ADSuyiCustomAdapterNativeAdView *)nativeView | 信息流广告关闭落地页 | | **需子类实现:** | | | -(void)requestAdWithContext:(ADSuyiCustomAdapterNativeRequestContext *)context | 请求广告方法,必须于子类中实现 | 3. 需继承视图父类 `ADSuyiCustomAdapterNativeAdView` , 将模板信息流添加至统一视图中 ```objc @interface ADSuyiCustomAdapterNativeAdView : UIView @end ``` `ADSuyiAdapterNativeAdViewDelegate` |
方法
|
参数说明
| |:-----------|:------| | **需子类实现:** | | | -(void)adsy_registViews:(NSArray *)clickViews | 注册广告视图 | | -(void)adsy_unRegistView | 取消注册 | | -(void)adsy_close | 广告关闭事件,手动调用 | | -(void)adsy_closeButtonExist | 广告关闭按钮是否存在 | | -(ADSuyiAdapterRenderType)renderType | 渲染类型 | | -(ADSuyiAdapterNativeAdData *)data | 自渲染广告数据,模版类型为空 | | -(nullable UIView *)adsy_mediaViewForWidth:(CGFloat)width | 获取视频视图,如果是模版广告则为nil | | -(void)adsy_platformLogoImageDarkMode:(BOOL)darkMode loadImageBlock:(void(^)(UIImage * _Nullable))block | 平台logo | **demo示例:** `ADSuyiCustomAdapterBUNativeAd.h` ```objc #import @interface ADSuyiCustomAdapterBUNativeAd : ADSuyiCustomAdapterNativeAd @end ``` `ADSuyiCustomAdapterBUNativeAd.m` ```objc #import "ADSuyiCustomAdapterBUNativeAd.h" #import #import "ADSuyiCustomAdapterBUNativeAdView.h" @interface ADSuyiCustomAdapterBUNativeAd () { BUNativeExpressAdManager *_nativeExpressAd; NSMapTable *_weakMapTable; NSHashTable *_hashTable; ADSuyiCustomAdapterNativeRequestContext *_context; } @end @implementation ADSuyiCustomAdapterBUNativeAd // MARK: - Override + (void)load { [self registPlatformAdLoaderClass:self forSdkName:@"toutiao" renderType:(ADSuyiAdapterRenderTypeExpress)]; } - (instancetype)init{ self = [super init]; if(self){ _weakMapTable = [NSMapTable weakToWeakObjectsMapTable]; _hashTable = [NSHashTable new]; } return self; } - (void)requestAdWithContext:(ADSuyiCustomAdapterNativeRequestContext *)context { _context = context; if(!_nativeExpressAd) { BUAdSlot *slot = [BUAdSlot new]; slot.ID = context.posId; slot.AdType = BUAdSlotAdTypeFeed; slot.position = BUAdSlotPositionFeed; BUSize *imageSize = [BUSize sizeBy:BUProposalSize_Feed690_388]; slot.imgSize = imageSize; _nativeExpressAd = [[BUNativeExpressAdManager alloc] initWithSlot:slot adSize:CGSizeMake(context.adSize.width, 0)]; _nativeExpressAd.delegate = self; } [_nativeExpressAd loadAdDataWithCount:context.loadCount]; } // MARK: - Helper - (NSArray *)creatNativeViewFrom:(NSArray<__kindof BUNativeExpressAdView *> *)views { NSMutableArray *dataArray = [NSMutableArray new]; for (BUNativeExpressAdView *view in views) { ADSuyiCustomAdapterBUNativeAdView *nativeView = [ADSuyiCustomAdapterBUNativeAdView new]; nativeView.buNativeAdView = view; view.rootViewController = _context.viewController; [dataArray addObject:nativeView]; nativeView.delegate = self; [_weakMapTable setObject:nativeView forKey:view]; } return dataArray.copy; } // MARK: - BUNativeExpressAdViewDelegate /** * Sent when views successfully load ad */ - (void)nativeExpressAdSuccessToLoad:(BUNativeExpressAdManager *)nativeExpressAdManager views:(NSArray<__kindof BUNativeExpressAdView *> *)views { NSArray *adViewArray = [self creatNativeViewFrom:views]; [self trackNativeAdSucceedToLoadWithNativeAdViews:adViewArray]; } /** * Sent when views fail to load ad */ - (void)nativeExpressAdFailToLoad:(BUNativeExpressAdManager *)nativeExpressAdManager error:(NSError *_Nullable)error { [self trackNativeAdFailToLoadWithError:error]; } /** * This method is called when rendering a nativeExpressAdView successed, and nativeExpressAdView.size.height has been updated */ - (void)nativeExpressAdViewRenderSuccess:(BUNativeExpressAdView *)nativeExpressAdView { ADSuyiCustomAdapterBUNativeAdView *adView = [_weakMapTable objectForKey:nativeExpressAdView]; if(!adView)return; [_hashTable removeObject:adView]; adView.frame = nativeExpressAdView.bounds; [self trackNativeAdRenderSucceedWithNativeView:adView]; } /** * This method is called when a nativeExpressAdView failed to render */ - (void)nativeExpressAdViewRenderFail:(BUNativeExpressAdView *)nativeExpressAdView error:(NSError *_Nullable)error { ADSuyiCustomAdapterBUNativeAdView *adView = [_weakMapTable objectForKey:nativeExpressAdView]; if(!adView)return; [_hashTable removeObject:adView]; [self trackNativeAdRenderFailedWithNativeView:adView]; } /** * Sent when an ad view is about to present modal content */ - (void)nativeExpressAdViewWillShow:(BUNativeExpressAdView *)nativeExpressAdView { [self trackNativeAdExposuredWithNativeView:[_weakMapTable objectForKey:nativeExpressAdView]]; } /** * Sent when an ad view is clicked * */ - (void)nativeExpressAdViewDidClick:(BUNativeExpressAdView *)nativeExpressAdView { [self trackNativeAdClickedWithNativeView:[_weakMapTable objectForKey:nativeExpressAdView]]; } /** Sent when a playerw playback status changed. @param playerState : player state after changed */ - (void)nativeExpressAdView:(BUNativeExpressAdView *)nativeExpressAdView stateDidChanged:(BUPlayerPlayState)playerState { } /** * Sent when a player finished * @param error : error of player */ - (void)nativeExpressAdViewPlayerDidPlayFinish:(BUNativeExpressAdView *)nativeExpressAdView error:(NSError *)error { } /** * Sent when a user clicked dislike reasons. * @param filterWords : the array of reasons why the user dislikes the ad */ - (void)nativeExpressAdView:(BUNativeExpressAdView *)nativeExpressAdView dislikeWithReason:(NSArray *)filterWords { [self trackNativeAdClosedWithNativeView:[_weakMapTable objectForKey:nativeExpressAdView]]; } /** * Sent after an ad view is clicked, a ad landscape view will present modal content */ - (void)nativeExpressAdViewWillPresentScreen:(BUNativeExpressAdView *)nativeExpressAdView { } /** This method is called when another controller has been closed. @param interactionType : open appstore in app or open the webpage or view video ad details page. */ - (void)nativeExpressAdViewDidCloseOtherController:(BUNativeExpressAdView *)nativeExpressAdView interactionType:(BUInteractionType)interactionType { [self trackNativeAdLandingPageClosedWithNativeView:[_weakMapTable objectForKey:nativeExpressAdView]]; } /** This method is called when the Ad view container is forced to be removed. @param nativeExpressAdView : Ad view container */ - (void)nativeExpressAdViewDidRemoved:(BUNativeExpressAdView *)nativeExpressAdView { } -(void)adsyCustomNativeViewRenderSuccess:(ADSuyiCustomAdapterBUNativeAdView *)nativeView{ [_hashTable addObject:nativeView]; } @end ``` `ADSuyiCustomAdapterBUNativeAdView.h` ```objc #import #import @class ADSuyiCustomAdapterBUNativeAdView; @protocol ADSuyiCustomAdapterBUNativeViewDelegate - (void)adsyCustomNativeViewRenderSuccess:(ADSuyiCustomAdapterBUNativeAdView *)nativeView; @end @interface ADSuyiCustomAdapterBUNativeAdView : ADSuyiCustomAdapterNativeAdView /// 平台信息流广告视图 @property (nonatomic, strong) BUNativeExpressAdView *buNativeAdView; @property (nonatomic, weak) id delegate; @end ``` `ADSuyiCustomAdapterBUNativeAdView.m` ```objc #import "ADSuyiCustomAdapterBUNativeAdView.h" @interface ADSuyiCustomAdapterBUNativeAdView () @end @implementation ADSuyiCustomAdapterBUNativeAdView #pragma mark - setter - (void)setBuNativeAdView:(BUNativeExpressAdView *)buNativeAdView{ _buNativeAdView = buNativeAdView; [self addSubview:buNativeAdView]; } #pragma mark - ADSuyiAdapterNativeAdViewDelegate - (void)adsy_registViews:(NSArray *)clickViews { [self.buNativeAdView render]; [self.delegate adsyCustomNativeViewRenderSuccess:self]; } - (void)adsy_unRegistView { } - (ADSuyiAdapterRenderType)renderType { return ADSuyiAdapterRenderTypeExpress; } - (ADSuyiAdapterNativeAdData *)data { return nil; } - (nullable UIView *)adsy_mediaViewForWidth:(CGFloat)width { return nil; } - (BOOL)adsy_closeButtonExist { // 是否存在关闭按钮 return YES; } #pragma mark - ADSuyiAdViewInfoProtocol - (ADSuyiAdapterPlatform)adsy_platform { return @"toutiao"; } @end ``` ### 4.1.7 自渲染信息流 1. 需继承 `ADSuyiCustomAdapterUnifiedNativeAd` 2. 通过以下方法子类进行调用 & 子类进行实现来完成适配 |
方法
|
参数说明
| |:-----------|:------| | -(void)trackNativeAdSucceedToLoadWithNativeAdViews:(NSArray *>*)nativeViews | 信息流请求成功 | | -(void)trackNativeAdFailToLoadWithError:(NSError * _Nullable)error | 信息流请求失败 | | -(void)trackNativeAdRenderSucceedWithNativeView:(UIView *)nativeView | 信息流广告渲染成功 | | -(void)trackNativeAdRenderFailedWithNativeView:(UIView *)nativeView | 信息流广告渲染失败 | | -(void)trackNativeAdExposuredWithNativeView:(UIView *)nativeView | 信息流广告展示 | | -(void)trackNativeAdClickedWithNativeView:(UIView *)nativeView | 信息流广告点击 | | -(void)trackNativeAdClosedWithNativeView:(UIView *)nativeView | 信息流广告关闭 | | -(void)trackNativeAdLandingPageClosedWithNativeView:(UIView *)nativeView | 信息流广告关闭落地页 | | **需子类实现:** | | | -(void)requestAdWithContext:(ADSuyiCustomAdapterNativeRequestContext *)context | 请求广告方法,必须于子类中实现 | 3. 视图需遵循协议,并实现协议方法 `ADSuyiAdapterNativeAdViewDelegate` , 将模板信息流添加至统一视图中 **demo示例:** > 不同的平台实现方式不同,需根据平台进行适配,适配过程中有疑问,请联系技术同学提供支持 `ADSuyiCustomAdapterGDTUnifiedNativeAd.h` ```objc #import @interface ADSuyiCustomAdapterGDTUnifiedNativeAd : ADSuyiCustomAdapterUnifiedNativeAd @end ``` `ADSuyiCustomAdapterGDTUnifiedNativeAd.m` ```objc #import "ADSuyiCustomAdapterGDTUnifiedNativeAd.h" #import #import #import #import "ADSuyiCustomAdapterGDTUnifiedNativeAdView.h" @interface ADSuyiCustomAdapterGDTUnifiedNativeAd () { ADSuyiCustomAdapterNativeRequestContext *_context; GDTUnifiedNativeAd *_unifiedNativeAdAd; NSMapTable *_weakMap; } @end @implementation ADSuyiCustomAdapterGDTUnifiedNativeAd + (void)load { [self registPlatformAdLoaderClass:self forSdkName:@"gdt" renderType:(ADSuyiAdapterRenderTypeNative)]; } - (instancetype)init { self = [super init]; if (self) { _weakMap = [NSMapTable weakToWeakObjectsMapTable]; } return self; } // MARK: - Override - (void)requestAdWithContext:(ADSuyiCustomAdapterNativeRequestContext *)context { _context = context; [self.unifiedNativeAdAd loadAdWithAdCount:_context.loadCount]; } // MARK: - GDTUnifiedNativeAdDelegate - (void)gdt_unifiedNativeAdLoaded:(NSArray * _Nullable)unifiedNativeAdDataObjects error:(NSError * _Nullable)error { if(error) { [self trackNativeAdFailToLoadWithError:error]; return; } NSMutableArray *> *adViewArray = [NSMutableArray new]; for (GDTUnifiedNativeAdDataObject *dataObj in unifiedNativeAdDataObjects) { ADSuyiCustomAdapterGDTUnifiedNativeAdView *adView = [ADSuyiCustomAdapterGDTUnifiedNativeAdView new]; adView.adData = dataObj; adView.delegate = self; adView.unifiedNativeAdDelegate = self; adView.viewController = _context.viewController; [adViewArray addObject:adView]; [_weakMap setObject:adView forKey:dataObj]; adView.adData.videoConfig.videoMuted = YES; } [self trackNativeAdSucceedToLoadWithNativeAdViews:adViewArray]; } // MARK: - GDTUnifiedNativeAdViewDelegate - (void)gdt_unifiedNativeAdViewWillExpose:(GDTUnifiedNativeAdView *)unifiedNativeAdView { ADSuyiCustomAdapterGDTUnifiedNativeAdView *adView = [_weakMap objectForKey:unifiedNativeAdView.dataObject]; [self trackNativeAdExposuredWithNativeView:adView]; } - (void)gdt_unifiedNativeAdViewDidClick:(GDTUnifiedNativeAdView *)unifiedNativeAdView { ADSuyiCustomAdapterGDTUnifiedNativeAdView *adView = [_weakMap objectForKey:unifiedNativeAdView.dataObject]; [self trackNativeAdClickedWithNativeView:adView]; } - (void)gdt_unifiedNativeAdDetailViewClosed:(GDTUnifiedNativeAdView *)unifiedNativeAdView { ADSuyiCustomAdapterGDTUnifiedNativeAdView *adView = [_weakMap objectForKey:unifiedNativeAdView.dataObject]; [self trackNativeAdLandingPageClosedWithNativeView:adView]; } // MARK: - ADSuyiCustomAdapterUnifiedNativeAdViewDelegate - (void)adsyCustomUnifiedNativeAdViewRender:(ADSuyiCustomAdapterGDTUnifiedNativeAdView *)adView { [self trackNativeAdRenderSucceedWithNativeView:adView]; } - (void)adsyCustomUnifiedNativeAdViewClose:(ADSuyiCustomAdapterGDTUnifiedNativeAdView *)adView { [self trackNativeAdClosedWithNativeView:adView]; } // MARK: - Lazy load - (GDTUnifiedNativeAd *)unifiedNativeAdAd { if(!_unifiedNativeAdAd) { _unifiedNativeAdAd = [[GDTUnifiedNativeAd alloc] initWithPlacementId:_context.posId]; _unifiedNativeAdAd.delegate = self; } return _unifiedNativeAdAd; } @end ``` `ADSuyiCustomAdapterGDTUnifiedNativeAdView.h` ```objc #import #import #import #import @class ADSuyiCustomAdapterGDTUnifiedNativeAdView; @protocol ADSuyiCustomAdapterGDTUnifiedNativeAdViewDelegate - (void)adsyCustomUnifiedNativeAdViewRender:(ADSuyiCustomAdapterGDTUnifiedNativeAdView *)adView; - (void)adsyCustomUnifiedNativeAdViewClose:(ADSuyiCustomAdapterGDTUnifiedNativeAdView *)adView; @end @interface ADSuyiCustomAdapterGDTUnifiedNativeAdView : GDTUnifiedNativeAdView @property (nonatomic, strong) GDTUnifiedNativeAdDataObject *adData; @property (nonatomic, weak) id unifiedNativeAdDelegate; @end ``` `ADSuyiCustomAdapterGDTUnifiedNativeAdView.m` ```objc #import "ADSuyiCustomAdapterGDTUnifiedNativeAdView.h" @interface ADSuyiAdapterNativeAdData() - (instancetype)initWithTitle:(NSString *)title content:(NSString *)content imageUrlStringArray:(NSArray *)imageUrlStringArray iconImage:(nullable UIImage *)iconImage iconImageUrl:(nullable NSString *)iconImageUrl shouldShowMediaView:(BOOL)shouldShowMediaView; @end @interface ADSuyiCustomAdapterGDTUnifiedNativeAdView () { ADSuyiAdapterNativeAdData *_data; CGFloat _width; } @end @implementation ADSuyiCustomAdapterGDTUnifiedNativeAdView #pragma mark - ADSuyiAdapterNativeAdViewDelegate - (void)adsy_registViews:(NSArray *)clickViews { [self registerDataObject:_adData clickableViews:clickViews]; if([self.delegate respondsToSelector:@selector(adsyCustomUnifiedNativeAdViewRender:)]) { [self.unifiedNativeAdDelegate adsyCustomUnifiedNativeAdViewRender:self]; } } - (ADSuyiAdapterNativeAdData *)data { return _data; } - (nullable UIView *)adsy_mediaViewForWidth:(CGFloat)width { [self.mediaView muteEnable:YES]; return self.mediaView; } - (void)adsy_platformLogoImageDarkMode:(BOOL)darkMode loadImageBlock:(void (^)(UIImage * _Nullable))block { if (!block) { return; } block(nil); } - (ADSuyiAdapterRenderType)renderType { return ADSuyiAdapterRenderTypeNative; } - (void)adsy_unRegistView { [self unregisterDataObject]; } - (void)adsy_close { [self.unifiedNativeAdDelegate adsyCustomUnifiedNativeAdViewClose:self]; } - (BOOL)adsy_closeButtonExist { return NO; } #pragma mark - Set - (void)setAdData:(GDTUnifiedNativeAdDataObject *)adData { _adData = adData; NSArray *imageUrlStringArray = @[]; if(_adData.imageUrl) { imageUrlStringArray = @[_adData.imageUrl]; } _data = [[ADSuyiAdapterNativeAdData alloc] initWithTitle:_adData.title content:_adData.desc imageUrlStringArray:imageUrlStringArray iconImage:nil iconImageUrl:_adData.iconUrl shouldShowMediaView:_adData.isVideoAd]; } #pragma mark - ADSuyiAdViewInfoProtocol - (ADSuyiAdapterPlatform)adsy_platform { return @"gdt"; } @end ``` ### 4.1.8 竞价 > 已 gdt 开屏为例子 |
方法
|
参数说明
| |:-----------|:------| | -(void)splashAdViewBiddingByPrice:(double)eCPM | 三方平台竞价广告询价请求成功时,子类适配器中调用方法
eCPM: 分 | | -(void)splashAdViewBiddingByError:(NSError *)error | 三方平台竞价广告询价请求失败时,子类适配器中调用方法 | | **需子类实现:** | | | -(void)biddingRequestWithContext:(ADSuyiCustomAdapterSplashRequestContext *)context | 竞价询价请求 | | -(void)biddingResult:(ADSuyiSDKSourceBiddingResult)result AllPrice:(NSArray *)allPrices | 竞价结果,该方法内实现仅处理三方竞价结果上报即可
allPrices: 分 | **demo示例:** `ADSuyiCustomAdapterGDTBiddingSplashAd.h` ```objc #import /// GDT 支持 Bidding 的写法 @interface ADSuyiCustomAdapterGDTBiddingSplashAd : ADSuyiCustomAdapterSplashAd @end ``` `ADSuyiCustomAdapterGDTBiddingSplashAd.m` ```objc #import "ADSuyiCustomAdapterGDTBiddingSplashAd.h" #import @interface ADSuyiCustomAdapterGDTBiddingSplashAd() @property (nonatomic, assign) bool isLoadSuccess;/**< 加载是否成功,该字段是为了处理gdt的失败回调 */ @property (nonatomic, strong) ADSuyiCustomAdapterSplashRequestContext *context; @property (nonatomic, strong) GDTSplashAd *splashAd; @end @implementation ADSuyiCustomAdapterGDTBiddingSplashAd + (void)load { [self registPlatformAdLoaderClass:self forSdkName:ADSuyiAdapterPlatformGDT renderType:ADSuyiAdapterRenderTypeExpress]; } /// 请求 - (void)requestAdWithContext:(ADSuyiCustomAdapterSplashRequestContext *)context{ _context = context; [self request:context]; } /// !!!: 竞价:询价请求 - (void)biddingRequestWithContext:(ADSuyiCustomAdapterSplashRequestContext *)context{ _context = context; [self request:context]; } /// !!!: 竞价:竞价结果,该方法内实现仅处理三方广告竞价结果上报即可 - (void)biddingResult:(ADSuyiSDKSourceBiddingResult)result AllPrice:(NSArray *)allPrices{ // 获取一价二价 NSNumber *winnerPrice = 0; NSNumber *secondPrice = 0; if (allPrices.count > 0) { NSNumber *firstPrice = allPrices.firstObject; // 聚合平台存储为单位为:分,GDT 是以元返回,同时也需要已元上报 winnerPrice = [NSNumber numberWithFloat:firstPrice.floatValue * 100]; } if (allPrices.count > 1) { NSNumber *tempSecondPrice = allPrices[1]; secondPrice = [NSNumber numberWithFloat:tempSecondPrice.floatValue * 100]; } switch (result) { case ADSuyiSDKSourceBiddingResult_Sucess: [self sendWinNotificationWithWinnerPrice:[NSNumber numberWithInteger:_splashAd.eCPM] withSecondPrice:secondPrice]; break; case ADSuyiSDKSourceBiddingResult_Failed: [self sendLossNotificationWithPrice:winnerPrice withRease:GDTAdBiddingLossReasonLowPrice withWinnerAdnID:@""]; break; case ADSuyiSDKSourceBiddingResult_Timeout: [self sendLossNotificationWithPrice:0 withRease:GDTAdBiddingLossReasonNoAd withWinnerAdnID:@""]; break; default: [self sendLossNotificationWithPrice:0 withRease:GDTAdBiddingLossReasonOther withWinnerAdnID:@""]; break; } } /// 展示 - (void)customAdapter_onAdReceive{ [_splashAd showAdInWindow:_context.window withBottomView:_context.bottomView skipView:_context.skipView]; } // MARK: - Method - (void)request:(ADSuyiCustomAdapterSplashRequestContext *)context{ _splashAd = [[GDTSplashAd alloc] initWithPlacementId:context.posId]; _splashAd.delegate = self; _splashAd.serverSideVerificationOptions = [[GDTServerSideVerificationOptions alloc]init]; if (context.userId){ _splashAd.serverSideVerificationOptions.userIdentifier = context.userId; } if (context.extra){ _splashAd.serverSideVerificationOptions.customRewardString = context.extra; } [_splashAd loadAd]; } /** 竞赢上报 * infoDic 字典类型,支持的key有 * GDT_M_W_E_COST_PRICE:竞胜价格 (单位: 分),值类型为NSNumber * * GDT_M_W_H_LOSS_PRICE:最高失败出价,值类型为NSNumber * */ - (void)sendWinNotificationWithWinnerPrice:(NSNumber *)winnerPrice withSecondPrice:(NSNumber *)secondPrice{ if(winnerPrice == nil){ return ; } NSMutableDictionary *infoDic = [NSMutableDictionary dictionary]; [infoDic setValue:winnerPrice forKey:GDT_M_W_E_COST_PRICE]; if (secondPrice != nil) { [infoDic setValue:secondPrice forKey:GDT_M_W_H_LOSS_PRICE]; }else{ [infoDic setValue:@(0) forKey:GDT_M_W_H_LOSS_PRICE]; } [_splashAd sendWinNotificationWithInfo:infoDic.copy]; } /** * 竞败之后或未参竞调用 * * infoDic 竞败信息,字典类型,支持的key有 * GDT_M_L_WIN_PRICE :竞胜价格 (单位: 分),值类型为NSNumber *,选填 * GDT_M_L_LOSS_REASON :优量汇广告竞败原因,竞败原因参考枚举GDTAdBiddingLossReason中的定义,值类型为NSNumber *,必填 * GDT_M_ADNID :竞胜方渠道ID,值类型为NSString *,必填 */ - (void)sendLossNotificationWithPrice:(NSNumber *)price withRease:(GDTAdBiddingLossReason)reason withWinnerAdnID:(NSString *)winnerAdnID{ NSMutableDictionary *infoDic = [NSMutableDictionary dictionary]; [infoDic setValue:price forKey:GDT_M_L_WIN_PRICE]; [infoDic setValue:@(reason) forKey:GDT_M_L_LOSS_REASON]; [infoDic setValue:winnerAdnID forKey:GDT_M_ADNID]; [_splashAd sendLossNotificationWithInfo:infoDic.copy]; } // MARK: - GDTSplashAdDelegate - (void)splashAdSuccessPresentScreen:(GDTSplashAd *)splashAd { [self trackSplashAdSuccessToPresent]; } - (void)splashAdDidLoad:(GDTSplashAd *)splashAd { _isLoadSuccess = YES; NSInteger price = _splashAd.eCPM; [self trackSplashAdSucceed:price/100.00]; } - (void)splashAdFailToPresent:(GDTSplashAd *)splashAd withError:(NSError *)error { // gdt 的失败回调特殊处理,加载成功之后调用失败,则说明广告数据加载成功,可能是present失败,所以属于展示失败,展示失败直接返回失败 if(_isLoadSuccess) { [self trackSplashAdFailedToPresentWithError:error]; // 直接失败,说明广告数据加载失败,属于请求失败么,请求失败轮询下一个平台 } else { [self trackSplashAdFailedWithError:error]; } } // 跳转其他页面也当作关闭处理 - (void)splashAdApplicationWillEnterBackground:(GDTSplashAd *)splashAd { [self splashAdClosed:splashAd]; } - (void)splashAdExposured:(GDTSplashAd *)splashAd { [self trackSplashAdDisplay]; } - (void)splashAdClicked:(GDTSplashAd *)splashAd { [self trackSplashAdClicked]; } - (void)splashAdClosed:(GDTSplashAd *)splashAd { [self trackSplashAdClosed]; } - (void)splashAdDidDismissFullScreenModal:(GDTSplashAd *)splashAd { [self trackSplashAdLandingPageClosed]; } -(void)splashAdDidRewardEffective:(GDTSplashAd *)splashAd info:(NSDictionary *)info{ [self trackSplashAdDidRewardEffective:info]; } @end ```