IMA SDK 설정

플랫폼 선택: HTML5 Android iOS tvOS

IMA SDK를 사용하면 멀티미디어 광고를 웹사이트와 앱에 쉽게 통합할 수 있습니다. IMA SDK는 VAST 호환 광고 서버에서 광고를 요청하고 앱에서 광고 재생을 관리할 수 있습니다. IMA 클라이언트 측 SDK를 사용하면 콘텐츠 동영상 재생을 제어할 수 있으며 SDK가 광고 재생을 처리합니다. 광고는 앱의 콘텐츠 동영상 플레이어 위에 배치된 별도의 동영상 플레이어에서 재생됩니다.

이 가이드에서는 IMA SDK를 동영상 플레이어 앱에 통합하는 방법을 보여줍니다. 완료된 샘플 통합을 확인하거나 따라 하려면 GitHub에서 BasicExample을 다운로드하세요.

IMA 클라이언트 측 개요

IMA 클라이언트 측 구현에는 이 가이드에 설명된 네 가지 주요 SDK 구성요소가 필요합니다.

  • IMAAdDisplayContainer: IMA가 광고 UI 요소를 렌더링하고 Active ViewOpen Measurement를 비롯한 조회가능성을 측정하는 위치를 지정하는 컨테이너 객체입니다.
  • IMAAdsLoader: 광고를 요청하고 광고 요청 응답의 이벤트를 처리하는 객체입니다. 애플리케이션 수명 동안 재사용할 수 있는 광고 로더를 하나만 인스턴스화해야 합니다.
  • IMAAdsRequest: 광고 요청을 정의하는 객체입니다. 광고 요청은 VAST 광고 태그의 URL과 광고 크기와 같은 추가 매개변수를 지정합니다.
  • IMAAdsManager: 광고 요청에 대한 응답을 포함하고, 광고 재생을 제어하며, SDK에서 발생한 광고 이벤트를 수신하는 객체입니다.

기본 요건

시작하기 전에 다음이 필요합니다.

1. 새 Xcode 프로젝트 만들기

Xcode에서 Objective-C 또는 Swift를 사용하여 새 iOS 프로젝트를 만듭니다. BasicExample을 프로젝트 이름으로 사용합니다.

2. Xcode 프로젝트에 IMA SDK 추가

CocoaPods는 Xcode 프로젝트의 종속 항목 관리자이며 IMA SDK를 설치하는 데 권장되는 방법입니다. CocoaPods 설치 또는 사용에 대한 자세한 내용은 CocoaPods 문서를 참고하세요. CocoaPods를 설치한 후 다음 안내에 따라 IMA SDK를 설치합니다.

  1. BasicExample.xcodeproj 파일과 동일한 디렉터리에 Podfile이라는 텍스트 파일을 만들고 다음 구성을 추가합니다.

    Objective-C

    source 'https://github.com/CocoaPods/Specs.git'
    
    platform :ios, '12'
    
    target "BasicExample" do
      pod 'GoogleAds-IMA-iOS-SDK', '~> 3.26.1'
    end
    
    

    Swift

    source 'https://github.com/CocoaPods/Specs.git'
    
    platform :ios, '12'
    
    target "BasicExample" do
      pod 'GoogleAds-IMA-iOS-SDK', '~> 3.26.1'
    end
    
    
  2. Podfile이 포함된 디렉터리에서 pod install --repo-update를 실행합니다.

  3. BasicExample.xcworkspace 파일을 열고 BasicExamplePods (CocoaPods에서 설치한 종속 항목)라는 두 프로젝트가 포함되어 있는지 확인하여 설치가 성공했는지 확인합니다.

Swift Package Manager를 사용하여 SDK 설치

양방향 미디어 광고 SDK는 버전 3.18.4부터 Swift Package Manager를 지원합니다. Swift 패키지를 가져오려면 다음 단계를 완료하세요.

  1. Xcode에서 File(파일) > Add Package Dependencies(패키지 종속 항목 추가)...로 이동하여 IMA SDK Swift 패키지를 설치합니다.

  2. 메시지에서 IMA iOS SDK Swift 패키지 GitHub 저장소(swift-package-manager-google-interactive-media-ads-ios)를 검색합니다.

  3. 사용할 IMA SDK Swift 패키지의 버전을 선택합니다. 새 프로젝트의 경우 Up to Next Major Version(최대 다음 메이저 버전)을 사용하는 것이 좋습니다.

