맞춤 네이티브 광고 형식

맞춤 광고 형식

시스템 정의 대응 항목처럼 맞춤 네이티브 광고 형식은 GADAdLoader 객체를 통해 로드됩니다. GADAdLoader를 초기화할 때 adTypes 배열에 GADAdLoaderAdTypeCustomNative 상수를 넣으면 광고를 로드할 때 맞춤 네이티브 형식을 요청하도록 구성됩니다.

GADCustomNativeAdLoaderDelegate

맞춤 형식을 로드하는 프로토콜에는 두 가지 메서드가 있습니다. 첫 번째는 GADAdLoader에서 사용하며, 요청해야 하는 형식 ID를 확인할 때 사용됩니다.

Swift

public func customNativeAdFormatIDs(for adLoader: GADAdLoader) -> [Any]

Objective-C

- (NSArray *)customNativeAdFormatIDsForAdLoader:(GADAdLoader *)adLoader;

모든 맞춤 네이티브 광고 형식에는 이를 식별하는 형식 ID가 있습니다. 이 메서드가 호출되면, 표시하도록 준비된 광고의 형식 ID가 포함된 배열을 앱에서 반환해야 합니다.

두 번째 메시지는 맞춤 네이티브 광고가 로드될 때 전송되며, 시스템 정의 형식과 유사합니다.

Swift

public func adLoader(_ adLoader: GADAdLoader,
    didReceive customNativeAd: GADCustomNativeAd)

Objective-C

- (void)adLoader:(GADAdLoader *)adLoader
    didReceiveCustomNativeAd:(GADCustomNativeAd *)customNativeAd;

형식 ID

맞춤 네이티브 광고 형식을 고유하게 참조할 때 사용되는 형식 ID는 Ad Manager UI에 접속한 후 게재 드롭다운 안에 있는 네이티브 섹션에서 확인할 수 있습니다.

맞춤 네이티브 광고의 형식 ID가 각 이름 옆에 표시됩니다. 이름 중 하나를 클릭하면 형식 필드에 대한 정보를 표시하는 세부정보 화면이 나타납니다.

여기에서 개별 필드를 추가, 수정, 삭제할 수 있습니다. 각 애셋의 이름을 기록합니다. 이름은 맞춤 네이티브 광고 형식을 표시할 때 각 애셋의 데이터를 가져오는 데 사용되는 키입니다.

맞춤 네이티브 광고 형식 표시

맞춤 네이티브 광고 형식은 게시자가 광고를 구성하는 애셋 목록을 정의할 수 있다는 점에서 시스템 정의 광고 형식과 다릅니다. 따라서 맞춤 네이티브 광고 형식의 표시 방법은 여러 측면에서 시스템 정의 형식과 다릅니다.

  1. GADCustomNativeAd는 직접 생성한 맞춤 네이티브 광고 형식을 처리하기 위한 것이므로 명명된 애셋 접근자가 없습니다. 대신 필드의 이름을 인수로 사용하는 imageForKey:, stringForKey: 등의 메서드를 제공합니다.
  2. GADCustomNativeAd와 함께 사용하는 광고 뷰 전용 클래스(예: GADNativeAdView)는 없습니다. 사용자 환경에 적합한 뷰를 자유롭게 사용할 수 있습니다.
  3. 광고 뷰 전용 클래스가 없으므로 광고 애셋을 표시하는 데 사용하는 뷰를 등록하지 않아도 됩니다.

다음은 간단한 맞춤 네이티브 광고를 표시할 수 있는 광고 뷰의 예입니다.

MySimpleNativeAdView.h

Swift

import UIKit
import GoogleMobileAds

/// Custom native ad view class with format ID 10063170.
class MySimpleNativeAdView: UIView {

  /// Weak references to this ad's asset views.
  @IBOutlet weak var headlineView: UILabel!
  @IBOutlet weak var mainImageView: UIImageView!
  @IBOutlet weak var captionView: UILabel!

  ...

  /// Populates the ad view with the custom native ad object.
  func populateWithCustomNativeAd(_ customNativeAd: GADCustomNativeAd) {
    ...
  }
}

Objective-C

@import UIKit;
@import GoogleMobileAds;

/// View representing a custom native ad format with format ID 10063170.
@interface MySimpleNativeAdView : UIView

