הגדרת IMA SDK

בחירת פלטפורמה: HTML5 Android iOS tvOS

ערכות IMA SDK מאפשרות לשלב בקלות מודעות מולטימדיה באתרים ובאפליקציות. ‫IMA SDK יכול לשלוח בקשות להצגת מודעות מכל שרת מודעות שתואם ל-VAST ולנהל את הפעלת המודעות באפליקציות שלכם. עם IMA SDK בצד הלקוח, אתם שומרים על שליטה בהפעלת תוכן הווידאו, בזמן שה-SDK מטפל בהפעלת המודעות. המודעות מוצגות בנגן וידאו נפרד שממוקם מעל נגן הווידאו של תוכן האפליקציה.

במדריך הזה מוסבר איך לשלב את IMA SDK באפליקציה של נגן וידאו. כדי לראות או לעקוב אחרי שילוב לדוגמה, אפשר להוריד את BasicExample מ-GitHub.

סקירה כללית על IMA בצד הלקוח

הטמעה של IMA בצד הלקוח כוללת ארבעה רכיבי SDK עיקריים. במדריך הזה מוצגים הרכיבים הבאים:

  • ‫ IMAAdDisplayContainer: אובייקט מאגר שמציין איפה IMA מעבד רכיבי ממשק משתמש של מודעות ומודד את הניראות, כולל Active View ו-Open Measurement.
  • ‫ IMAAdsLoader: אובייקט שמבקש מודעות ומטפל באירועים מתשובות לבקשות להצגת מודעות. צריך ליצור מופע אחד בלבד של ads loader, שאפשר להשתמש בו שוב במהלך הפעילות של האפליקציה.
  • ‫ IMAAdsRequest: אובייקט שמגדיר בקשה להצגת מודעות. בבקשות להצגת מודעות מצוינת כתובת ה-URL של תג המודעה בפורמט VAST, וגם פרמטרים נוספים כמו מידות המודעה.
  • ‫ IMAAdsManager: אובייקט שמכיל את התגובה לבקשת המודעות, שולט בהפעלת המודעות ומאזין לאירועי מודעות שהופעלו על ידי ה-SDK.

דרישות מוקדמות

לפני שמתחילים, צריך:

1. יצירת פרויקט חדש ב-Xcode

ב-Xcode, יוצרים פרויקט tvOS חדש באמצעות Objective-C או Swift. משתמשים ב-BasicExample כשם הפרויקט.

2. הוספת IMA SDK לפרויקט Xcode

כדי להתקין את IMA SDK, בוחרים את השיטה המועדפת.

מומלץ: התקנת IMA SDK באמצעות Swift Package Manager

החל מגרסה 4.8.2,‏ Interactive Media Ads SDK תומך ב-Swift Package Manager. כדי לייבא את חבילת Swift, פועלים לפי השלבים הבאים.

  1. ב-Xcode, מתקינים את חבילת IMA SDK Swift על ידי מעבר אל File > Add Packages... (קובץ > הוספת חבילות...).

  2. בהנחיה שמופיעה, מחפשים את מאגר IMA SDK Swift Package GitHub:

    https://github.com/googleads/swift-package-manager-google-interactive-media-ads-tvos
    
  3. בוחרים את הגרסה של IMA SDK Swift Package שרוצים להשתמש בה. לפרויקטים חדשים, מומלץ להשתמש באפשרות עד הגרסה הראשית הבאה.

אחרי שתסיימו, פלטפורמת Xcode תטפל ביחסי התלות שבחבילה ותוריד אותם ברקע. פרטים נוספים על הוספת יחסי תלות בחבילה זמינים במאמר של Apple.

הורדה והתקנה ידניות של IMA SDK

אם אתם לא רוצים להשתמש ב-Swift Package Manager, אתם יכולים להוריד את IMA SDK ולהוסיף אותו לפרויקט באופן ידני.

3. ייבוא של IMA SDK

מוסיפים את מסגרת IMA באמצעות הצהרת ייבוא.

Objective-C

#import "ViewController.h"
#import <AVKit/AVKit.h>