작업을 완료하면 Xcode에서 패키지 종속 항목을 확인하고 백그라운드에서 다운로드합니다. 패키지 종속 항목을 추가하는 방법에 대한 자세한 내용은 Apple 도움말을 참고하세요.

SDK 수동 다운로드 및 설치

Swift Package Manager 또는 CocoaPods를 사용하지 않으려면 IMA SDK를 다운로드하여 프로젝트에 수동으로 추가하면 됩니다.

3. 동영상 플레이어 만들기

먼저 동영상 플레이어를 구현합니다. 처음에 이 플레이어는 IMA SDK를 사용하지 않으며 재생을 트리거하는 메서드를 포함하지 않습니다.

Objective-C

플레이어 종속 항목을 가져옵니다.

#import "ViewController.h"

@import AVFoundation;

플레이어 변수를 설정합니다.

@interface ViewController () <IMAAdsLoaderDelegate, IMAAdsManagerDelegate>

/// Content video player.
@property(nonatomic, strong) AVPlayer *contentPlayer;

/// Play button.
@property(nonatomic, weak) IBOutlet UIButton *playButton;

/// UIView in which we will render our AVPlayer for content.
@property(nonatomic, weak) IBOutlet UIView *videoView;

뷰가 로드될 때 동영상 플레이어를 시작합니다.

@implementation ViewController

// The content URL to play.
NSString *const kTestAppContentUrl_MP4 =
    @"https://storage.googleapis.com/gvabox/media/samples/stock.mp4";

// Ad tag
NSString *const kTestAppAdTagUrl = @"https://pubads.g.doubleclick.net/gampad/ads?"
  @"iu=/21775744923/external/single_ad_samples&sz=640x480&cust_params=sample_ct%3Dlinear&"
  @"ciu_szs=300x250%2C728x90&gdfp_req=1&output=vast&unviewed_position_start=1&env=vp&"
  @"correlator=";

- (void)viewDidLoad {
  [super viewDidLoad];

  self.playButton.layer.zPosition = MAXFLOAT;

  [self setupAdsLoader];
  [self setUpContentPlayer];
}

#pragma mark Content Player Setup

- (void)setUpContentPlayer {
  // Load AVPlayer with path to our content.
  NSURL *contentURL = [NSURL URLWithString:kTestAppContentUrl_MP4];
  self.contentPlayer = [AVPlayer playerWithURL:contentURL];

  // Create a player layer for the player.
  AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.contentPlayer];

  // Size, position, and display the AVPlayer.
  playerLayer.frame = self.videoView.layer.bounds;
  [self.videoView.layer addSublayer:playerLayer];

  // Set up our content playhead and contentComplete callback.
  self.contentPlayhead = [[IMAAVPlayerContentPlayhead alloc] initWithAVPlayer:self.contentPlayer];
  [[NSNotificationCenter defaultCenter] addObserver:self
                                           selector:@selector(contentDidFinishPlaying:)
                                               name:AVPlayerItemDidPlayToEndTimeNotification
                                             object:self.contentPlayer.currentItem];
}

- (IBAction)onPlayButtonTouch:(id)sender {
  [self requestAds];
  self.playButton.hidden = YES;
}

Swift

플레이어 종속 항목을 가져옵니다.

import AVFoundation

플레이어 변수를 설정합니다.

class PlayerContainerViewController: UIViewController, IMAAdsLoaderDelegate, IMAAdsManagerDelegate {
  static let contentURL = URL(
    string: "https://storage.googleapis.com/gvabox/media/samples/stock.mp4")!

  private var contentPlayer = AVPlayer(url: PlayerContainerViewController.contentURL)

