תחילת העבודה עם IMA DAI SDK

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

בחירת פתרון ה-DAI הרצוי

מודעות דינמיות ב-Pod

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

סקירה כללית על הטמעת מודעות דינמיות (DAI) ב-IMA

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

  • IMAAdDisplayContainer – אובייקט קונטיינר שממוקם מעל אלמנט ההפעלה של הסרטון ומכיל את רכיבי ממשק המשתמש של המודעה.
  • IMAAdsLoader – אובייקט שמבקש שידורים ומטפל באירועים שמופעל על ידי אובייקטים של תגובות לבקשות של שידורים. צריך ליצור רק אובייקט אחד של Ads Loader, שאפשר לעשות בו שימוש חוזר במהלך כל חיי האפליקציה.
  • IMAStreamRequest – הערך יכול להיות IMAPodVODStreamRequest או IMAPodStreamRequest.
  • IMAStreamManager – אובייקט שמטפל בזרמים של הטמעת מודעות דינמיות ובאינטראקציות עם הקצה העורפי של DAI. מנהל הסטרימינג מטפל גם בפניות מעקב (pings) ומעביר אירועי סטרימינג ומודעות לבעלי התוכן הדיגיטלי.

בנוסף, כדי להפעיל שידורים של מודעות ב-Pod, צריך להטמיע מתבצע VTP בהתאמה אישית. הטיפול המותאם אישית של VTP שולח את מזהה הסטרימינג לשותף הטכני של הווידאו (VTP) יחד עם כל המידע הנוסף שנחוץ לו כדי להחזיר מניפסט של סטרימינג שמכיל גם תוכן וגם מודעות מודבקות. ב-VTP יתקבלו הוראות להטמעת הטיפול המותאם אישית ב-VTP.

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

לפני שמתחילים, צריך את הדברים הבאים:

צריך גם את הפרמטרים שמשמשים לשליחת בקשה לסטרימינג מ-IMA SDK.

פרמטרים של שידורים חיים
קוד רשת קוד הרשת של חשבון Ad Manager 360.
דוגמה: 51636543
מפתח מותאם אישית של נכס מפתח הנכס המותאם אישית שמזהה את אירוע הצגת המודעות ב-Pod ב-Ad Manager 360. הקוד הזה יכול להיווצר על ידי הכלי לעיבוד המניפסט או על ידי שותף צד שלישי להצגת מודעות ב-Pod.
דוגמה: google-sample
פרמטרים של סטרימינג של VOD
קוד רשת קוד הרשת של חשבון Ad Manager 360.
דוגמה: 51636543

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

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

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

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

התקנת ה-SDK באמצעות CocoaPods (האפשרות המועדפת)

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

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

    source 'https://github.com/CocoaPods/Specs.git'
    
    platform :ios, '14'
    
    target 'PodServingExample' do
      pod 'GoogleAds-IMA-iOS-SDK'
    end
    

  2. בתיקייה שמכילה את Podfile, מריצים את הפקודה:

    pod install --repo-update

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

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

  1. ב-Xcode, מתקינים את חבילת Swift של IMA DAI SDK. לשם כך, עוברים אל File > Add Packages.

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

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

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

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

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

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

הטמעת נגן וידאו ב-View Controller הראשי באמצעות נגן AV שמקובץ בתצוגת UI. ‏IMA SDK משתמש בתצוגת ממשק המשתמש כדי להציג רכיבי ממשק משתמש של מודעות.

#import "ViewController.h"

#import <AVKit/AVKit.h>

/// Content URL.
static NSString *const kBackupContentUrl =
    @"http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8";

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

@property(nonatomic, weak) IBOutlet UIView *videoView;
/// Video player.
@property(nonatomic, strong) AVPlayer *videoPlayer;
@end

@implementation ViewController

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

  // Load AVPlayer with the path to your content.
  NSURL *contentURL = [NSURL URLWithString:kBackupContentUrl];
  self.videoPlayer = [AVPlayer playerWithURL:contentURL];

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

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

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

@end

איך מאתחלים את הטעינה של המודעות

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

מוסיפים את המאפיינים הפרטיים הבאים כדי לאחסן רכיבים מרכזיים של IMA SDK:

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

מאתחלים את מערך הטעינה של המודעות, את מאגר המודעות ואת תצוגת הסרטון אחרי שהתצוגה נטענת.

@import GoogleInteractiveMediaAds;