// Weak references to this ad's asset views.
@property(weak, nonatomic) IBOutlet UILabel *headlineView;
@property(weak, nonatomic) IBOutlet UIImageView *mainImageView;
@property(weak, nonatomic) IBOutlet UILabel *captionView;

/// Populates the ad view with the custom native ad object.
- (void)populateWithCustomNativeAd:(GADCustomNativeAd *)customNativeAd;

@end

MySimpleNativeAdView.m (발췌)

Swift

...
func populateWithCustomNativeAd(_ customNativeAd: GADCustomNativeAd) {
  self.customNativeAd = customNativeAd

  // Populate the custom native ad assets.
  headlineView.text = self.customNativeAd.stringForKey("Headline")
  mainImageView.image = self.customNativeAd.imageForKey("MainImage")?.image
  captionView.text = self.customNativeAd.stringForKey("Caption")
}
...

Objective-C

...
- (void)populateWithCustomNativeAd:(GADCustomNativeAd *)customNativeAd {
  self.customNativeAd = customNativeAd;

  // Populate the custom native ad assets.
  self.headlineView.text = [customNativeAd stringForKey:@"Headline"];
  self.mainImageView.image = [customNativeAd imageForKey:@"MainImage"].image;
  self.captionView.text = [customNativeAd stringForKey:@"Caption"];
}
...

AdChoices 아이콘 렌더링

디지털 서비스법 (DSA) 지원의 일환으로 유럽 경제 지역 (EEA)에서 게재되는 예약 광고에는 AdChoices 아이콘과 Google의 광고 수신 정보 페이지로 연결되는 링크가 필요합니다. 맞춤 네이티브 광고를 구현할 때는 AdChoices 아이콘을 렌더링해야 합니다. 기본 광고 확장 소재를 렌더링할 때는 AdChoices 아이콘에 대한 클릭 리스너를 렌더링하고 설정하는 것이 중요합니다.

다음 예에서는 AdChoices 아이콘을 렌더링하고 적절한 클릭 동작을 구성합니다.

Swift

class MySimpleNativeAdView: UIView {
  @IBOutlet weak var adChoicesView: UIImageView!