  private lazy var playerLayer: AVPlayerLayer = {
    AVPlayerLayer(player: contentPlayer)
  }()

뷰가 로드될 때 동영상 플레이어를 시작합니다.

private lazy var videoView: UIView = {
  let videoView = UIView()
  videoView.translatesAutoresizingMaskIntoConstraints = false
  view.addSubview(videoView)

  NSLayoutConstraint.activate([
    videoView.bottomAnchor.constraint(
      equalTo: view.safeAreaLayoutGuide.bottomAnchor),
    videoView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
    videoView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
    videoView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
  ])
  return videoView
}()

// MARK: - View controller lifecycle methods

override func viewDidLoad() {
  super.viewDidLoad()

  videoView.layer.addSublayer(playerLayer)
  adsLoader.delegate = self

  NotificationCenter.default.addObserver(
    self,
    selector: #selector(contentDidFinishPlaying(_:)),
    name: .AVPlayerItemDidPlayToEndTime,
    object: contentPlayer.currentItem)
}

override func viewDidAppear(_ animated: Bool) {
  super.viewDidAppear(animated)
  playerLayer.frame = videoView.layer.bounds
}

override func viewWillTransition(
  to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator
) {
  coordinator.animate { _ in
    // do nothing
  } completion: { _ in
    self.playerLayer.frame = self.videoView.layer.bounds
  }
}

// MARK: - Public methods

func playButtonPressed() {
  requestAds()
}

4. IMA SDK 가져오기

IMA SDK를 가져오려면 다음 단계를 따르세요.

Objective-C

  1. IMA SDK를 가져옵니다.

    @import GoogleInteractiveMediaAds;
    
  2. 앱에서 사용되는 IMAAdsLoader, IMAAVPlayerContentPlayhead, IMAAdsManager 클래스의 변수를 만듭니다.

    // SDK
    /// Entry point for the SDK. Used to make ad requests.
    @property(nonatomic, strong) IMAAdsLoader *adsLoader;
    
    /// Playhead used by the SDK to track content video progress and insert mid-rolls.
    @property(nonatomic, strong) IMAAVPlayerContentPlayhead *contentPlayhead;
    
    /// Main point of interaction with the SDK. Created by the SDK as the result of an ad request.
    @property(nonatomic, strong) IMAAdsManager *adsManager;
    

Swift

  1. IMA SDK를 가져옵니다.

    import GoogleInteractiveMediaAds
    
    
  2. 앱에서 사용되는 IMAAdsLoader, IMAAVPlayerContentPlayhead, IMAAdsManager 클래스의 변수를 만듭니다.

    static let adTagURLString =
      "https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/"
      + "single_ad_samples&sz=640x480&cust_params=sample_ct%3Dlinear&ciu_szs=300x250%2C728x90&"
      + "gdfp_req=1&output=vast&unviewed_position_start=1&env=vp&correlator="
    
    private let adsLoader = IMAAdsLoader()
    private var adsManager: IMAAdsManager?
    
    private lazy var contentPlayhead: IMAAVPlayerContentPlayhead = {
      IMAAVPlayerContentPlayhead(avPlayer: contentPlayer)
    }()
    

5. 콘텐츠 재생 헤드 추적기 및 스트림 종료 관찰자 구현

미드롤 광고를 재생하려면 IMA SDK가 동영상 콘텐츠의 현재 위치를 추적해야 합니다. 이렇게 하려면 IMAContentPlayhead를 구현하는 클래스를 만듭니다. 이 예에 표시된 대로 AVPlayer를 사용하는 경우 SDK는 이를 실행하는 IMAAVPlayerContentPlayhead 클래스를 제공합니다. AVPlayer를 사용하지 않는 경우 자체 클래스에서 IMAContentPlayhead를 구현해야 합니다.

또한 콘텐츠 재생이 완료되면 SDK가 포스트롤 광고를 표시할 수 있도록 SDK에 알려야 합니다. 이 작업은 AVPlayerItemDidPlayToEndTimeNotification을 사용하여 IMAAdsLoader에서 contentComplete 메서드를 호출하여 실행됩니다.

Objective-C

플레이어 설정에서 IMAAVPlayerContentPlayhead 인스턴스를 만듭니다.

// Set up our content playhead and contentComplete callback.
self.contentPlayhead = [[IMAAVPlayerContentPlayhead alloc] initWithAVPlayer:self.contentPlayer];
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(contentDidFinishPlaying:)
                                             name:AVPlayerItemDidPlayToEndTimeNotification
                                           object:self.contentPlayer.currentItem];

콘텐츠 재생이 완료되면 IMAAdsLoader.contentComplete()를 호출하는 contentDidFinishPlaying() 메서드를 만듭니다.

- (void)contentDidFinishPlaying:(NSNotification *)notification {
  // Make sure we don't call contentComplete as a result of an ad completing.
  if (notification.object == self.contentPlayer.currentItem) {
    [self.adsLoader contentComplete];
  }
}

Swift

