Mopub Mediation Native

出自TAMedia
於 2017年7月14日 (五) 10:43 由 imported>Wikiuser 所做的修訂
跳至導覽 跳至搜尋

官方教學:連結
NativeAd需要建立4個客製化class來串接廣告

回MoPub教學

TAMediaTAMediaCustomNativeAdEventAdapter

1.建立一class實做MPNativeAdAdapter protocol,protocol有兩必須實作property:properties及defaultActionURL,此class是作為Tamedia native ad與MPNativeAd的橋樑
2.建立初始化方法,將Tamedia native ad拿到的dictionary作為參數帶入,將帶入的dictionary與MPNativeAdConstants.h提供的key值建立相對應的dictionary後賦予給prooerties
3.defaultActionURL則為Tamedia拿到的nurl
4.實作displayContentForURL:rootViewController:completion:當user點擊時觸發
參考以下代碼

  //  TAMediaTAMediaCustomNativeAdEventAdapter.h
  #import <Foundation/Foundation.h>
  #import "MPNativeAdAdapter.h"
  #import "TADNativeAd.h"
  
  @interface TAMediaTAMediaCustomNativeAdEventAdapter : NSObject <MPNativeAdAdapter>
  
  - (instancetype)initWithTADic:(NSDictionary *)taDic;
  
  @property (nonatomic, readonly) NSDictionary *properties;
  @property (nonatomic, readonly) NSURL *defaultActionURL;
  @end
  //  TAMediaTAMediaCustomNativeAdEventAdapter.m
  #import "TAMediaTAMediaCustomNativeAdEventAdapter.h"
  #import "MPNativeAdConstants.h"
  
  @interface TAMediaTAMediaCustomNativeAdEventAdapter ()   
  @end
  
  @implementation TAMediaTAMediaCustomNativeAdEventAdapter 
  
  - (instancetype)initWithTADic:(NSDictionary *)taDic {
      self = [super init];
      NSDictionary *taMeidaDicMapping = @{@"LONGSUBJECT":kAdTitleKey,
                                          @"BODY":kAdTextKey,
                                          @"ICONSQUARE":kAdIconImageKey,
                                          @"IMAGE1280X720":kAdMainImageKey,
                                          @"VIDEO":kVASTVideoKey,
                                          @"nurl":kDefaultActionURLKey,
                                          @"IMAGE960X640":@"IMAGE960X640",
                                          @"IMAGE1200X627":@"IMAGE1200X627",
                                          @"ICONRECTANGLE":@"ICONRECTANGLE",
                                          @"SHORTSUBJECT":@"SHORTSUBJECT",
                                          @"IMAGE720X1280":@"IMAGE720X1280",
                                          @"IMAGE640X960":@"IMAGE640X960"};
      
      NSMutableDictionary *dic = [NSMutableDictionary new];
      for (NSString *key in taDic.allKeys) {
          [dic setObject:taDic[key] forKey:taMeidaDicMapping[key]];
      }
      _properties = dic;
      _defaultActionURL = [NSURL URLWithString:taDic[@"nurl"]];
      return self;
  }
  
  - (void)displayContentForURL:(NSURL *)URL rootViewController:(UIViewController *)controller {    
      [[UIApplication sharedApplication] openURL:URL];
  }
  @end

TAMediaTAMediaCustomNativeAdEventSetting

此class需實做MPNativeAdRendererSettings protocol,用來設定 viewSize,與指定需要來呈現的View,亦可用MPNativeAdRendererSettings取代

  //  TAMediaTAMediaCustomNativeAdEventSetting.h
  #import <Foundation/Foundation.h>
  #import "MPNativeAdRendererSettings.h"
  @interface TAMediaTAMediaCustomNativeAdEventSetting : NSObject <MPNativeAdRendererSettings>
  
  @property (nonatomic, assign) Class renderingViewClass;
  
  @property (nonatomic, readwrite, copy) MPNativeViewSizeHandler viewSizeHandler;
  @end
  //  TAMediaTAMediaCustomNativeAdEventSetting.m
  #import "TAMediaTAMediaCustomNativeAdEventSetting.h"
  @implementation TAMediaTAMediaCustomNativeAdEventSetting
  @end