@import GoogleInteractiveMediaAds;

Swift

import AVFoundation
import GoogleInteractiveMediaAds
import UIKit

4. יצירת נגן וידאו ושילוב של IMA SDK

בדוגמה הבאה מוצג אתחול של IMA SDK:

Objective-C

NSString *const kContentURLString =
    @"https://storage.googleapis.com/interactive-media-ads/media/stock.mp4";
NSString *const kAdTagURLString =
    @"https://pubads.g.doubleclick.net/gampad/ads?"
    @"iu=/21775744923/external/vmap_ad_samples&sz=640x480&"
    @"cust_params=sample_ar%3Dpremidpostlongpod&ciu_szs=300x250&gdfp_req=1&ad_rule=1&"
    @"output=vmap&unviewed_position_start=1&env=vp&cmsid=496&vid=short_onecue&correlator=";

@interface ViewController () <IMAAdsLoaderDelegate, IMAAdsManagerDelegate>
@property(nonatomic) IMAAdsLoader *adsLoader;
@property(nonatomic) IMAAdDisplayContainer *adDisplayContainer;
@property(nonatomic) IMAAdsManager *adsManager;
@property(nonatomic) IMAAVPlayerContentPlayhead *contentPlayhead;
@property(nonatomic) AVPlayerViewController *contentPlayerViewController;
@property(nonatomic, getter=isAdBreakActive) BOOL adBreakActive;
@end

@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];
  self.view.backgroundColor = [UIColor blackColor];
  [self setupAdsLoader];
  [self setupContentPlayer];
}

- (void)viewDidAppear:(BOOL)animated {
  [super viewDidAppear:animated];
  [self requestAds];
}

// Add the content video player as a child view controller.
- (void)showContentPlayer {
  [self addChildViewController:self.contentPlayerViewController];
  self.contentPlayerViewController.view.frame = self.view.bounds;
  [self.view insertSubview:self.contentPlayerViewController.view atIndex:0];
  [self.contentPlayerViewController didMoveToParentViewController:self];
}

// Remove and detach the content video player.
- (void)hideContentPlayer {
  // The whole controller needs to be detached so that it doesn't capture resume events from the
  // remote and play content underneath the ad.
  [self.contentPlayerViewController willMoveToParentViewController:nil];
  [self.contentPlayerViewController.view removeFromSuperview];
  [self.contentPlayerViewController removeFromParentViewController];
}

Swift

class ViewController: UIViewController, IMAAdsLoaderDelegate, IMAAdsManagerDelegate {
  static let contentURLString =
    "https://devstreaming-cdn.apple.com/videos/streaming/examples/"
    + "img_bipbop_adv_example_fmp4/master.m3u8"
  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="

  var adsLoader: IMAAdsLoader!
  var adDisplayContainer: IMAAdDisplayContainer!
  var adsManager: IMAAdsManager!
  var contentPlayhead: IMAAVPlayerContentPlayhead?
  var playerViewController: AVPlayerViewController!
  var adBreakActive = false

  deinit {
    NotificationCenter.default.removeObserver(self)
  }

  override func viewDidLoad() {
    super.viewDidLoad()
    self.view.backgroundColor = UIColor.black
    setUpContentPlayer()
    setUpAdsLoader()
  }

  override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    requestAds()
  }

בדוגמה הזו, viewDidLoad() מאתחל את IMAAdsLoader, וviewDidAppear() שולח בקשות להצגת מודעות אחרי שהתצוגה גלויה. השיטות העזר showContentPlayer() ו-hideContentPlayer() מחליפות את מצב החשיפה של התוכן במהלך הפעלת המודעה.

