設定 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 廣告代碼的網址,以及廣告尺寸等其他參數。
  • IMAAdsManager: 這個物件包含廣告請求的回應、控管廣告播放,並監聽 SDK 觸發的廣告事件。

必要條件

開始之前,請先備妥下列項目:

1. 建立新的 Xcode 專案

在 Xcode 中,使用 Objective-C 或 Swift 建立新的 iOS 專案。使用「BasicExample」BasicExample做為專案名稱。

2. 將 IMA SDK 新增至 Xcode 專案

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 檔案,確認其中包含兩個專案:「BasicExample」和「Pods」 (CocoaPods 安裝的依附元件),即可確認安裝是否成功。

使用 Swift Package Manager 安裝 SDK

互動式媒體廣告 SDK 從 3.18.4 版開始支援 Swift Package Manager。如要匯入 Swift 套件,請完成下列步驟:

  1. 在 Xcode 中,依序前往「File」>「Add Package Dependencies...」,安裝 IMA SDK Swift Package。

  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. 為應用程式中使用的 IMAAdsLoaderIMAAVPlayerContentPlayheadIMAAdsManager 類別建立變數:

    // 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. 為應用程式中使用的 IMAAdsLoaderIMAAVPlayerContentPlayheadIMAAdsManager 類別建立變數:

    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 內容播放完畢的時間,以便顯示片尾廣告。方法是在 IMAAdsLoader 上呼叫 contentComplete 方法,並使用 AVPlayerItemDidPlayToEndTimeNotification

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];

建立 contentDidFinishPlaying() 方法,在內容播放完畢時呼叫 IMAAdsLoader.contentComplete()

- (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)

建立 contentDidFinishPlaying() 方法,在內容播放完畢時呼叫 IMAAdsLoader.contentComplete()

@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 例項。 這個載入器可用於處理與指定廣告代碼網址相關聯的 IMAAdsRequest 物件。

最佳做法是,在整個應用程式生命週期中,只維護一個 IMAAdsLoader 例項。如要提出額外的廣告請求,請建立新的 IMAAdsRequest 物件,但重複使用相同的 IMAAdsLoader。詳情請參閱 IMA SDK 常見問題

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 的執行個體。接著,您可以初始化廣告管理工具,載入廣告代碼網址回應中定義的個別廣告。

此外,請務必處理載入程序中可能發生的任何錯誤。如果廣告無法載入,請確保媒體播放作業會繼續進行 (不含廣告),以免干擾使用者體驗。

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 平台上的廣告收益,請要求應用程式追蹤透明度權限,以便使用廣告識別碼