// ...

@interface ViewController () <IMAAdsLoaderDelegate, IMAStreamManagerDelegate>
/// The entry point for the IMA DAI SDK to make DAI stream requests.
@property(nonatomic, strong) IMAAdsLoader *adsLoader;
/// The container where the SDK renders each ad's user interface elements and companion slots.
@property(nonatomic, strong) IMAAdDisplayContainer *adDisplayContainer;
/// The reference of your video player for the IMA DAI SDK to monitor playback and handle timed
/// metadata.
@property(nonatomic, strong) IMAAVPlayerVideoDisplay *imaVideoDisplay;
/// References the stream manager from the IMA DAI SDK after successful stream loading.
@property(nonatomic, strong) IMAStreamManager *streamManager;

// ...

@end

@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];

  // ...

  self.adsLoader = [[IMAAdsLoader alloc] initWithSettings:nil];
  self.adsLoader.delegate = self;

  // Create an ad display container for rendering each ad's user interface elements and companion
  // slots.
  self.adDisplayContainer =
      [[IMAAdDisplayContainer alloc] initWithAdContainer:self.videoView
                                          viewController:self
                                          companionSlots:nil];

  // Create an IMAAVPlayerVideoDisplay to give the SDK access to your video player.
  self.imaVideoDisplay = [[IMAAVPlayerVideoDisplay alloc] initWithAVPlayer:self.videoPlayer];
}

שליחת בקשה להעברת נתונים

כשמשתמש לוחץ על לחצן ההפעלה, שולחים בקשה חדשה לשידור. משתמשים ב-class‏ IMAPodStreamRequest לשידורים חיים. להעברות VOD, משתמשים במחלקה IMAPodVODStreamRequest.

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

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

- (void)requestStream {
  // Create a stream request.
  IMAStreamRequest *request;
  if (kStreamType == StreamTypeLive) {
    // Live stream request. Replace the network code and custom asset key with your values.
    request = [[IMAPodStreamRequest alloc] initWithNetworkCode:kNetworkCode
                                                customAssetKey:kCustomAssetKey
                                            adDisplayContainer:adDisplayContainer
                                                  videoDisplay:self.videoDisplay
                                         pictureInPictureProxy:nil
                                                   userContext:nil];
  } else {
    // VOD request. Replace the network code with your value.
    request = [[IMAPodVODStreamRequest alloc] initWithNetworkCode:@kNetworkCode
                                               adDisplayContainer:adDisplayContainer
                                                     videoDisplay:self.videoDisplay
                                            pictureInPictureProxy:nil
                                                      userContext:nil];
  }
  [self.adsLoader requestStreamWithRequest:request];
}

הקשבה לאירועי טעינה של שידורים

הכיתה IMAAdsLoader קורא לשיטות IMAAdsLoaderDelegate אם האתחול של בקשת הסטרימינג הצליח או נכשל.

בשיטת הענקת הגישה adsLoadedWithData, מגדירים את IMAStreamManagerDelegate. מעבירים את מזהה מקור הנתונים למטפל VTP בהתאמה אישית ומאחזרים את כתובת ה-URL של המניפסט של מקור הנתונים. בשידורים חיים, טוענים את כתובת ה-URL של המניפסט במסך הווידאו ומתחילים את ההפעלה. בשידורי VOD, מעבירים את כתובת ה-URL של המניפסט לשיטה loadThirdPartyStream של מנהל הסטרימינג. בשיטה הזו, המערכת מבקשת נתונים של אירועי מודעות מ-Ad Manager 360, ואז טוענת את כתובת ה-URL של המניפסט ומתחילה את ההפעלה.

מתעדים את השגיאה ביומן של שיטת הענקת הגישה failedWithErrorData. אפשר גם להפעיל את סטרימינג הגיבוי. שיטות מומלצות ל-DAI

- (void)adsLoader:(IMAAdsLoader *)loader adsLoadedWithData:(IMAAdsLoadedData *)adsLoadedData {
  NSLog(@"Stream created with: %@.", adsLoadedData.streamManager.streamId);
  self.streamManager = adsLoadedData.streamManager;
  self.streamManager.delegate = self;

  // Build the Pod serving Stream URL.
  NSString *streamID = adsLoadedData.streamManager.streamId;
  // Your custom VTP handler takes the stream ID and returns the stream manifest URL.
  NSString *urlString = gCustomVTPHandler(streamID);
  NSURL *streamUrl = [NSURL URLWithString:urlString];
  if (kStreamType == StreamTypeLive) {
    // Load live streams directly into the AVPlayer.
    [self.videoDisplay loadStream:streamUrl withSubtitles:@[]];
    [self.videoDisplay play];
  } else {
    // Load VOD streams using the `loadThirdPartyStream` method in IMA SDK's stream manager.
    // The stream manager loads the stream, requests metadata, and starts playback.
    [self.streamManager loadThirdPartyStream:streamUrl streamSubtitles:@[]];
  }
}