  override func awakeFromNib() {
    super.awakeFromNib()

    // Enable clicks on AdChoices.
    adChoicesView.addGestureRecognizer(
      UITapGestureRecognizer(
        target: self,
        action: #selector(performClickOnAdChoices(_:))))
    adChoicesView.isUserInteractionEnabled = true
  }

  @objc func performClickOnAdChoices(_ sender: UIImage!) {
    customNativeAd.performClickOnAsset(withKey:
      GADNativeAssetIdentifier.adChoicesViewAsset.rawValue)
  }

  func populate(withCustomNativeAd customNativeAd: GADCustomNativeAd) {

    // Render the AdChoices image.
    let adChoicesKey = GADNativeAssetIdentifier.adChoicesViewAsset.rawValue
    let adChoicesImage = customNativeAd.image(forKey: adChoicesKey)?.image
    adChoicesView.image = adChoicesImage
    adChoicesView.isHidden = adChoicesImage == nil
    ...
  }
}

Objective-C

@interface MySimpleNativeAdView ()

@property(nonatomic, weak) IBOutlet UIImageView *adChoicesView;

@end

@implementation MySimpleNativeAdView

- (void)awakeFromNib {
  [super awakeFromNib];
  // Enable clicks on AdChoices.
  [self.adChoicesView addGestureRecognizer:[[UITapGestureRecognizer alloc]
                                            initWithTarget:self
                                            action:@selector(performClickOnAdChoices:)]];
  self.adChoicesView.userInteractionEnabled = YES;
}

- (void)performClickOnAdChoices:(UITapGestureRecognizer *)sender {
    [self.customNativeAd performClickOnAssetWithKey:GADNativeAdChoicesViewAsset];
}

- (void)populateWithCustomNativeAd:(GADCustomNativeAd *)customNativeAd {
  // Render the AdChoices image.
  GADNativeAdImage *adChoicesAsset = [customNativeAd
    imageForKey:GADNativeAdChoicesViewAsset];
  self.adChoicesView.image = adChoicesAsset.image;
  self.adChoicesView.hidden = (adChoicesAsset == nil);
  ...
}

맞춤 네이티브 광고 형식을 위한 네이티브 동영상

맞춤 형식을 만들 때 형식을 동영상에 적합하게 만들 수 있습니다.

앱 구현에서 GADCustomNativeAd.mediaView 속성을 사용하여 동영상의 보기를 가져올 수 있습니다. 그런 다음 이 뷰를 뷰 계층 구조에 추가하세요. 광고에 동영상 콘텐츠가 없으면 동영상 없이 광고를 표시하는 대체 계획을 세우세요.

다음은 광고에 동영상 콘텐츠가 있는지 확인하고 동영상을 사용할 수 없는 경우 대신 이미지를 표시하는 방법의 예입니다.

Swift

...
  /// Populates the ad view with the custom native ad object.
  func populate(withCustomNativeAd customNativeAd: GADCustomNativeAd) {
    if customNativeAd.videoController.hasVideoContent(),
      let mediaView = customNativeAd.mediaView {
      updateMainView(mediaView)
    } else {
      // Assumes your native format has an image asset with the name MainImage.
      let image: UIImage? = customNativeAd.image(forKey: "MainImage")?.image
      updateMainView(UIImageView(image: image))
    }
  }

  private func updateMainView(_ mainView:UIView) {
    // Assumes you have a placeholder view for your media content.
    // Remove all the placeholder's subviews.
    for subview: UIView in mainPlaceholder.subviews {
      subview.removeFromSuperview()
    }
    mainPlaceholder.addSubview(mainView)
    // Size the media view to fill our container size.
    mainView.translatesAutoresizingMaskIntoConstraints = false
    let viewDictionary: [AnyHashable: Any] = ["mainView":mainView]
    mainPlaceholder.addConstraints(NSLayoutConstraint.constraints(
      withVisualFormat: "H:|[mainView]|", options: [], metrics: nil,
      views: viewDictionary as? [String : Any] ?? [String : Any]()))
    mainPlaceholder.addConstraints(NSLayoutConstraint.constraints(
      withVisualFormat: "V:|[mainView]|", options: [], metrics: nil,
      views: viewDictionary as? [String : Any] ?? [String : Any]()))
  }
...

Objective-C

...
- (void)populateWithCustomNativeAd:(GADCustomNativeAd *)ad {
  UIView *mainView = nil;
  if (ad.videoController.hasVideoContent) {
    mainView = ad.mediaView;
  } else {
    // Assumes your native format has an image asset with the name MainImage.
    UIImage *image = [ad imageForKey:@"MainImage"].image;
    mainView = [[UIImageView alloc] initWithImage:image];
  }
  // Assumes you have a placeholder view for your media content.
  for (UIView *subview in self.mainPlaceholder.subviews) {
    [subview removeFromSuperview];
  }
  [self.mainPlaceholder addSubview:mainView];

  // Size the main view to fill our container size.
  [mainView setTranslatesAutoresizingMaskIntoConstraints:NO];
  NSDictionary *viewDictionary = NSDictionaryOfVariableBindings(mainView);
  [self.mainPlaceholder
      addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[mainView]|"
                                                             options:0
                                                             metrics:nil
                                                               views:viewDictionary]];
}
...

맞춤 네이티브 광고의 동영상 환경을 맞춤설정하는 방법에 관한 자세한 내용은 GADVideoController를 참고하세요.

실제 사용 중인 네이티브 동영상의 작동 예시를 보려면 Ad Manager 맞춤 렌더링 예시를 다운로드하세요.

맞춤 네이티브 광고 클릭 및 노출 처리

맞춤 네이티브 광고 형식의 경우 앱이 노출을 기록하고 SDK에 클릭 이벤트를 보고합니다.

노출 기록

맞춤 네이티브 광고의 노출을 기록하려면 해당 GADCustomNativeAd에서 recordImpression 메서드를 호출하세요.

Swift

myCustomNativeAd.recordImpression()

Objective-C

[myCustomNativeAd recordImpression];

앱에서 동일한 광고에 대해 메서드를 실수로 여러 번 호출한 경우 SDK는 단일 요청에 대해 중복 노출이 기록되지 않게 합니다.

클릭 보고

애셋 뷰에서 클릭이 발생했음을 SDK에 보고하려면 해당 GADCustomNativeAd에서 performClickOnAssetWithKey: 메서드를 호출하고 클릭한 애셋의 이름을 전달하세요. 예를 들어 맞춤 형식에 'MainImage'라는 애셋이 있으며, 이 애셋에 해당하는 뷰에 대한 클릭을 보고하려는 경우 다음과 같은 코드를 사용할 수 있습니다.

Swift

myCustomNativeAd.performClickOnAsset(withKey: "MainImage")

Objective-C

[myCustomNativeAd performClickOnAssetWithKey:@"MainImage"];

광고와 연결된 일부 애셋 뷰에 대해서는 이 메서드를 호출하지 않아도 됩니다. 예를 들어 표시할 다른 애셋인 'Caption'이 있지만 사용자가 이 애셋을 클릭하거나 탭하지 않은 경우에는 앱에서 해당 뷰에 대해 performClickOnAssetWithKey:를 호출하지 않아도 됩니다.

맞춤 클릭 액션에 응답

GADCustomNativeAd에는 유형이 GADNativeAdCustomClickHandlercustomClickHandler 속성이 있습니다.

Swift

typealias GADNativeAdCustomClickHandler = (assetID: String) -> Void

Objective-C

typedef void (^GADNativeAdCustomClickHandler)(NSString *assetID);

assetID를 클릭이 발생한 애셋을 식별하는 입력 매개변수로 허용하는 블록 (Objective-C) / 클로저 (Swift)입니다.

맞춤 네이티브 광고를 클릭하면 SDK에서 세 가지 가능한 응답이 다음 순서대로 시도됩니다.

