אני רוצה לנסות

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

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

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

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

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

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

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

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

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

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

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

  1. באותה ספרייה כמו הקובץ BasicExample.xcodeproj, יוצרים קובץ טקסט בשם Podfile ומוסיפים את ההגדרות הבאות:

    source 'https://github.com/CocoaPods/Specs.git'
    platform :ios, '14'
    target "BasicExample" do
      pod 'GoogleAds-IMA-iOS-SDK', '~> 3.23.0'
    end
    
  2. מהספרייה שמכילה את ה-Podfile, מריצים את הפקודה pod install --repo-update

  3. כדי לוודא שההתקנה בוצעה בהצלחה, פותחים את הקובץ BasicExample.xcworkspace ומאשרים שהוא מכיל שני פרויקטים: BasicExample ו-Pods (יחסי התלות שהותקנו על ידי CocoaPods).

התקנת ה-SDK באמצעות Swift Package Manager

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

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

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

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

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

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

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

3. יצירת נגן וידאו פשוט

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

ViewController.m

Objective-C

#import "ViewController.h"

#import <AVKit/AVKit.h>

NSString *const kContentURLString =
    @"https://storage.googleapis.com/interactive-media-ads/media/stock.mp4";

@interface ViewController ()
@property(nonatomic) AVPlayerViewController *contentPlayerViewController;
@end

@implementation ViewController

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

- (void)setupContentPlayer {
  // Create a content video player.
  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;

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

// 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 events from the remote.
  [self.contentPlayerViewController willMoveToParentViewController:nil];
  [self.contentPlayerViewController.view removeFromSuperview];
  [self.contentPlayerViewController removeFromParentViewController];
}

@end
      

Swift

import AVFoundation
import UIKit

class ViewController: UIViewController {
  static let ContentURLString = "https://storage.googleapis.com/interactive-media-ads/media/stock.mp4"

  var playerViewController: AVPlayerViewController!

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

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

    showContentPlayer()
  }

  func showContentPlayer() {
    self.addChild(playerViewController)
    playerViewController.view.frame = self.view.bounds
    self.view.insertSubview(playerViewController.view, at: 0)
    playerViewController.didMove(toParent:self)
  }

  func hideContentPlayer() {
    // The whole controller needs to be detached so that it doesn't capture
    // events from the remote.
    playerViewController.willMove(toParent:nil)
    playerViewController.view.removeFromSuperview()
    playerViewController.removeFromParent()
  }
}
      

‫4. ייבוא של IMA SDK

לאחר מכן, הוסיפו את מסגרת ה-IMA באמצעות הצהרת ייבוא מתחת לפעולות הייבוא הקיימות.

ViewController.m

Objective-C

#import "ViewController.h"

#import <AVKit/AVKit.h>
#import <GoogleInteractiveMediaAds/GoogleInteractiveMediaAds.h>
NSString *const kContentURLString =
    @"https://storage.googleapis.com/interactive-media-ads/media/stock.mp4";
      

Swift

import AVFoundation
import GoogleInteractiveMediaAds
import UIKit

class ViewController: UIViewController {
  static let ContentURLString = "https://storage.googleapis.com/interactive-media-ads/media/stock.mp4"
      

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

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

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

ViewController.m

Objective-C

...

@interface ViewController ()
@property(nonatomic) IMAAVPlayerContentPlayhead *contentPlayhead;
@property(nonatomic) AVPlayerViewController *contentPlayerViewController;
@end

...

- (void)setupContentPlayer {
  // Create a content video player.
  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];
}

...

- (void)contentDidFinishPlaying:(NSNotification *)notification {}

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

@end
      

Swift

...

class ViewController: UIViewController {
  static let ContentURLString = "https://storage.googleapis.com/interactive-media-ads/media/stock.mp4"

  var contentPlayhead: IMAAVPlayerContentPlayhead?
  var playerViewController: AVPlayerViewController!

  deinit {
    NotificationCenter.default.removeObserver(self)
  }

...

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

    // Set up your 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()
  }

...

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

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

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

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

ViewController.m

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&impl=s&cmsid=496&vid=short_onecue&correlator=";

@interface ViewController ()
@property(nonatomic) IMAAdsLoader *adsLoader;
@property(nonatomic) IMAAVPlayerContentPlayhead *contentPlayhead;
@property(nonatomic) AVPlayerViewController *contentPlayerViewController;
@end