TAMediaCustomNativeAdRenderer

此class需實做MPNativeAdRenderer protocol,用於回傳所需要的AdView以及設置客製化事件處理的class
1.實作+ (MPNativeAdRendererConfiguration *)rendererConfigurationWithRendererSettings:(id<MPNativeAdRendererSettings>)rendererSettings建立MPNativeAdRendererConfiguration物件
2.設置rendering class為本身class
3.設置rendererSettings為參數傳入的rendererSettings
4.設置supportedCustomEvents為TAMediaCustomNativeAdEvent class
5.實作initWithRendererSettings:設置物件viewSizeHandler,以及任何客製化設定
6.實作retrieveViewWithAdapter:回傳要來呈顯在畫面上的View
參考以下代碼

  //  TAMediaCustomNativeAdRenderer.h
  #import <Foundation/Foundation.h>
  #import "MPNativeAdRenderer.h"
  @interface TAMediaCustomNativeAdRenderer : NSObject <MPNativeAdRenderer>
  
  @property (nonatomic, readonly) MPNativeViewSizeHandler viewSizeHandler;
  
  @end
  //  TAMediaCustomNativeAdRenderer.m
  #import "TAMediaCustomNativeAdRenderer.h"
  #import "MPNativeAdRendererConfiguration.h"
  #import "MPNativeAdRendererSettings.h"
  #import "MPNativeAdRendering.h"
  #import "MPNativeAdAdapter.h"
  #import "MPNativeAdConstants.h"
  #import "MPNativeAdView.h"
  #import "MPNativeAdRendererImageHandler.h"
  #import "MPNativeAdRenderingImageLoader.h"
  
  @interface TAMediaCustomNativeAdRenderer() <MPNativeAdRendererImageHandlerDelegate>
  
  @property (nonatomic,strong) id<MPNativeAdRendererSettings>setting;
  
  @property (nonatomic,strong) MPNativeAdRendererImageHandler *rendererImageHandler;
  
  @end
   
  @implementation TAMediaCustomNativeAdRenderer
  
  + (MPNativeAdRendererConfiguration *)rendererConfigurationWithRendererSettings:(id<MPNativeAdRendererSettings>)rendererSettings {
      MPNativeAdRendererConfiguration *config = [[MPNativeAdRendererConfiguration alloc] init];
      config.rendererSettings = rendererSettings;
      config.supportedCustomEvents = @[@"TAMediaCustomNativeAdEvent"];//設置客製化事件處理的class
      config.rendererClass = [self class];
      return config;
  }
  
  - (instancetype)initWithRendererSettings:(id<MPNativeAdRendererSettings>)rendererSettings {
      self = [super init];
      _viewSizeHandler = [rendererSettings.viewSizeHandler copy];
      self.setting = rendererSettings;
      self.rendererImageHandler = [MPNativeAdRendererImageHandler new];
      self.rendererImageHandler.delegate = self;
      return self;
  }
  
  - (UIView *)retrieveViewWithAdapter:(id<MPNativeAdAdapter>)adapter error:(NSError **)error {
      UIView<MPNativeAdRendering> *adView = [MPNativeAdView new];
      //MPNativeAdRendering potocol設置的項目
      adView.nativeTitleTextLabel.text = adapter.properties[kAdTitleKey];
      adView.nativeMainTextLabel.text = adapter.properties[kAdTextKey];
      [self.rendererImageHandler loadImageForURL:[NSURL URLWithString:[adapter.properties objectForKey:kAdIconImageKey]] intoImageView:adView.nativeIconImageView];
      [self.rendererImageHandler loadImageForURL:[NSURL URLWithString:[adapter.properties objectForKey:kAdMainImageKey]] intoImageView:adView.nativeMainImageView];
      
      //MPNativeAdRendering potocol以外的項目用以下方式設置
      MPNativeAdRenderingImageLoader *imageLoader = [[MPNativeAdRenderingImageLoader alloc] initWithImageHandler:self.rendererImageHandler];
      [adView layoutCustomAssetsWithProperties:adapter.properties imageLoader:imageLoader];
      return adView;
  }
  
  - (BOOL)nativeAdViewInViewHierarchy
  {
      return YES;
  }
  @end