  1. Objective-C에서 customClickHandler 블록 또는 Swift에서 클로저(설정된 경우)를 호출합니다.
  2. 광고의 딥 링크 URL을 반복하고 일치하는 앱이 있는 첫 번째 URL을 엽니다.
  3. 브라우저를 열고 광고의 기존 도착 URL로 이동합니다.

customClickHandler 속성은 Objective-C의 블록과 Swift의 클로저를 허용합니다. 블록 또는 클로저를 설정하면 SDK에서 이를 실행하고 더 이상의 조치를 취하지 않습니다. 그러나 nil 값을 설정하면 SDK가 광고에 등록된 딥 링크 또는 도착 URL로 되돌아갑니다.

맞춤 클릭 핸들러를 사용하면 UI 업데이트, 다른 뷰 컨트롤러 표시 또는 단순한 클릭 기록 등에 관계없이 앱이 클릭에 대한 응답으로 취할 수 있는 최상의 조치를 스스로 결정할 수 있습니다. 다음은 알림을 보여주는 예입니다.

Swift

myCustomNativeAd.customClickHandler = { assetID in
  if assetID == "MainImage" {
    let alertView = UIAlertView(title: "Custom Click",
        message: "You just clicked on the image!",
        delegate: self,
        cancelButtonTitle: "OK")
    alertView.alertViewStyle = .default
    alertView.show()
  }
}
myCustomNativeAd.performClickOnAsset(withKey: "MainImage")

Objective-C

[self.customNativeAd setCustomClickHandler:^(NSString *assetID){
  if ([assetID isEqualToString:@"MainImage"]) {
    [[[UIAlertView alloc] initWithTitle:@"Custom Click"
                                message:@"You just clicked on the image!"
                               delegate:self
                      cancelButtonTitle:@"OK"
                      otherButtonTitles:nil] show];
  }
}];
[self.customNativeAd performClickOnAssetWithKey:@"MainImage"];

네이티브 광고 코드 테스트

직접 판매 광고

직접 판매된 네이티브 광고가 어떤 광고인지 테스트하고 싶다면 아래의 Ad Manager 광고 단위 ID를 사용해 보세요.

/21775744923/example/native

이 ID는 샘플 앱 설치 및 콘텐츠 광고는 물론 다음 애셋이 포함된 맞춤 네이티브 광고 형식으로 게재하도록 구성되었습니다.

  • 광고 제목 (텍스트)
  • 기본 이미지 (이미지)
  • 캡션 (텍스트)

네이티브 백업 광고

네이티브 백업 광고의 작동을 테스트하려면 다음과 같은 Ad Manager 광고 단위를 사용하세요.

/21775744923/example/native-backfill

이 광고 단위에서는 샘플 앱 설치를 제공하고 AdChoices 오버레이가 적용된 콘텐츠 광고를 게재합니다.

광고 단위를 게시하기 전에 실제 광고 단위 및 형식 ID를 참조하도록 코드를 업데이트해야 합니다.