בדוגמה הזו נעשה שימוש במשתנה הקבוע adTagURLString כדי להגדיר את תג המודעה של VAST לבקשה להצגת מודעה, וברכיבים הבאים כדי לנהל את IMA SDK:

  • ‫adsLoader: מטפל בבקשות להצגת מודעות ובתגובות. מומלץ להשתמש במופע יחיד למחזור החיים של האפליקציה.
  • ‫adDisplayContainer: מציין את התצוגה לעיבוד מודעות.
  • ‫adsManager: מנהל את הפעלת המודעות ומאזין לאירועים שקשורים למודעות.
  • ‫contentPlayhead: עוקב אחרי התקדמות התוכן כדי להפעיל הפסקות למודעות באמצע הסרטון.
  • ‫adBreakActive: מציין אם מוצגת הפסקה למודעה כדי למנוע דילוג על מודעות.

5. הטמעה של כלי למעקב אחר המיקום הנוכחי של התוכן ושל כלי למעקב אחר סיום הסטרימינג

כדי להציג מודעות באמצע הסרטון (mid-roll), ערכת IMA SDK צריכה לעקוב אחרי המיקום הנוכחי של תוכן הווידאו. כדי להעביר את המיקום הנוכחי ל-IMA, צריך ליצור מחלקה שמטמיעה את IMAContentPlayhead. אם אתם משתמשים ב-AVPlayer, כמו בדוגמה הזו, IMA SDK מספק את המחלקה IMAAVPlayerContentPlayhead כדי להעביר את פרטי המיקום הנוכחי בשבילכם. אם אתם לא משתמשים ב-AVPlayer, אתם יכולים להטמיע את IMAContentPlayhead בכיתה משלכם.

Objective-C

- (void)setupContentPlayer {
  // Create a content video player. Create a playhead to track content progress so the SDK knows
  // when to play ads in a VMAP playlist.
  NSURL *contentURL = [NSURL URLWithString:kContentURLString];
  AVPlayer *player = [AVPlayer playerWithURL:contentURL];
  self.contentPlayerViewController = [[AVPlayerViewController alloc] init];
  self.contentPlayerViewController.player = player;
  self.contentPlayerViewController.view.frame = self.view.bounds;
  self.contentPlayhead =
      [[IMAAVPlayerContentPlayhead alloc] initWithAVPlayer:self.contentPlayerViewController.player];

  // Track end of content.
  AVPlayerItem *contentPlayerItem = self.contentPlayerViewController.player.currentItem;
  [[NSNotificationCenter defaultCenter] addObserver:self
                                           selector:@selector(contentDidFinishPlaying:)
                                               name:AVPlayerItemDidPlayToEndTimeNotification
                                             object:contentPlayerItem];

  // Attach content video player to view hierarchy.
  [self showContentPlayer];
}

Swift

func setUpContentPlayer() {
  // Load AVPlayer with path to our content.
  let contentURL = URL(string: ViewController.contentURLString)!
  let player = AVPlayer(url: contentURL)
  playerViewController = AVPlayerViewController()
  playerViewController.player = player

  // Set up our content playhead and contentComplete callback.
  contentPlayhead = IMAAVPlayerContentPlayhead(avPlayer: player)
  NotificationCenter.default.addObserver(
    self,
    selector: #selector(ViewController.contentDidFinishPlaying(_:)),
    name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
    object: player.currentItem)

  showContentPlayer()
}

מגדירים מאזין לקריאה ל-contentComplete ב-IMAAdsLoader כשתוכן מסתיים, באמצעות AVPlayerItemDidPlayToEndTimeNotification. הפונקציה contentComplete מאפשרת ל-IMA SDK לדעת מתי התוכן שלכם מסתיים כדי להציג מודעות בסוף סרטון.

Objective-C

- (void)contentDidFinishPlaying:(NSNotification *)notification {
  // Notify the SDK that the postrolls should be played.
  [self.adsLoader contentComplete];
}

- (void)dealloc {
  [[NSNotificationCenter defaultCenter] removeObserver:self];
}

Swift

@objc func contentDidFinishPlaying(_ notification: Notification) {
  adsLoader.contentComplete()
}

6. מאתחלים את הכלי לטעינת מודעות ושולחים בקשה להצגת מודעות

כדי לבקש קבוצה של מודעות, יוצרים מופע של IMAAdsLoader. רכיב הטעינה הזה מעבד אובייקטים של IMAAdsRequest שמשויכים לכתובת URL ספציפית של תג מודעה.