@implementation ViewController

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

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

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

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

...

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

...

@end
      

Swift

...

class ViewController: UIViewController {
  static let ContentURLString = "https://storage.googleapis.com/interactive-media-ads/media/stock.mp4"
  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&impl=s&correlator="

  var adsLoader: IMAAdsLoader!
  var contentPlayhead: IMAAVPlayerContentPlayhead?
  var playerViewController: AVPlayerViewController!

...

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

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

...

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

  func requestAds() {
    // Create ad display container for ad rendering.
    let adDisplayContainer = IMAAdDisplayContainer(adContainer: self.view)
    // 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)
  }

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

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

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

בנוסף, חשוב לטפל בשגיאות שעלולות להתרחש במהלך הטעינה. אם מודעות לא נטענות, חשוב לוודא שהפעלת המדיה נמשכת ללא מודעות, כדי לא להפריע לחוויית המשתמש.

ViewController.m

Objective-C

...

@interface ViewController () <IMAAdsLoaderDelegate>
@property(nonatomic) IMAAdsLoader *adsLoader;
@property(nonatomic) IMAAdsManager *adsManager;
@property(nonatomic) IMAAVPlayerContentPlayhead *contentPlayhead;
@property(nonatomic) AVPlayerViewController *contentPlayerViewController;
@end

@implementation ViewController

...

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

...

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

@end
      

Swift

...

class ViewController: UIViewController, IMAAdsLoaderDelegate {

...

  var adsLoader: IMAAdsLoader!
  var adsManager: IMAAdsManager!
  var contentPlayhead: IMAAVPlayerContentPlayhead?
  var playerViewController: AVPlayerViewController!

...

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

...

  // MARK: - IMAAdsLoaderDelegate

  func adsLoader(_ loader: IMAAdsLoader!, adsLoadedWith adsLoadedData: IMAAdsLoadedData!) {
    adsManager = adsLoadedData.adsManager
    adsManager.initialize(with: nil)
  }

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

‫8. איך נותנים הרשאה לניהול מודעות

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

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

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

ViewController.m

Objective-C

@interface ViewController () <IMAAdsLoaderDelegate, IMAAdsManagerDelegate>

...

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

...

#pragma mark - IMAAdsManagerDelegate

- (void)adsManager:(IMAAdsManager *)adsManager didReceiveAdEvent:(IMAAdEvent *)event {
  // Play each ad once it has loaded.
  if (event.type == kIMAAdEvent_LOADED) {
    [adsManager start];
  }
}

...
      

Swift

...

class ViewController: UIViewController, IMAAdsLoaderDelegate, IMAAdsManagerDelegate {

...

  func adsLoader(_ loader: IMAAdsLoader!, adsLoadedWith adsLoadedData: IMAAdsLoadedData!) {
    // Grab the instance of the IMAAdsManager and set yourself as the delegate.
    adsManager = adsLoadedData.adsManager
    adsManager.delegate = self
    adsManager.initialize(with: nil)
  }

...

  // MARK: - IMAAdsManagerDelegate

  func adsManager(_ adsManager: IMAAdsManager!, didReceive event: IMAAdEvent!) {
    // Play each ad once it has been loaded
    if event.type == IMAAdEventType.LOADED {
      adsManager.start()
    }
  }

...
      

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

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

ViewController.m

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];
}
@end
      

Swift

...

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

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

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

ViewController.m

Objective-C

...

- (void)adsManagerDidRequestContentPause:(IMAAdsManager *)adsManager {
  // Pause the content for the SDK to play ads.
  [self.contentPlayerViewController.player pause];
  [self hideContentPlayer];
}

- (void)adsManagerDidRequestContentResume:(IMAAdsManager *)adsManager {
  // Resume the content since the SDK is done playing ads (at least for now).
  [self showContentPlayer];
  [self.contentPlayerViewController.player play];
}

@end
      

Swift

...

  func adsManagerDidRequestContentPause(_ adsManager: IMAAdsManager!) {
    // Pause the content for the SDK to play ads.
    playerViewController.player?.pause()
    hideContentPlayer()
  }

  func adsManagerDidRequestContentResume(_ adsManager: IMAAdsManager!) {
    // Resume the content since the SDK is done playing ads (at least for now).
    showContentPlayer()
    playerViewController.player?.play()
  }
}
      

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

השלבים הבאים

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