플레이어 설정에서 콘텐츠 종료 관찰자를 만듭니다.

NotificationCenter.default.addObserver(
  self,
  selector: #selector(contentDidFinishPlaying(_:)),
  name: .AVPlayerItemDidPlayToEndTime,
  object: contentPlayer.currentItem)

콘텐츠 재생이 완료되면 IMAAdsLoader.contentComplete()를 호출하는 contentDidFinishPlaying() 메서드를 만듭니다.

@objc func contentDidFinishPlaying(_ notification: Notification) {
  // Make sure we don't call contentComplete as a result of an ad completing.
  if notification.object as? AVPlayerItem == contentPlayer.currentItem {
    adsLoader.contentComplete()
  }
}

6. 광고 로더를 초기화하고 광고 요청하기

광고 세트를 요청하려면 IMAAdsLoader 인스턴스를 만들어야 합니다. 이 로더는 지정된 광고 태그 URL과 연결된 IMAAdsRequest 객체를 처리하는 데 사용할 수 있습니다.

앱의 전체 수명 주기에 대해 IMAAdsLoader 인스턴스를 하나만 유지하는 것이 좋습니다. 추가 광고 요청을 하려면 새 IMAAdsRequest 객체를 만들되 동일한 IMAAdsLoader를 재사용하세요. 자세한 내용은 IMA SDK FAQ를 참고하세요.

Objective-C

- (void)setupAdsLoader {
  self.adsLoader = [[IMAAdsLoader alloc] initWithSettings:nil];
  self.adsLoader.delegate = self;
}

- (void)requestAds {
  // Create an ad display container for ad rendering.
  IMAAdDisplayContainer *adDisplayContainer =
      [[IMAAdDisplayContainer alloc] initWithAdContainer:self.videoView
                                          viewController:self
                                          companionSlots:nil];
  // Create an ad request with our ad tag, display container, and optional user context.
  IMAAdsRequest *request = [[IMAAdsRequest alloc] initWithAdTagUrl:kTestAppAdTagUrl
                                                adDisplayContainer:adDisplayContainer
                                                   contentPlayhead:self.contentPlayhead
                                                       userContext:nil];
  [self.adsLoader requestAdsWithRequest:request];
}

Swift

private func requestAds() {
  // Create ad display container for ad rendering.
  let adDisplayContainer = IMAAdDisplayContainer(
    adContainer: videoView, viewController: self, companionSlots: nil)
  // Create an ad request with our ad tag, display container, and optional user context.
  let request = IMAAdsRequest(
    adTagUrl: PlayerContainerViewController.adTagURLString,
    adDisplayContainer: adDisplayContainer,
    contentPlayhead: contentPlayhead,
    userContext: nil)

  adsLoader.requestAds(with: request)
}

7. 광고 로더 대리자 설정

로드 이벤트가 성공하면 IMAAdsLoader가 할당된 대리자의 adsLoadedWithData 메서드를 호출하여 IMAAdsManager 인스턴스를 전달합니다. 그런 다음 광고 태그 URL에 대한 응답에 정의된 대로 개별 광고를 로드하는 광고 관리자를 초기화할 수 있습니다.

또한 로드 프로세스 중에 발생할 수 있는 오류를 처리해야 합니다. 광고가 로드되지 않으면 사용자의 환경을 방해하지 않도록 광고 없이 미디어 재생이 계속되도록 해야 합니다.

Objective-C

- (void)adsLoader:(IMAAdsLoader *)loader adsLoadedWithData:(IMAAdsLoadedData *)adsLoadedData {
  // Grab the instance of the IMAAdsManager and set ourselves as the delegate.
  self.adsManager = adsLoadedData.adsManager;
  self.adsManager.delegate = self;
  // Create ads rendering settings to tell the SDK to use the in-app browser.
  IMAAdsRenderingSettings *adsRenderingSettings = [[IMAAdsRenderingSettings alloc] init];
  adsRenderingSettings.linkOpenerPresentingController = self;
  // Initialize the ads manager.
  [self.adsManager initializeWithAdsRenderingSettings:adsRenderingSettings];
}

- (void)adsLoader:(IMAAdsLoader *)loader failedWithErrorData:(IMAAdLoadingErrorData *)adErrorData {
  // Something went wrong loading ads. Log the error and play the content.
  NSLog(@"Error loading ads: %@", adErrorData.adError.message);
  [self.contentPlayer play];
}