מומלץ לשמור רק מופע אחד של IMAAdsLoader לאורך כל מחזור החיים של האפליקציה. כדי לשלוח בקשות נוספות להצגת מודעות, צריך ליצור אובייקט IMAAdsRequest חדש, אבל להשתמש שוב באותו IMAAdsLoader. מידע נוסף זמין בשאלות הנפוצות בנושא IMA SDK.

Objective-C

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

- (void)requestAds {
  // Pass the main view as the container for ad display.
  self.adDisplayContainer = [[IMAAdDisplayContainer alloc] initWithAdContainer:self.view
                                                                viewController:self];
  IMAAdsRequest *request = [[IMAAdsRequest alloc] initWithAdTagUrl:kAdTagURLString
                                                adDisplayContainer:self.adDisplayContainer
                                                   contentPlayhead:self.contentPlayhead
                                                       userContext:nil];
  [self.adsLoader requestAdsWithRequest:request];
}

Swift

func setUpAdsLoader() {
  adsLoader = IMAAdsLoader(settings: nil)
  adsLoader.delegate = self
}

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

  adsLoader.requestAds(with: request)
}

7. הגדרת נציג לטעינת מודעות

באירוע טעינה מוצלח, IMAAdsLoader מפעיל את השיטה adsLoadedWithData של הנציג שהוקצה לו, ומעביר לו מופע של IMAAdsManager. אחרי שיש לכם את מופע IMAAdsManager, מאתחלים את הכלי לניהול מודעות, שמטעין מודעות ספציפיות על סמך התגובה של כתובת ה-URL של תג המודעה.

במקרה של אירועי טעינה לא מוצלחים, צריך להגדיר IMAAdsLoader delegate כדי לטפל בשגיאות שמתרחשות במהלך תהליך הטעינה. אם המודעות לא נטענות, צריך לוודא שהפעלת המדיה ממשיכה ללא מודעות כדי לאפשר למשתמשים לצפות בתוכן המדיה.

Objective-C

#pragma mark - IMAAdsLoaderDelegate

- (void)adsLoader:(IMAAdsLoader *)loader adsLoadedWithData:(IMAAdsLoadedData *)adsLoadedData {
  // Initialize and listen to the ads manager loaded for this request.
  self.adsManager = adsLoadedData.adsManager;
  self.adsManager.delegate = self;
  [self.adsManager initializeWithAdsRenderingSettings:nil];
}