- (void)adsLoader:(IMAAdsLoader *)loader failedWithErrorData:(IMAAdLoadingErrorData *)adErrorData {
  // Log the error and play the backup content.
  NSLog(@"AdsLoader error, code:%ld, message: %@", adErrorData.adError.code,
        adErrorData.adError.message);
  [self.videoPlayer play];
}

הטמעת טיפול VTP בהתאמה אישית

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

לדוגמה, VTP עשוי לכלול כתובת URL של תבנית מניפסט שמכילה את המאקרו [[STREAMID]]. בדוגמה הזו, הטיפולן מוסיף את מזהה הסטרימינג במקום המאקרו ומחזיר את כתובת ה-URL של המניפסט שנוצר.

/// Custom VTP Handler.
///
/// Returns the stream manifest URL from the video technical partner or manifest manipulator.
static NSString *(^gCustomVTPHandler)(NSString *) = ^(NSString *streamID) {
  // Insert synchronous code here to retrieve a stream manifest URL from your video tech partner
  // or manifest manipulation server.
  // This example uses a hardcoded URL template, containing a placeholder for the stream
  // ID and replaces the placeholder with the stream ID.
  NSString *manifestUrl = @"YOUR_MANIFEST_URL_TEMPLATE";
  return [manifestUrl stringByReplacingOccurrencesOfString:@"[[STREAMID]]"
                                                withString:streamID];
};

האזנה לאירועים של מודעות

האירועים והשגיאות של הסטרימינג מועברים לאפליקציה באמצעות הקריאה של IMAStreamManager לשיטות IMAStreamManagerDelegate.

בדוגמה הזו, מתעדים ביומן במסוף את אירועי המודעות הראשיים:

- (void)streamManager:(IMAStreamManager *)streamManager didReceiveAdEvent:(IMAAdEvent *)event {
  NSLog(@"Ad event (%@).", event.typeString);
  switch (event.type) {
    case kIMAAdEvent_STARTED: {
      // Log extended data.
      NSString *extendedAdPodInfo = [[NSString alloc]
          initWithFormat:@"Showing ad %ld/%ld, bumper: %@, title: %@, description: %@, contentType:"
                         @"%@, pod index: %ld, time offset: %lf, max duration: %lf.",
                         (long)event.ad.adPodInfo.adPosition, (long)event.ad.adPodInfo.totalAds,
                         event.ad.adPodInfo.isBumper ? @"YES" : @"NO", event.ad.adTitle,
                         event.ad.adDescription, event.ad.contentType,
                         (long)event.ad.adPodInfo.podIndex, event.ad.adPodInfo.timeOffset,
                         event.ad.adPodInfo.maxDuration];

      NSLog(@"%@", extendedAdPodInfo);
      break;
    }
    case kIMAAdEvent_AD_BREAK_STARTED: {
      NSLog(@"Ad break started");
      break;
    }
    case kIMAAdEvent_AD_BREAK_ENDED: {
      NSLog(@"Ad break ended");
      break;
    }
    case kIMAAdEvent_AD_PERIOD_STARTED: {
      NSLog(@"Ad period started");
      break;
    }
    case kIMAAdEvent_AD_PERIOD_ENDED: {
      NSLog(@"Ad period ended");
      break;
    }
    default:
      break;
  }
}

- (void)streamManager:(IMAStreamManager *)streamManager didReceiveAdError:(IMAAdError *)error {
  NSLog(@"StreamManager error with type: %ld\ncode: %ld\nmessage: %@", error.type, error.code,
        error.message);
  [self.videoPlayer play];
}

ניקוי נכסי IMA DAI

כדי להפסיק את הפעלת הסטרימינג, להפסיק את כל המעקב אחר מודעות ולשחרר את כל נכסי הסטרימינג שנטענו, צריך לבצע קריאה ל-IMAStreamManager.destroy().

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