TAMediaCustomNativeAdEvent

此class需繼承MPNativeCustomEvent,用來取得Tamedia native ad提供給MoPub
1.建立class繼承MPNativeCustomEvent
2.複寫 - (void)requestAdWithCustomEventInfo:(NSDictionary *)info在此用TADNativeAd去取得廣告
3.取得廣告後用取得的Dictionary建立TAMediaTAMediaCustomNativeAdEventAdapter後再用adapter建立MPNativeAd
4.呈現廣告前先呼叫父類別precacheImagesWithURLs:completionBlock:取得image後,再呼叫customNativeEvent:didLoadAd:

  //  TAMediaCustomNativeAdEvent.h
  #import "MPNativeCustomEvent.h"
  #import "TADNativeAd.h"
  
  @interface TAMediaCustomNativeAdEvent : MPNativeCustomEvent <TADNativeAdDelegate> {
      TADNativeAd *nativeAd;
  }
  @end
  //  TAMediaCustomNativeAdEvent.m
  #import "TAMediaCustomNativeAdEvent.h"
  #import "TAMediaTAMediaCustomNativeAdEventAdapter.h"
  #import "MPNativeAdConstants.h"
  #import "MPNativeAd.h"
  #import "MPNativeAdError.h"
  
  @implementation TAMediaCustomNativeAdEvent
  
  - (void)requestAdWithCustomEventInfo:(NSDictionary *)info {
      TADRequest *request = [TADRequest request];
      request.testing = NO;
      // Type: TADGender
      request.gender = kTADGenderUnknown;
      
      // Set birthday
      [request setBirthdayWithYear:1988 month:6 day:11];
      
      // Set location
      [request setLocationWithLatitude:25.033534 longitude:121.534791 accuracy:1];
      // NAD 物件初始化, 帶入自訂的origin
      if (!nativeAd) {
          nativeAd = [[TADNativeAd alloc] initWithAdUnitId:info[@"NativeId"]];//NativeId在MoPub內設定
      }
      // 必須要設定delegate
      nativeAd.delegate = self;
      // 載入廣告
      [nativeAd loadRequest:request];
  }
  
  - (void)nativeAdDidReceiveAd:(TADNativeAd *)ad {
      // 表示本次請求收到廣告, 藉由 getNativeAdContent 取得包含回覆內容的 NSDictionary
      NSDictionary *nadDic = [nativeAd getNativeAdContent];  
      TAMediaTAMediaCustomNativeAdEventAdapter *adapter = [[TAMediaTAMediaCustomNativeAdEventAdapter alloc] initWithTADic:nadDic];
      MPNativeAd *mpNativeAd = [[MPNativeAd alloc] initWithAdAdapter:adapter];
      NSMutableArray *imageURLs = [NSMutableArray array];
      for (NSString *key in nadDic.allKeys) {
       if ([[key lowercaseString] hasPrefix:@"image"] || [key hasPrefix:@"ICON"]) {
           if (nadDic[key] && ![nadDic[key] isEqualToString:@""]) {
               NSURL *url = [NSURL URLWithString:nadDic[key]];
               [imageURLs addObject:url];
           }            
       }
   }
      //在呼叫delegate didloadAd前先將圖片預載
      [super precacheImagesWithURLs:imageURLs completionBlock:^(NSArray *errors) {
          if (errors) {            
              [self.delegate nativeCustomEvent:self didFailToLoadAdWithError:MPNativeAdNSErrorForImageDownloadFailure()];
          } else {
              [self.delegate nativeCustomEvent:self didLoadAd:mpNativeAd];
          }
      }];
  }
  
  - (void)nativeAd:(TADNativeAd *)ad didFailToReceiveAdWithError:(TADRequestError *)error {
      if ([self.delegate respondsToSelector:@selector(nativeCustomEvent:didFailToLoadAdWithError:)]) {
          [self.delegate nativeCustomEvent:self didFailToLoadAdWithError:error];
      }
  }
  
  - (void)dealloc {
      if (nativeAd != nil) {
          nativeAd.delegate = nil;
          nativeAd = nil;
      }
  }
  @end