- (void)adsLoader:(IMAAdsLoader *)loader failedWithErrorData:(IMAAdLoadingErrorData *)adErrorData {
  // Fall back to playing content.
  NSLog(@"Error loading ads: %@", adErrorData.adError.message);
  [self.contentPlayerViewController.player 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
  adsManager.initialize(with: nil)
}

func adsLoader(_ loader: IMAAdsLoader, failedWith adErrorData: IMAAdLoadingErrorData) {
  print("Error loading ads: \(adErrorData.adError.message ?? "No error message available.")")
  showContentPlayer()
  playerViewController.player?.play()
}

8. הגדרה של משתמש מורשה ב-Ads Manager

לבסוף, כדי לנהל אירועים ושינויים במצב, למרכז ניהול המודעות נדרש נציג משלו. ל-IMAAdManagerDelegate יש methods לטיפול באירועים ובשגיאות שקשורים למודעות, וגם methods להפעלת תוכן הווידאו ולהשהייתו.

ההפעלה מתחילה

השיטה didReceiveAdEvent מטפלת בכל האירועים מסוג IMAAdEvent. בדוגמה הבסיסית הזו, צריך להאזין לאירוע LOADED כדי להורות למנהל המודעות להתחיל בהפעלה של תוכן ומודעות. ה-SDK של IMA מפעיל את האירוע ICON_FALLBACK_IMAGE_CLOSED כשהמשתמש סוגר תיבת דו-שיח של חלופה לסמל אחרי שהוא מקיש על סמל. אחרי הפעולה הזו, הפעלת המודעה תימשך.

Objective-C

#pragma mark - IMAAdsManagerDelegate

- (void)adsManager:(IMAAdsManager *)adsManager didReceiveAdEvent:(IMAAdEvent *)event {
  switch (event.type) {
    case kIMAAdEvent_LOADED: {
      // Play each ad once it has loaded.
      [adsManager start];
      break;
    }
    case kIMAAdEvent_ICON_FALLBACK_IMAGE_CLOSED: {
      // Resume ad after user has closed dialog.
      [adsManager resume];
      break;
    }
    default:
      break;
  }
}

Swift

func adsManager(_ adsManager: IMAAdsManager, didReceive event: IMAAdEvent) {
  switch event.type {
  case IMAAdEventType.LOADED:
    // Play each ad once it has been loaded.
    adsManager.start()
  case IMAAdEventType.ICON_FALLBACK_IMAGE_CLOSED:
    // Resume playback after the user has closed the dialog.
    adsManager.resume()
  default:
    break
  }
}

טיפול בשגיאות

כדאי גם להוסיף handler לשגיאות שקשורות למודעות. אם מתרחשת שגיאה, כמו בשלב הקודם, מפעילים מחדש את התוכן.

Objective-C

- (void)adsManager:(IMAAdsManager *)adsManager didReceiveAdError:(IMAAdError *)error {
  // Fall back to playing content.
  NSLog(@"AdsManager error: %@", error.message);
  [self showContentPlayer];
  [self.contentPlayerViewController.player play];
}

Swift

func adsManager(_ adsManager: IMAAdsManager, didReceive error: IMAAdError) {
  // Fall back to playing content
  print("AdsManager error: \(error.message ?? "No error message available.")")
  showContentPlayer()
  playerViewController.player?.play()
}

הפעלת אירועי הפעלה והשהיה

שתי שיטות הנציג האחרונות שמטמיעים מפעילות אירועי הפעלה והשהיה בתוכן הווידאו הבסיסי כש-IMA SDK מבקש אותם. הפעלת ההשהיה וההפעלה כשמתקבלות בקשות מ-IMA SDK מונעת מהמשתמש לפספס חלקים מתוכן הווידאו בזמן שהמודעות מוצגות.

Objective-C

- (void)adsManagerDidRequestContentPause:(IMAAdsManager *)adsManager {
  // Pause the content for the SDK to play ads.
  [self.contentPlayerViewController.player pause];
  [self hideContentPlayer];
  // Trigger an update to send focus to the ad display container.
  self.adBreakActive = YES;
  [self setNeedsFocusUpdate];
}

- (void)adsManagerDidRequestContentResume:(IMAAdsManager *)adsManager {
  // Resume the content since the SDK is done playing ads (at least for now).
  [self showContentPlayer];
  [self.contentPlayerViewController.player play];
  // Trigger an update to send focus to the content player.
  self.adBreakActive = NO;
  [self setNeedsFocusUpdate];
}

Swift

func adsManagerDidRequestContentPause(_ adsManager: IMAAdsManager) {
  // Pause the content for the SDK to play ads.
  playerViewController.player?.pause()
  hideContentPlayer()
  // Trigger an update to send focus to the ad display container.
  adBreakActive = true
  setNeedsFocusUpdate()
}

func adsManagerDidRequestContentResume(_ adsManager: IMAAdsManager) {
  // Resume the content since the SDK is done playing ads (at least for now).
  showContentPlayer()
  playerViewController.player?.play()
  // Trigger an update to send focus to the content player.
  adBreakActive = false
  setNeedsFocusUpdate()
}

זהו! עכשיו אתם שולחים בקשות להצגת מודעות ומציגים מודעות באמצעות IMA SDK. כדי לקבל מידע על תכונות נוספות של ה-SDK, אפשר לעיין במדריכים האחרים או בדוגמאות ב-GitHub.

השלבים הבאים

כדי להגדיל את ההכנסות מפרסום בפלטפורמת tvOS, צריך לבקש הרשאה לשקיפות ומעקב באפליקציה כדי להשתמש ב-IDFA.