Swift

func adsLoader(_ loader: IMAAdsLoader, adsLoadedWith adsLoadedData: IMAAdsLoadedData) {
  // Grab the instance of the IMAAdsManager and set ourselves as the delegate.
  adsManager = adsLoadedData.adsManager
  adsManager?.delegate = self

  // Create ads rendering settings and tell the SDK to use the in-app browser.
  let adsRenderingSettings = IMAAdsRenderingSettings()
  adsRenderingSettings.linkOpenerPresentingController = self

  // Initialize the ads manager.
  adsManager?.initialize(with: adsRenderingSettings)
}

func adsLoader(_ loader: IMAAdsLoader, failedWith adErrorData: IMAAdLoadingErrorData) {
  if let message = adErrorData.adError.message {
    print("Error loading ads: \(message)")
  }
  contentPlayer.play()
}

8. 광고 관리자 위임 설정

마지막으로 이벤트와 상태 변경을 관리하려면 광고 관리자에게 자체 위임자가 필요합니다. IMAAdManagerDelegate에는 광고 이벤트와 오류를 처리하는 메서드와 동영상 콘텐츠의 재생 및 일시중지를 트리거하는 메서드가 있습니다.

재생 시작

LOADED 이벤트를 수신 대기하여 콘텐츠와 광고의 재생을 시작합니다. 자세한 내용은 didReceiveAdEvent를 참고하세요.

Objective-C

- (void)adsManager:(IMAAdsManager *)adsManager didReceiveAdEvent:(IMAAdEvent *)event {
  // When the SDK notified us that ads have been loaded, play them.
  if (event.type == kIMAAdEvent_LOADED) {
    [adsManager start];
  }
}

Swift

func adsManager(_ adsManager: IMAAdsManager, didReceive event: IMAAdEvent) {
  // When the SDK notifies us the ads have been loaded, play them.
  if event.type == IMAAdEventType.LOADED {
    adsManager.start()
  }
}

오류 처리

광고 오류 핸들러도 추가합니다. 이전 단계와 같이 오류가 발생하면 콘텐츠 재생을 재개합니다.

Objective-C

- (void)adsManager:(IMAAdsManager *)adsManager didReceiveAdError:(IMAAdError *)error {
  // Something went wrong with the ads manager after ads were loaded. Log the error and play the
  // content.
  NSLog(@"AdsManager error: %@", error.message);
  [self.contentPlayer play];
}

Swift

func adsManager(_ adsManager: IMAAdsManager, didReceive error: IMAAdError) {
  // Something went wrong with the ads manager after ads were loaded.
  // Log the error and play the content.
  if let message = error.message {
    print("AdsManager error: \(message)")
  }
  contentPlayer.play()
}

재생 및 일시중지 이벤트 수신 대기

구현해야 하는 마지막 두 개의 위임 메서드는 IMA SDK에서 요청할 때 기본 동영상 콘텐츠에서 재생 및 일시중지 이벤트를 트리거하는 데 사용됩니다. 요청 시 일시중지 및 재생을 트리거하면 광고가 표시될 때 사용자가 동영상 콘텐츠의 일부를 놓치지 않습니다.

Objective-C

- (void)adsManagerDidRequestContentPause:(IMAAdsManager *)adsManager {
  // The SDK is going to play ads, so pause the content.
  [self.contentPlayer pause];
}

- (void)adsManagerDidRequestContentResume:(IMAAdsManager *)adsManager {
  // The SDK is done playing ads (at least for now), so resume the content.
  [self.contentPlayer play];
}

Swift

func adsManagerDidRequestContentPause(_ adsManager: IMAAdsManager) {
  // The SDK is going to play ads, so pause the content.
  contentPlayer.pause()
}

func adsManagerDidRequestContentResume(_ adsManager: IMAAdsManager) {
  // The SDK is done playing ads (at least for now), so resume the content.
  contentPlayer.play()
}

작업이 끝났습니다. 이제 IMA SDK를 사용하여 광고를 요청하고 표시합니다. 추가 SDK 기능에 대해 알아보려면 다른 가이드나 GitHub의 샘플을 참고하세요.

다음 단계

iOS 플랫폼에서 광고 수익을 극대화하려면 IDFA를 사용하기 위해 앱 투명성 및 추적 권한을 요청하세요.